001    package railo.runtime.functions.file;
002    
003    import java.io.BufferedInputStream;
004    import java.io.File;
005    import java.io.IOException;
006    import java.io.RandomAccessFile;
007    
008    import railo.commons.io.IOUtil;
009    import railo.commons.io.res.Resource;
010    import railo.runtime.exp.PageException;
011    import railo.runtime.op.Caster;
012    
013    public class FileStreamWrapperReadBinary extends FileStreamWrapper {
014            
015    
016    
017            private BufferedInputStream bis;
018            private boolean isEOF;
019            private boolean seekable;
020            private RandomAccessFile raf;
021    
022            /**
023             * Constructor of the class
024             * @param res
025             * @param charset
026             * @throws IOException
027             */
028            public FileStreamWrapperReadBinary(Resource res,boolean seekable) {
029                    super(res);
030                    this.seekable=seekable;
031            }
032            
033    
034    
035    
036            /**
037             *
038             * @see railo.runtime.functions.file.FileStreamWrapper#read(int)
039             */
040            public Object read(int len) throws IOException {
041                    byte[] barr=new byte[len];
042                    len=seekable?getRAF().read(barr):_getBIS().read(barr);
043                    if(len!=barr.length) {
044                            byte[] rtn=new byte[len];
045                            for(int i=0;i<len;i++) {
046                                    rtn[i]=barr[i];
047                            }
048                            barr=rtn;
049                            isEOF=true;
050                    }
051                    return barr;
052            }
053    
054            /**
055             * @see railo.runtime.functions.file.FileStreamWrapper#close()
056             */
057            public void close() throws IOException {
058                    super.setStatus(FileStreamWrapper.STATE_CLOSE);
059                    if(bis!=null)bis.close();
060                    if(raf!=null)raf.close();
061            }
062    
063            /**
064             * @see railo.runtime.functions.file.FileStreamWrapper#getMode()
065             */
066            public String getMode() {
067                    return "readBinary";
068            }
069    
070            public boolean isEndOfFile() {
071                    return isEOF;
072            }
073    
074            /**
075             * @see railo.runtime.functions.file.FileStreamWrapper#getSize()
076             */
077            public long getSize() {
078                    return res.length();
079            }
080            
081            /**
082             * @see railo.runtime.functions.file.FileStreamWrapper#skip(long)
083             */
084            public void skip(int len) throws PageException {
085                    if(seekable){
086                            try {
087                                    getRAF().skipBytes(len);
088                            } catch (IOException e) {
089                                    throw Caster.toPageException(e);
090                            }
091                            return;
092                    }
093                    
094                    try {
095                            _getBIS().skip(len);
096                            return;
097                    } 
098                    catch (IOException e) {}
099                            
100                    throw Caster.toPageException(new IOException("skip is only supported when you have set argument seekable of function fileOpen to true"));
101            }
102            public void seek(long pos) throws PageException {
103                    if(seekable){
104                            try {
105                                    getRAF().seek(pos);
106                            } catch (IOException e) {
107                                    throw Caster.toPageException(e);
108                            }
109                    }
110                    else throw Caster.toPageException(new IOException("seek is only supported when you have set argument seekable of function fileOpen to true"));
111            }
112            
113            private RandomAccessFile getRAF() throws IOException {
114                    if(raf==null){
115                            if(!(res instanceof File))
116                                    throw new IOException("only resources for local filesytem support seekable");
117                            
118                            raf = new RandomAccessFile((File)res,"r");
119                    }
120                    return raf;
121            }
122            
123    
124            private BufferedInputStream _getBIS() throws IOException {
125                    if(bis==null)bis = IOUtil.toBufferedInputStream(res.getInputStream());
126                    return bis;
127            }
128    }