001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.quercus.lib.file;
031:
032: import com.caucho.quercus.QuercusModuleException;
033: import com.caucho.quercus.env.*;
034: import com.caucho.vfs.ReadStream;
035: import com.caucho.vfs.VfsStream;
036:
037: import java.io.IOException;
038: import java.io.InputStream;
039: import java.io.OutputStream;
040: import java.io.UnsupportedEncodingException;
041: import java.util.logging.Level;
042: import java.util.logging.Logger;
043:
044: /**
045: * Represents a Quercus file open for reading
046: */
047: public class ReadStreamInput extends InputStream implements BinaryInput {
048: private static final Logger log = Logger
049: .getLogger(ReadStreamInput.class.getName());
050:
051: private Env _env;
052: private LineReader _lineReader;
053: private ReadStream _is;
054:
055: public ReadStreamInput(Env env) {
056: _env = env;
057: }
058:
059: public ReadStreamInput(Env env, InputStream is) {
060: _env = env;
061:
062: if (is instanceof ReadStream)
063: init((ReadStream) is);
064: else if (is != null)
065: init(new ReadStream(new VfsStream(is, null)));
066: }
067:
068: protected ReadStreamInput(Env env, LineReader lineReader) {
069: _env = env;
070: _lineReader = lineReader;
071: }
072:
073: protected ReadStreamInput(Env env, LineReader lineReader,
074: ReadStream is) {
075: this (env, lineReader);
076: init(is);
077: }
078:
079: public void init(ReadStream is) {
080: _is = is;
081: }
082:
083: /**
084: * Returns the input stream.
085: */
086: public InputStream getInputStream() {
087: return _is;
088: }
089:
090: /**
091: * Opens a copy.
092: */
093: public BinaryInput openCopy() throws IOException {
094: return new ReadStreamInput(_env, _lineReader, _is.getPath()
095: .openRead());
096: }
097:
098: public void setEncoding(String encoding)
099: throws UnsupportedEncodingException {
100: if (_is != null)
101: _is.setEncoding(encoding);
102: }
103:
104: /**
105: *
106: */
107: public void unread() throws IOException {
108: if (_is != null)
109: _is.unread();
110: }
111:
112: /**
113: * Reads a character from a file, returning -1 on EOF.
114: */
115: public int read() throws IOException {
116: if (_is != null)
117: return _is.read();
118: else
119: return -1;
120: }
121:
122: /**
123: * Reads a buffer from a file, returning -1 on EOF.
124: */
125: public int read(byte[] buffer, int offset, int length)
126: throws IOException {
127: if (_is != null) {
128: return _is.read(buffer, offset, length);
129: } else
130: return -1;
131: }
132:
133: /**
134: * Reads a buffer from a file, returning -1 on EOF.
135: */
136: public int read(char[] buffer, int offset, int length)
137: throws IOException {
138: if (_is != null) {
139: return _is.read(buffer, offset, length);
140: } else
141: return -1;
142: }
143:
144: /**
145: * Reads into a binary builder.
146: */
147: public StringValue read(int length) throws IOException {
148: if (_is == null)
149: return null;
150:
151: StringValue bb = _env.createBinaryBuilder();
152:
153: bb.appendRead(_is, length);
154:
155: return bb;
156: }
157:
158: /**
159: * Reads the optional linefeed character from a \r\n
160: */
161: public boolean readOptionalLinefeed() throws IOException {
162: if (_is == null)
163: return false;
164:
165: int ch = _is.read();
166:
167: if (ch == '\n') {
168: return true;
169: } else {
170: _is.unread();
171: return false;
172: }
173: }
174:
175: public void writeToStream(OutputStream os, int length)
176: throws IOException {
177: if (_is != null) {
178: _is.writeToStream(os, length);
179: }
180: }
181:
182: /**
183: * Appends to a string builder.
184: */
185: public StringValue appendTo(StringValue builder) {
186: if (_is != null)
187: return builder.append(_is);
188: else
189: return builder;
190: }
191:
192: /**
193: * Reads a line from a file, returning null on EOF.
194: */
195: public StringValue readLine(long length) throws IOException {
196: return getLineReader().readLine(_env, this , length);
197: }
198:
199: /**
200: * Returns true on the EOF.
201: */
202: public boolean isEOF() {
203: if (_is == null)
204: return true;
205: else {
206: try {
207: // XXX: not quite right for sockets
208: return _is.available() <= 0;
209: } catch (IOException e) {
210: log.log(Level.FINE, e.toString(), e);
211:
212: return true;
213: }
214: }
215: }
216:
217: /**
218: * Returns the current location in the file.
219: */
220: public long getPosition() {
221: if (_is == null)
222: return -1;
223: else
224: return _is.getPosition();
225: }
226:
227: /**
228: * Returns the current location in the file.
229: */
230: public boolean setPosition(long offset) {
231: if (_is == null)
232: return false;
233:
234: try {
235: return _is.setPosition(offset);
236: } catch (IOException e) {
237: throw new QuercusModuleException(e);
238: }
239: }
240:
241: public long seek(long offset, int whence) {
242: long position;
243:
244: switch (whence) {
245: case BinaryInput.SEEK_CUR:
246: position = getPosition() + offset;
247: break;
248: case BinaryInput.SEEK_END:
249: // don't necessarily have an end
250: position = getPosition();
251: break;
252: case BinaryInput.SEEK_SET:
253: default:
254: position = offset;
255: break;
256: }
257:
258: if (!setPosition(position))
259: return -1L;
260: else
261: return position;
262: }
263:
264: public Value stat() {
265: return BooleanValue.FALSE;
266: }
267:
268: private LineReader getLineReader() {
269: if (_lineReader == null)
270: _lineReader = new LineReader(_env);
271:
272: return _lineReader;
273: }
274:
275: /**
276: * Closes the stream for reading.
277: */
278: public void closeRead() {
279: close();
280: }
281:
282: /**
283: * Closes the file.
284: */
285: public void close() {
286: ReadStream is = _is;
287: _is = null;
288:
289: if (is != null)
290: is.close();
291: }
292:
293: public Object toJavaObject() {
294: return this ;
295: }
296:
297: public String getResourceType() {
298: return "stream";
299: }
300:
301: /**
302: * Converts to a string.
303: */
304: public String toString() {
305: return "ReadStreamInput[" + _is.getPath() + "]";
306: }
307: }
|