KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jruby > util > IOHandlerUnseekable


1 /***** BEGIN LICENSE BLOCK *****
2  * Version: CPL 1.0/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Common Public
5  * License Version 1.0 (the "License"); you may not use this file
6  * except in compliance with the License. You may obtain a copy of
7  * the License at http://www.eclipse.org/legal/cpl-v10.html
8  *
9  * Software distributed under the License is distributed on an "AS
10  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * rights and limitations under the License.
13  *
14  * Copyright (C) 2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
15  * Copyright (C) 2004-2006 Thomas E Enebo <enebo@acm.org>
16  * Copyright (C) 2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
17  * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
18  * Copyright (C) 2005 David Corbin <dcorbin@users.sourceforge.net>
19  * Copyright (C) 2005 Charles O Nutter <headius@headius.com>
20  *
21  * Alternatively, the contents of this file may be used under the terms of
22  * either of the GNU General Public License Version 2 or later (the "GPL"),
23  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
24  * in which case the provisions of the GPL or the LGPL are applicable instead
25  * of those above. If you wish to allow use of your version of this file only
26  * under the terms of either the GPL or the LGPL, and not to allow others to
27  * use your version of this file under the terms of the CPL, indicate your
28  * decision by deleting the provisions above and replace them with the notice
29  * and other provisions required by the GPL or the LGPL. If you do not delete
30  * the provisions above, a recipient may use your version of this file under
31  * the terms of any one of the CPL, the GPL or the LGPL.
32  ***** END LICENSE BLOCK *****/

33 package org.jruby.util;
34
35 import java.io.BufferedInputStream JavaDoc;
36 import java.io.FileOutputStream JavaDoc;
37 import java.io.IOException JavaDoc;
38 import java.io.InputStream JavaDoc;
39 import java.io.OutputStream JavaDoc;
40 import java.nio.channels.FileChannel JavaDoc;
41
42 import org.jruby.Ruby;
43 import org.jruby.RubyIO;
44
45 /**
46  * @author enebo
47  *
48  */

49 public class IOHandlerUnseekable extends IOHandlerJavaIO {
50     protected InputStream JavaDoc input = null;
51     protected OutputStream JavaDoc output = null;
52
53     /**
54      * @param inStream
55      * @param outStream
56      * @throws IOException
57      */

58     public IOHandlerUnseekable(Ruby runtime, InputStream JavaDoc inStream,
59                      OutputStream JavaDoc outStream) throws IOException JavaDoc {
60         super(runtime);
61         String JavaDoc mode = "";
62         
63         if (inStream != null) {
64             // No reason to buffer the buffer (cloning trips over this)
65
if (inStream instanceof BufferedInputStream JavaDoc) {
66                 input = inStream;
67             } else {
68                 input = new BufferedInputStream JavaDoc(inStream);
69             }
70             mode += "r";
71             isOpen = true;
72         }
73         
74         if (outStream != null) {
75             output = outStream;
76             mode += "w";
77             isOpen = true;
78         }
79         if ("rw".equals(mode)) {
80             modes = new IOModes(runtime, IOModes.RDWR);
81             isOpen = true;
82         } else {
83         
84             // Neither stream exists?
85
if (!isOpen) {
86                 throw new IOException JavaDoc("Opening nothing?");
87             }
88             
89             modes = new IOModes(runtime, mode);
90         }
91         fileno = RubyIO.getNewFileno();
92     }
93     
94     public IOHandlerUnseekable(Ruby runtime, int fileno) throws IOException JavaDoc {
95         super(runtime);
96         
97         switch (fileno) {
98         case 0:
99             input = new RubyInputStream(runtime.getIn());
100             modes = new IOModes(runtime, "r");
101             isOpen = true;
102             break;
103         case 1:
104             output = runtime.getOut();
105             modes = new IOModes(runtime, "w");
106             isOpen = true;
107             break;
108         case 2:
109             output = runtime.getErr();
110             modes = new IOModes(runtime, "w");
111             isOpen = true;
112             break;
113         default:
114             throw new IOException JavaDoc("Bad file descriptor");
115         }
116         
117         this.fileno = fileno;
118     }
119     
120     public IOHandlerUnseekable(Ruby runtime, int fileno, String JavaDoc mode) throws IOException JavaDoc {
121         super(runtime);
122
123         modes = new IOModes(runtime, mode);
124         
125         if (fileno < 0 || fileno > 2) {
126             throw new IOException JavaDoc("Bad file descriptor");
127         }
128         
129         if (modes.isReadable()) {
130             input = new RubyInputStream(System.in);
131             isOpen = true;
132             if (modes.isWriteable()) {
133                 output = System.out;
134             }
135         } else if (isWriteable()) {
136             output = System.out;
137             isOpen = true;
138         }
139         
140         this.fileno = fileno;
141     }
142     
143     public IOHandler cloneIOHandler() throws IOException JavaDoc {
144         return new IOHandlerUnseekable(getRuntime(), input, output);
145     }
146
147     // FIXME: Only close underlying stream if it is not shared by another IO.
148
// The real problem is that when an IO is dup'd, we do not actually
149
// clone the handler AND get a new fileno. The importance of this is
150
// that we need to make sure we only close underlying streams that are
151
// not shared by multiple IOHandlers.
152

153     /**
154      * <p>Close IO handler resources.</p>
155      * @throws IOException
156      * @throws BadDescriptorException
157      *
158      * @see org.jruby.util.IOHandler#close()
159      */

160     public void close() throws IOException JavaDoc, BadDescriptorException {
161         if (!isOpen()) {
162             throw new BadDescriptorException();
163         }
164         
165         isOpen = false;
166
167         // We are not allowing the underlying System stream to be closed
168
if (modes.isReadable() && input != System.in) {
169             input.close();
170         }
171         
172         // We are not allowing the underlying System stream to be closed
173
if (modes.isWriteable() && output != System.out && output != System.err) {
174             output.close();
175         }
176     }
177
178     /**
179      * @throws IOException
180      * @throws BadDescriptorException
181      * @see org.jruby.util.IOHandler#flush()
182      */

183     public void flush() throws IOException JavaDoc, BadDescriptorException {
184         checkWriteable();
185
186         output.flush();
187     }
188     
189     /**
190      * @see org.jruby.util.IOHandler#getInputStream()
191      */

192     public InputStream JavaDoc getInputStream() {
193         return input;
194     }
195
196     /**
197      * @see org.jruby.util.IOHandler#getOutputStream()
198      */

199     public OutputStream JavaDoc getOutputStream() {
200         return output;
201     }
202
203     /**
204      * @throws IOException
205      * @throws BadDescriptorException
206      * @see org.jruby.util.IOHandler#isEOF()
207      */

208     public boolean isEOF() throws IOException JavaDoc, BadDescriptorException {
209         checkReadable();
210
211         int c = input.read();
212         if (c == -1) {
213             return true;
214         }
215         ungetc(c);
216         return false;
217     }
218     
219     /**
220      * @see org.jruby.util.IOHandler#pid()
221      */

222     public int pid() {
223         // Not a process.
224
return -1;
225     }
226     
227     /**
228      * @throws PipeException
229      * @see org.jruby.util.IOHandler#pos()
230      */

231     public long pos() throws PipeException {
232         throw new IOHandler.PipeException();
233     }
234     
235     public void resetByModes(IOModes newModes) {
236     }
237     
238     /**
239      * @throws PipeException
240      * @see org.jruby.util.IOHandler#rewind()
241      */

242     public void rewind() throws PipeException {
243         throw new IOHandler.PipeException();
244     }
245     
246     /**
247      * @throws PipeException
248      * @see org.jruby.util.IOHandler#seek(long, int)
249      */

250     public void seek(long offset, int type) throws PipeException {
251         throw new IOHandler.PipeException();
252     }
253     
254     /**
255      * @see org.jruby.util.IOHandler#sync()
256      */

257     public void sync() throws IOException JavaDoc {
258         output.flush();
259         
260         if (output instanceof FileOutputStream JavaDoc) {
261             ((FileOutputStream JavaDoc) output).getFD().sync();
262         }
263     }
264
265     protected void sysread(ByteList buf, int off, int length) throws IOException JavaDoc {
266         int read = 0;
267         int n;
268         while(read < length) {
269             n = input.read(buf.bytes,off+read,length-read);
270             if(n == -1) {
271                 if(read == 0) {
272                     throw new java.io.EOFException JavaDoc();
273                 } else {
274                     break;
275                 }
276             }
277             read += n;
278         }
279         buf.realSize += read;
280     }
281
282     public ByteList sysread(int number) throws IOException JavaDoc, BadDescriptorException {
283         checkReadable();
284         byte[] buf = new byte[number];
285         int read = 0;
286         int n;
287         while(read < number) {
288             n = input.read(buf,read,number-read);
289             if(n == -1) {
290                 if(read == 0) {
291                     throw new java.io.EOFException JavaDoc();
292                 } else {
293                     break;
294                 }
295             }
296             read += n;
297         }
298         
299         return new ByteList(buf, 0, read, false);
300     }
301     
302     /**
303      * @see org.jruby.util.IOHandler#sysread()
304      */

305     public int sysread() throws IOException JavaDoc {
306         return input.read();
307     }
308
309     /**
310      * @throws IOException
311      * @throws BadDescriptorException
312      * @see org.jruby.util.IOHandler#syswrite(String buf)
313      */

314     public int syswrite(ByteList buf) throws IOException JavaDoc, BadDescriptorException {
315         getRuntime().secure(4);
316         checkWriteable();
317         
318         if (buf == null || buf.realSize == 0) {
319             return 0;
320         }
321         
322         output.write(buf.bytes,0,buf.realSize);
323
324         // Should syswrite sync?
325
if (isSync) {
326             sync();
327         }
328             
329         return buf.realSize;
330     }
331
332     /**
333      * @throws IOException
334      * @throws BadDescriptorException
335      * @see org.jruby.util.IOHandler#syswrite(String buf)
336      */

337     public int syswrite(int c) throws IOException JavaDoc, BadDescriptorException {
338         getRuntime().secure(4);
339         checkWriteable();
340         
341         output.write(c);
342
343         // Should syswrite sync?
344
if (isSync) {
345             sync();
346         }
347             
348         return c;
349     }
350     
351     public void truncate(long newLength) throws IOException JavaDoc, PipeException {
352         throw new IOHandler.PipeException();
353     }
354     
355     public FileChannel JavaDoc getFileChannel() {
356         assert false : "No file channel for unseekable IO";
357         return null;
358     }
359 }
360
Popular Tags