001 package railo.runtime.functions.file; 002 003 import java.io.File; 004 import java.io.IOException; 005 import java.io.InputStream; 006 import java.io.RandomAccessFile; 007 008 import railo.commons.io.res.Resource; 009 import railo.runtime.exp.PageException; 010 import railo.runtime.op.Caster; 011 import railo.runtime.op.Decision; 012 013 public class FileStreamWrapperReadWrite extends FileStreamWrapper { 014 015 //private BufferedOutputStream bos; 016 private String charset; 017 private boolean seekable; 018 private RandomAccessFile raf; 019 private boolean isEOF; 020 021 public FileStreamWrapperReadWrite(Resource res, String charset,boolean seekable) { 022 super(res); 023 024 this.charset=charset; 025 this.seekable=seekable; 026 } 027 028 029 /** 030 * @see railo.runtime.functions.file.FileStreamWrapper#write(java.lang.Object) 031 */ 032 public void write(Object obj) throws IOException { 033 byte[] bytes = null; 034 InputStream is=null; 035 if(Decision.isBinary(obj)){ 036 bytes=Caster.toBinary(obj,null); 037 } 038 else if(obj instanceof FileStreamWrapper) { 039 is=((FileStreamWrapper)obj).getResource().getInputStream(); 040 } 041 else if(obj instanceof Resource) { 042 is=((Resource)obj).getInputStream(); 043 } 044 else if(Decision.isSimpleValue(obj)){ 045 String str = Caster.toString(obj,null); 046 if(str!=null) bytes=str.getBytes(charset); 047 } 048 049 if(bytes!=null){ 050 getRAF().write(bytes); 051 } 052 else if(is!=null){ 053 writeToRAF(is, getRAF()); 054 } 055 else 056 throw new IOException("can't write down object of type ["+Caster.toTypeName(obj)+"] to resource ["+res+"]"); 057 058 059 060 061 } 062 063 public void close() throws IOException { 064 if(raf!=null)raf.close(); 065 } 066 067 /** 068 * 069 * @see railo.runtime.functions.file.FileStreamWrapper#getMode() 070 */ 071 public String getMode() { 072 return "readwrite"; 073 } 074 075 /** 076 * 077 * @see railo.runtime.functions.file.FileStreamWrapper#read(int) 078 */ 079 public Object read(int len) throws IOException { 080 byte[] barr=new byte[len]; 081 len=getRAF().read(barr); 082 if(len!=barr.length) { 083 byte[] rtn=new byte[len]; 084 for(int i=0;i<len;i++) { 085 rtn[i]=barr[i]; 086 } 087 barr=rtn; 088 isEOF=true; 089 } 090 return barr; 091 } 092 093 094 095 /** 096 * @see railo.runtime.functions.file.FileStreamWrapper#isEndOfFile() 097 */ 098 public boolean isEndOfFile() { 099 return isEOF; 100 } 101 102 /** 103 * @see railo.runtime.functions.file.FileStreamWrapper#getSize() 104 */ 105 public long getSize() { 106 return res.length(); 107 } 108 109 /** 110 * @see railo.runtime.functions.file.FileStreamWrapper#skip(long) 111 */ 112 public void skip(int len) throws PageException { 113 try { 114 getRAF().skipBytes(len); 115 } catch (IOException e) { 116 throw Caster.toPageException(e); 117 } 118 } 119 public void seek(long pos) throws PageException { 120 try { 121 getRAF().seek(pos); 122 } catch (IOException e) { 123 throw Caster.toPageException(e); 124 } 125 } 126 127 public static void writeToRAF(InputStream is, RandomAccessFile raf) throws IOException { 128 129 byte[] buffer = new byte[2048]; 130 int tmp=0; 131 132 while ((tmp = is.read(buffer)) != -1) { 133 raf.write(buffer, 0, tmp); 134 } 135 } 136 137 private RandomAccessFile getRAF() throws IOException { 138 if(raf==null){ 139 if(!(res instanceof File)) 140 throw new IOException("only resources for local filesytem support seekable"); 141 raf = new RandomAccessFile((File)res,"rw"); 142 143 } 144 return raf; 145 } 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 }