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            @Override
037            public Object read(int len) throws IOException {
038                    byte[] barr=new byte[len];
039                    len=seekable?getRAF().read(barr):_getBIS().read(barr);
040                    if(len!=barr.length) {
041                            byte[] rtn=new byte[len];
042                            for(int i=0;i<len;i++) {
043                                    rtn[i]=barr[i];
044                            }
045                            barr=rtn;
046                            isEOF=true;
047                    }
048                    return barr;
049            }
050    
051            @Override
052            public void close() throws IOException {
053                    super.setStatus(FileStreamWrapper.STATE_CLOSE);
054                    if(bis!=null)bis.close();
055                    if(raf!=null)raf.close();
056            }
057    
058            @Override
059            public String getMode() {
060                    return "readBinary";
061            }
062    
063            public boolean isEndOfFile() {
064                    return isEOF;
065            }
066    
067            @Override
068            public long getSize() {
069                    return res.length();
070            }
071            
072            @Override
073            public void skip(int len) throws PageException {
074                    if(seekable){
075                            try {
076                                    getRAF().skipBytes(len);
077                            } catch (IOException e) {
078                                    throw Caster.toPageException(e);
079                            }
080                            return;
081                    }
082                    
083                    try {
084                            _getBIS().skip(len);
085                            return;
086                    } 
087                    catch (IOException e) {}
088                            
089                    throw Caster.toPageException(new IOException("skip is only supported when you have set argument seekable of function fileOpen to true"));
090            }
091            public void seek(long pos) throws PageException {
092                    if(seekable){
093                            try {
094                                    getRAF().seek(pos);
095                            } catch (IOException e) {
096                                    throw Caster.toPageException(e);
097                            }
098                    }
099                    else throw Caster.toPageException(new IOException("seek is only supported when you have set argument seekable of function fileOpen to true"));
100            }
101            
102            private RandomAccessFile getRAF() throws IOException {
103                    if(raf==null){
104                            if(!(res instanceof File))
105                                    throw new IOException("only resources for local filesytem support seekable");
106                            
107                            raf = new RandomAccessFile((File)res,"r");
108                    }
109                    return raf;
110            }
111            
112    
113            private BufferedInputStream _getBIS() throws IOException {
114                    if(bis==null)bis = IOUtil.toBufferedInputStream(res.getInputStream());
115                    return bis;
116            }
117    }