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 @Override 030 public void write(Object obj) throws IOException { 031 byte[] bytes = null; 032 InputStream is=null; 033 if(Decision.isBinary(obj)){ 034 bytes=Caster.toBinary(obj,null); 035 } 036 else if(obj instanceof FileStreamWrapper) { 037 is=((FileStreamWrapper)obj).getResource().getInputStream(); 038 } 039 else if(obj instanceof Resource) { 040 is=((Resource)obj).getInputStream(); 041 } 042 else if(Decision.isSimpleValue(obj)){ 043 String str = Caster.toString(obj,null); 044 if(str!=null) bytes=str.getBytes(charset); 045 } 046 047 if(bytes!=null){ 048 getRAF().write(bytes); 049 } 050 else if(is!=null){ 051 writeToRAF(is, getRAF()); 052 } 053 else 054 throw new IOException("can't write down object of type ["+Caster.toTypeName(obj)+"] to resource ["+res+"]"); 055 056 057 058 059 } 060 061 public void close() throws IOException { 062 if(raf!=null)raf.close(); 063 } 064 065 @Override 066 public String getMode() { 067 return "readwrite"; 068 } 069 070 @Override 071 public Object read(int len) throws IOException { 072 byte[] barr=new byte[len]; 073 len=getRAF().read(barr); 074 if(len!=barr.length) { 075 byte[] rtn=new byte[len]; 076 for(int i=0;i<len;i++) { 077 rtn[i]=barr[i]; 078 } 079 barr=rtn; 080 isEOF=true; 081 } 082 return barr; 083 } 084 085 086 087 @Override 088 public boolean isEndOfFile() { 089 return isEOF; 090 } 091 092 @Override 093 public long getSize() { 094 return res.length(); 095 } 096 097 @Override 098 public void skip(int len) throws PageException { 099 try { 100 getRAF().skipBytes(len); 101 } catch (IOException e) { 102 throw Caster.toPageException(e); 103 } 104 } 105 public void seek(long pos) throws PageException { 106 try { 107 getRAF().seek(pos); 108 } catch (IOException e) { 109 throw Caster.toPageException(e); 110 } 111 } 112 113 public static void writeToRAF(InputStream is, RandomAccessFile raf) throws IOException { 114 115 byte[] buffer = new byte[2048]; 116 int tmp=0; 117 118 while ((tmp = is.read(buffer)) != -1) { 119 raf.write(buffer, 0, tmp); 120 } 121 } 122 123 private RandomAccessFile getRAF() throws IOException { 124 if(raf==null){ 125 if(!(res instanceof File)) 126 throw new IOException("only resources for local filesytem support seekable"); 127 raf = new RandomAccessFile((File)res,"rw"); 128 129 } 130 return raf; 131 } 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 }