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 }