001 package railo.runtime.functions.file; 002 003 import java.io.BufferedReader; 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.exp.PageRuntimeException; 012 import railo.runtime.op.Caster; 013 014 public class FileStreamWrapperRead extends FileStreamWrapper { 015 016 017 private BufferedReader br; 018 private String charset; 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 FileStreamWrapperRead(Resource res, String charset,boolean seekable) { 029 super(res); 030 this.charset=charset; 031 this.seekable=seekable; 032 } 033 034 /** 035 * 036 * @see railo.runtime.functions.file.FileStreamWrapper#read(int) 037 */ 038 public Object read(int len) throws IOException { 039 if(seekable) { 040 byte[] barr=new byte[len]; 041 len = getRAF().read(barr); 042 if(len==-1) throw new IOException("End of file reached"); 043 return new String(barr, 0, len, charset); 044 } 045 046 char[] carr=new char[len]; 047 len = _getBR().read(carr); 048 if(len==-1) throw new IOException("End of file reached"); 049 050 return new String(carr,0,len); 051 } 052 053 /** 054 * 055 * @see railo.runtime.functions.file.FileStreamWrapper#readLine() 056 */ 057 public String readLine() throws IOException { 058 if(seekable) { 059 return getRAF().readLine(); 060 } 061 062 if(!_getBR().ready()) 063 throw new IOException(" End of file reached"); 064 return _getBR().readLine(); 065 } 066 067 /** 068 * @see railo.runtime.functions.file.FileStreamWrapper#close() 069 */ 070 public void close() throws IOException { 071 super.setStatus(FileStreamWrapper.STATE_CLOSE); 072 if(br!=null)br.close(); 073 if(raf!=null)raf.close(); 074 } 075 076 /** 077 * @see railo.runtime.functions.file.FileStreamWrapper#getMode() 078 */ 079 public String getMode() { 080 return "read"; 081 } 082 083 public boolean isEndOfFile() { 084 if(seekable){ 085 long pos=0; 086 try { 087 pos = getRAF().getFilePointer(); 088 } catch (IOException ioe) { 089 throw new PageRuntimeException(Caster.toPageException(ioe)); 090 } 091 try { 092 if(raf.read()==-1) return true; 093 raf.seek(pos); 094 } 095 catch (IOException e) { 096 return true; 097 } 098 return false; 099 } 100 101 try { 102 return !_getBR().ready(); 103 } catch (IOException e) { 104 return true; 105 } 106 } 107 108 /** 109 * @see railo.runtime.functions.file.FileStreamWrapper#getSize() 110 */ 111 public long getSize() { 112 return res.length(); 113 } 114 115 /** 116 * @see railo.runtime.functions.file.FileStreamWrapper#skip(long) 117 */ 118 public void skip(int len) throws PageException { 119 if(seekable){ 120 try { 121 getRAF().skipBytes(len); 122 } catch (IOException e) { 123 throw Caster.toPageException(e); 124 } 125 return; 126 } 127 128 try { 129 _getBR().skip(len); 130 return; 131 } 132 catch (IOException e) {} 133 134 throw Caster.toPageException(new IOException("skip is only supported when you have set argument seekable of function fileOpen to true")); 135 } 136 public void seek(long pos) throws PageException { 137 if(seekable){ 138 try { 139 getRAF().seek(pos); 140 } catch (IOException e) { 141 throw Caster.toPageException(e); 142 } 143 } 144 else throw Caster.toPageException(new IOException("seek is only supported when you have set argument seekable of function fileOpen to true")); 145 } 146 147 private RandomAccessFile getRAF() throws IOException { 148 if(raf==null){ 149 if(!(res instanceof File)) 150 throw new IOException("only resources for local filesytem support seekable"); 151 152 raf = new RandomAccessFile((File)res,"r"); 153 } 154 return raf; 155 } 156 157 158 private BufferedReader _getBR() throws IOException { 159 if(br==null){ 160 br = IOUtil.toBufferedReader(IOUtil.getReader(res.getInputStream(),charset)); 161 } 162 return br; 163 } 164 }