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: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.vfs;
030:
031: import java.io.*;
032:
033: public class TempStream extends StreamImpl {
034: private String _encoding;
035: private TempBuffer _head;
036: private TempBuffer _tail;
037:
038: public TempStream() {
039: }
040:
041: /**
042: * Initializes the temp stream for writing.
043: */
044: public void openWrite() {
045: TempBuffer ptr = _head;
046:
047: _head = null;
048: _tail = null;
049:
050: _encoding = null;
051:
052: TempBuffer.freeAll(ptr);
053: }
054:
055: public byte[] getTail() {
056: return _tail.getBuffer();
057: }
058:
059: /**
060: * Sets the encoding.
061: */
062: public void setEncoding(String encoding) {
063: _encoding = encoding;
064: }
065:
066: /**
067: * Gets the encoding.
068: */
069: public String getEncoding() {
070: return _encoding;
071: }
072:
073: @Override
074: public boolean canWrite() {
075: return true;
076: }
077:
078: /**
079: * Writes a chunk of data to the temp stream.
080: */
081: @Override
082: public void write(byte[] buf, int offset, int length, boolean isEnd)
083: throws IOException {
084: while (length > 0) {
085: if (_tail == null)
086: addBuffer(TempBuffer.allocate());
087: else if (_tail._buf.length <= _tail._length)
088: addBuffer(TempBuffer.allocate());
089:
090: int sublen = _tail._buf.length - _tail._length;
091: if (length < sublen)
092: sublen = length;
093:
094: System.arraycopy(buf, offset, _tail._buf, _tail._length,
095: sublen);
096:
097: length -= sublen;
098: offset += sublen;
099: _tail._length += sublen;
100: }
101: }
102:
103: private void addBuffer(TempBuffer buf) {
104: buf._next = null;
105: if (_tail != null) {
106: _tail._next = buf;
107: _tail = buf;
108: } else {
109: _tail = buf;
110: _head = buf;
111: }
112:
113: _head._bufferCount++;
114: }
115:
116: @Override
117: public void flush() throws IOException {
118: }
119:
120: /**
121: * Opens a read stream to the buffer.
122: */
123: public ReadStream openRead() throws IOException {
124: close();
125:
126: TempReadStream read = new TempReadStream(_head);
127: read.setFreeWhenDone(true);
128: _head = null;
129: _tail = null;
130:
131: return new ReadStream(read);
132: }
133:
134: /**
135: * Opens a read stream to the buffer.
136: *
137: * @param free if true, frees the buffer as it's read
138: */
139: public ReadStream openReadAndSaveBuffer() throws IOException {
140: close();
141:
142: TempReadStream read = new TempReadStream(_head);
143: read.setFreeWhenDone(false);
144:
145: return new ReadStream(read);
146: }
147:
148: /**
149: * Opens a read stream to the buffer.
150: */
151: public void openRead(ReadStream rs) throws IOException {
152: close();
153:
154: TempReadStream tempReadStream = new TempReadStream(_head);
155: tempReadStream.setPath(getPath());
156: tempReadStream.setFreeWhenDone(true);
157:
158: _head = null;
159: _tail = null;
160:
161: rs.init(tempReadStream, null);
162: }
163:
164: /**
165: * Returns the head buffer.
166: */
167: public TempBuffer getHead() {
168: return _head;
169: }
170:
171: public void writeToStream(OutputStream os) throws IOException {
172: for (TempBuffer ptr = _head; ptr != null; ptr = ptr._next) {
173: os.write(ptr.getBuffer(), 0, ptr.getLength());
174: }
175: }
176:
177: /**
178: * Returns the total length of the buffer's bytes
179: */
180: public int getLength() {
181: int length = 0;
182:
183: for (TempBuffer ptr = _head; ptr != null; ptr = ptr._next) {
184: length += ptr.getLength();
185: }
186:
187: return length;
188: }
189:
190: @Override
191: public void clearWrite() {
192: TempBuffer ptr = _head;
193:
194: _head = null;
195: _tail = null;
196:
197: TempBuffer.freeAll(ptr);
198: }
199:
200: public void discard() {
201: _head = null;
202: _tail = null;
203: }
204:
205: /**
206: * Copies the temp stream;
207: */
208: public TempStream copy() {
209: TempStream newStream = new TempStream();
210:
211: TempBuffer ptr = _head;
212:
213: for (; ptr != null; ptr = ptr.getNext()) {
214: TempBuffer newPtr = TempBuffer.allocate();
215:
216: if (newStream._tail != null)
217: newStream._tail.setNext(newPtr);
218: else
219: newStream._head = newPtr;
220: newStream._tail = newPtr;
221:
222: newPtr.write(ptr.getBuffer(), 0, ptr.getLength());
223: }
224:
225: return newStream;
226: }
227:
228: /**
229: * Clean up the temp stream.
230: */
231: public void destroy() {
232: try {
233: close();
234: } catch (IOException e) {
235: } finally {
236: TempBuffer ptr = _head;
237:
238: _head = null;
239: _tail = null;
240:
241: TempBuffer.freeAll(ptr);
242: }
243: }
244: }
|