KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > lib > file > WrappedStream


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Emil Ong
28  */

29
30 package com.caucho.quercus.lib.file;
31
32 import com.caucho.quercus.QuercusModuleException;
33 import com.caucho.quercus.env.*;
34 import com.caucho.vfs.TempBuffer;
35
36 import java.io.IOException JavaDoc;
37 import java.io.InputStream JavaDoc;
38 import java.io.OutputStream JavaDoc;
39 import java.io.UnsupportedEncodingException JavaDoc;
40
41 /**
42  * A stream that has its operations mediated by a Quercus object.
43  */

44 public class WrappedStream implements BinaryInput, BinaryOutput {
45   private byte []printBuffer = new byte[1];
46
47   private Env _env;
48   private Value _wrapper;
49   private InputStream JavaDoc _is;
50   private OutputStream JavaDoc _os;
51   private int _buffer;
52   private boolean _doUnread = false;
53
54   private int _writeLength;
55
56   private WrappedStream(Env env, Value wrapper)
57   {
58     _env = env;
59
60     _wrapper = wrapper;
61   }
62
63   public WrappedStream(Env env, QuercusClass qClass,
64                        StringValue path, StringValue mode, LongValue options)
65   {
66     _env = env;
67
68     _wrapper = qClass.callNew(_env, new Value[0]);
69
70     _wrapper.callMethod(_env, "stream_open",
71                         path, mode, options, NullValue.NULL);
72   }
73
74   public InputStream JavaDoc getInputStream()
75   {
76     if (_is == null)
77       _is = new WrappedInputStream();
78
79     return _is;
80   }
81
82   public OutputStream JavaDoc getOutputStream()
83   {
84     if (_os == null)
85       _os = new WrappedOutputStream();
86
87     return _os;
88   }
89
90   /**
91    * Opens a new copy.
92    */

93   public BinaryInput openCopy()
94     throws IOException JavaDoc
95   {
96     return new WrappedStream(_env, _wrapper);
97   }
98
99   /**
100    * Sets the current read encoding. The encoding can either be a
101    * Java encoding name or a mime encoding.
102    *
103    * @param encoding name of the read encoding
104    */

105   public void setEncoding(String JavaDoc encoding)
106     throws UnsupportedEncodingException JavaDoc
107   {
108   }
109
110   public void closeRead()
111   {
112     close();
113   }
114
115   public void closeWrite()
116   {
117     close();
118   }
119
120   public void close()
121   {
122     _wrapper.callMethod(_env, "stream_close");
123   }
124
125   /**
126    * Reads a character from a file, returning -1 on EOF.
127    */

128   public int read()
129     throws IOException JavaDoc
130   {
131     if (_doUnread) {
132       _doUnread = false;
133
134       return _buffer;
135     } else {
136       Value output = _wrapper.callMethod(_env, "stream_read", LongValue.ONE);
137
138       _buffer = (int) output.toLong();
139
140       return _buffer;
141     }
142   }
143
144   /**
145    * Unread a character.
146    */

147   public void unread()
148     throws IOException JavaDoc
149   {
150     _doUnread = true;
151   }
152
153   public int read(byte []buffer, int offset, int length)
154   {
155     Value output = _wrapper.callMethod(_env, "stream_read",
156                                        LongValue.create(length));
157
158     // XXX "0"?
159
if (! output.toBoolean())
160       return -1;
161
162     byte []outputBytes = output.toString().getBytes();
163
164     if (length > outputBytes.length)
165       length = outputBytes.length;
166
167     System.arraycopy(outputBytes, 0, buffer, offset, length);
168
169     return length;
170   }
171
172   /**
173    * Reads a Binary string.
174    */

175   public BinaryValue read(int length)
176     throws IOException JavaDoc
177   {
178     Value output = _wrapper.callMethod(_env, "stream_read",
179                                        LongValue.create(length));
180
181     return output.toBinaryValue(_env);
182   }
183
184   /**
185    * Reads the optional linefeed character from a \r\n
186    */

187   public boolean readOptionalLinefeed()
188     throws IOException JavaDoc
189   {
190     int ch = read();
191
192     if (ch == '\n') {
193       return true;
194     }
195     else {
196       unread();
197       return false;
198     }
199   }
200
201     /**
202    * Reads a line from a file, returning null on EOF.
203    */

204   public StringValue readLine(long length)
205     throws IOException JavaDoc
206   {
207     StringBuilderValue sb = new StringBuilderValue();
208
209     int ch;
210
211     for (; length > 0 && (ch = read()) >= 0; length--) {
212       if (ch == '\n') {
213         sb.append((char) ch);
214         return sb;
215       }
216       else if (ch == '\r') {
217         sb.append('\r');
218
219         int ch2 = read();
220
221         if (ch == '\n')
222           sb.append('\n');
223         else
224           unread();
225
226         return sb;
227       }
228       else
229         sb.append((char) ch);
230     }
231
232     if (sb.length() == 0)
233       return null;
234     else
235       return sb;
236   }
237   
238   public void write(byte []buffer, int offset, int length)
239     throws IOException JavaDoc
240   {
241     BinaryBuilderValue bb = new BinaryBuilderValue(buffer, offset, length);
242
243     Value output = _wrapper.callMethod(_env, "stream_write", bb);
244
245     _writeLength = (int) output.toLong();
246   }
247
248   /**
249    * Writes to a stream.
250    */

251   public int write(InputStream JavaDoc is, int length)
252   {
253     int writeLength = 0;
254
255     TempBuffer tb = TempBuffer.allocate();
256     byte []buffer = tb.getBuffer();
257
258     try {
259       while (length > 0) {
260         int sublen;
261
262         if (length < buffer.length)
263           sublen = length;
264         else
265           sublen = buffer.length;
266
267         sublen = is.read(buffer, 0, sublen);
268
269         if (sublen < 0)
270           break;
271
272         for (int offset = 0; offset < sublen;) {
273           write(buffer, offset, sublen);
274
275           if (_writeLength > 0)
276             offset += _writeLength;
277           else
278             return writeLength;
279         }
280
281         writeLength += sublen;
282         length -= sublen;
283       }
284
285       return writeLength;
286     } catch (IOException JavaDoc e) {
287       throw new QuercusModuleException(e);
288     } finally {
289       TempBuffer.free(tb);
290     }
291   }
292
293   /**
294    * Prints a string to a file.
295    */

296   public void print(char v)
297     throws IOException JavaDoc
298   {
299     printBuffer[0] = (byte) v;
300
301     write(printBuffer, 0, 1);
302   }
303
304   /**
305    * Prints a string to a file.
306    */

307   public void print(String JavaDoc v)
308     throws IOException JavaDoc
309   {
310     for (int i = 0; i < v.length(); i++)
311       print(v.charAt(i));
312   }
313
314   /**
315    * Returns true if end-of-file has been reached
316    */

317   public boolean isEOF()
318   {
319     return _wrapper.callMethod(_env, "stream_eof").toBoolean();
320   }
321
322   /**
323    * Tells the position in the stream
324    */

325   public long getPosition()
326   {
327     return _wrapper.callMethod(_env, "stream_tell").toLong();
328   }
329
330   /**
331    * Sets the position.
332    */

333   public boolean setPosition(long offset)
334   {
335     LongValue offsetValue = LongValue.create(offset);
336     LongValue whenceValue = LongValue.create(SEEK_SET);
337
338     return _wrapper.callMethod(_env, "stream_seek",
339                                offsetValue, whenceValue).toBoolean();
340   }
341
342   public long seek(long offset, int whence)
343   {
344     LongValue offsetValue = LongValue.create(offset);
345     LongValue whenceValue = LongValue.create(whence);
346
347     return _wrapper.callMethod(_env, "stream_seek",
348                                offsetValue, whenceValue).toLong();
349   }
350
351   public void flush()
352     throws IOException JavaDoc
353   {
354     if (! _wrapper.callMethod(_env, "stream_flush").toBoolean())
355       throw new IOException JavaDoc(); // Get around java.io.Flushable
356
}
357
358   public Value stat()
359   {
360     return _wrapper.callMethod(_env, "stream_flush");
361   }
362
363   private class WrappedInputStream extends InputStream JavaDoc {
364     public int read()
365       throws IOException JavaDoc
366     {
367       return WrappedStream.this.read();
368     }
369   }
370
371   private class WrappedOutputStream extends OutputStream JavaDoc {
372     public void write(int b)
373       throws IOException JavaDoc
374     {
375       _wrapper.callMethod(_env, "stream_write", LongValue.create(b));
376     }
377   }
378 }
379
Popular Tags