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    }