001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.functions.file; 020 021import java.io.File; 022import java.io.IOException; 023import java.io.InputStream; 024import java.io.RandomAccessFile; 025 026import lucee.commons.io.res.Resource; 027import lucee.runtime.exp.PageException; 028import lucee.runtime.op.Caster; 029import lucee.runtime.op.Decision; 030 031public class FileStreamWrapperReadWrite extends FileStreamWrapper { 032 033 //private BufferedOutputStream bos; 034 private String charset; 035 private boolean seekable; 036 private RandomAccessFile raf; 037 private boolean isEOF; 038 039 public FileStreamWrapperReadWrite(Resource res, String charset,boolean seekable) { 040 super(res); 041 042 this.charset=charset; 043 this.seekable=seekable; 044 } 045 046 047 @Override 048 public void write(Object obj) throws IOException { 049 byte[] bytes = null; 050 InputStream is=null; 051 if(Decision.isBinary(obj)){ 052 bytes=Caster.toBinary(obj,null); 053 } 054 else if(obj instanceof FileStreamWrapper) { 055 is=((FileStreamWrapper)obj).getResource().getInputStream(); 056 } 057 else if(obj instanceof Resource) { 058 is=((Resource)obj).getInputStream(); 059 } 060 else {//if(Decision.isSimpleValue(obj)){ 061 String str = Caster.toString(obj,false,null); 062 if(str!=null) bytes=str.getBytes(charset); 063 } 064 065 if(bytes!=null){ 066 getRAF().write(bytes); 067 } 068 else if(is!=null){ 069 writeToRAF(is, getRAF()); 070 } 071 else 072 throw new IOException("can't write down object of type ["+Caster.toTypeName(obj)+"] to resource ["+res+"]"); 073 074 075 076 077 } 078 079 public void close() throws IOException { 080 if(raf!=null)raf.close(); 081 } 082 083 @Override 084 public String getMode() { 085 return "readwrite"; 086 } 087 088 @Override 089 public Object read(int len) throws IOException { 090 byte[] barr=new byte[len]; 091 len=getRAF().read(barr); 092 if(len!=barr.length) { 093 byte[] rtn=new byte[len]; 094 for(int i=0;i<len;i++) { 095 rtn[i]=barr[i]; 096 } 097 barr=rtn; 098 isEOF=true; 099 } 100 return barr; 101 } 102 103 104 105 @Override 106 public boolean isEndOfFile() { 107 return isEOF; 108 } 109 110 @Override 111 public long getSize() { 112 return res.length(); 113 } 114 115 @Override 116 public void skip(int len) throws PageException { 117 try { 118 getRAF().skipBytes(len); 119 } catch (IOException e) { 120 throw Caster.toPageException(e); 121 } 122 } 123 public void seek(long pos) throws PageException { 124 try { 125 getRAF().seek(pos); 126 } catch (IOException e) { 127 throw Caster.toPageException(e); 128 } 129 } 130 131 public static void writeToRAF(InputStream is, RandomAccessFile raf) throws IOException { 132 133 byte[] buffer = new byte[2048]; 134 int tmp=0; 135 136 while ((tmp = is.read(buffer)) != -1) { 137 raf.write(buffer, 0, tmp); 138 } 139 } 140 141 private RandomAccessFile getRAF() throws IOException { 142 if(raf==null){ 143 if(!(res instanceof File)) 144 throw new IOException("only resources for local filesytem support seekable"); 145 raf = new RandomAccessFile((File)res,"rw"); 146 147 } 148 return raf; 149 } 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167}