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.BufferedInputStream; 022import java.io.File; 023import java.io.IOException; 024import java.io.RandomAccessFile; 025 026import lucee.commons.io.IOUtil; 027import lucee.commons.io.res.Resource; 028import lucee.runtime.exp.PageException; 029import lucee.runtime.op.Caster; 030 031public class FileStreamWrapperReadBinary extends FileStreamWrapper { 032 033 034 035 private BufferedInputStream bis; 036 private boolean isEOF; 037 private boolean seekable; 038 private RandomAccessFile raf; 039 040 /** 041 * Constructor of the class 042 * @param res 043 * @param charset 044 * @throws IOException 045 */ 046 public FileStreamWrapperReadBinary(Resource res,boolean seekable) { 047 super(res); 048 this.seekable=seekable; 049 } 050 051 052 053 054 @Override 055 public Object read(int len) throws IOException { 056 byte[] barr=new byte[len]; 057 len=seekable?getRAF().read(barr):_getBIS().read(barr); 058 if(len!=barr.length) { 059 byte[] rtn=new byte[len]; 060 for(int i=0;i<len;i++) { 061 rtn[i]=barr[i]; 062 } 063 barr=rtn; 064 isEOF=true; 065 } 066 return barr; 067 } 068 069 @Override 070 public void close() throws IOException { 071 super.setStatus(FileStreamWrapper.STATE_CLOSE); 072 if(bis!=null)bis.close(); 073 if(raf!=null)raf.close(); 074 } 075 076 @Override 077 public String getMode() { 078 return "readBinary"; 079 } 080 081 public boolean isEndOfFile() { 082 return isEOF; 083 } 084 085 @Override 086 public long getSize() { 087 return res.length(); 088 } 089 090 @Override 091 public void skip(int len) throws PageException { 092 if(seekable){ 093 try { 094 getRAF().skipBytes(len); 095 } catch (IOException e) { 096 throw Caster.toPageException(e); 097 } 098 return; 099 } 100 101 try { 102 _getBIS().skip(len); 103 return; 104 } 105 catch (IOException e) {} 106 107 throw Caster.toPageException(new IOException("skip is only supported when you have set argument seekable of function fileOpen to true")); 108 } 109 public void seek(long pos) throws PageException { 110 if(seekable){ 111 try { 112 getRAF().seek(pos); 113 } catch (IOException e) { 114 throw Caster.toPageException(e); 115 } 116 } 117 else throw Caster.toPageException(new IOException("seek is only supported when you have set argument seekable of function fileOpen to true")); 118 } 119 120 private RandomAccessFile getRAF() throws IOException { 121 if(raf==null){ 122 if(!(res instanceof File)) 123 throw new IOException("only resources for local filesytem support seekable"); 124 125 raf = new RandomAccessFile((File)res,"r"); 126 } 127 return raf; 128 } 129 130 131 private BufferedInputStream _getBIS() throws IOException { 132 if(bis==null)bis = IOUtil.toBufferedInputStream(res.getInputStream()); 133 return bis; 134 } 135}