001: /***** BEGIN LICENSE BLOCK *****
002: * Version: CPL 1.0/GPL 2.0/LGPL 2.1
003: *
004: * The contents of this file are subject to the Common Public
005: * License Version 1.0 (the "License"); you may not use this file
006: * except in compliance with the License. You may obtain a copy of
007: * the License at http://www.eclipse.org/legal/cpl-v10.html
008: *
009: * Software distributed under the License is distributed on an "AS
010: * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
011: * implied. See the License for the specific language governing
012: * rights and limitations under the License.
013: *
014: * Copyright (C) 2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
015: * Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
016: * Copyright (C) 2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
017: * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
018: * Copyright (C) 2006 Evan Buswell <evan@heron.sytes.net>
019: *
020: * Alternatively, the contents of this file may be used under the terms of
021: * either of the GNU General Public License Version 2 or later (the "GPL"),
022: * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
023: * in which case the provisions of the GPL or the LGPL are applicable instead
024: * of those above. If you wish to allow use of your version of this file only
025: * under the terms of either the GPL or the LGPL, and not to allow others to
026: * use your version of this file under the terms of the CPL, indicate your
027: * decision by deleting the provisions above and replace them with the notice
028: * and other provisions required by the GPL or the LGPL. If you do not delete
029: * the provisions above, a recipient may use your version of this file under
030: * the terms of any one of the CPL, the GPL or the LGPL.
031: ***** END LICENSE BLOCK *****/package org.jruby.util;
032:
033: import java.io.InputStream;
034: import java.io.OutputStream;
035: import java.io.IOException;
036: import java.io.EOFException;
037:
038: import org.jruby.Ruby;
039:
040: /**
041: */
042: public abstract class IOHandlerJavaIO extends IOHandler {
043: // Last char to be 'ungot'. <0 indicates nothing waiting to be re-got
044: protected int ungotc = -1;
045:
046: protected IOHandlerJavaIO(Ruby runtime) {
047: super (runtime);
048: }
049:
050: public ByteList gets(ByteList separatorString) throws IOException,
051: BadDescriptorException {
052: checkReadable();
053:
054: if (separatorString == null) {
055: return getsEntireStream();
056: }
057:
058: final ByteList separator = (separatorString == PARAGRAPH_DELIMETER) ? ByteList
059: .create("\n\n")
060: : separatorString;
061:
062: byte c = (byte) read();
063: if (c == -1) {
064: return null;
065: }
066:
067: ByteList buffer = new ByteList();
068:
069: LineLoop: while (true) {
070: while (c != separator.bytes[separator.begin] && c != -1) {
071: buffer.append(c);
072: c = (byte) read();
073: }
074: for (int i = 0; i < separator.realSize; i++) {
075: if (c == -1) {
076: break LineLoop;
077: } else if (c != separator.bytes[separator.begin + i]) {
078: continue LineLoop;
079: }
080: buffer.append(c);
081: if (i < separator.realSize - 1) {
082: c = (byte) read();
083: }
084: }
085: break;
086: }
087:
088: if (separatorString == PARAGRAPH_DELIMETER) {
089: while (c == separator.bytes[separator.begin]) {
090: c = (byte) read();
091: }
092: ungetc(c);
093: }
094:
095: return buffer;
096: }
097:
098: public ByteList getsEntireStream() throws IOException {
099: ByteList result = new ByteList();
100: int c;
101: while ((c = (byte) read()) != -1) {
102: result.append(c);
103: }
104:
105: // We are already at EOF
106: if (result.realSize == 0) {
107: return null;
108: }
109:
110: return result;
111: }
112:
113: public int read() throws IOException {
114: try {
115: if (ungotc >= 0) {
116: int c = ungotc;
117: ungotc = -1;
118: return c;
119: }
120:
121: return sysread();
122: } catch (EOFException e) {
123: return -1;
124: }
125: }
126:
127: public int getc() throws IOException, BadDescriptorException {
128: checkReadable();
129:
130: int c = read();
131:
132: if (c == -1) {
133: return c;
134: }
135: return c & 0xff;
136: }
137:
138: public ByteList read(int number) throws IOException,
139: BadDescriptorException {
140: try {
141:
142: if (ungotc >= 0) {
143: ByteList buf2 = sysread(number - 1);
144: buf2.prepend((byte) ungotc);
145: ungotc = -1;
146: return buf2;
147: }
148:
149: return sysread(number);
150: } catch (EOFException e) {
151: return null;
152: }
153: }
154:
155: public void ungetc(int c) {
156: // Ruby silently ignores negative ints for some reason?
157: if (c >= 0) {
158: ungotc = c;
159: }
160: }
161:
162: public void putc(int c) throws IOException, BadDescriptorException {
163: try {
164: syswrite(c);
165: flush();
166: } catch (IOException e) {
167: }
168: }
169:
170: public int write(ByteList string) throws IOException,
171: BadDescriptorException {
172: return syswrite(string);
173: }
174:
175: protected int sysread(ByteList buf, int length) throws IOException {
176: if (buf == null) {
177: throw new IOException("sysread2: Buf is null");
178: }
179:
180: int i = 0;
181: for (; i < length; i++) {
182: int c = sysread();
183:
184: if (c == -1) {
185: if (i <= 0) {
186: return -1;
187: }
188: break;
189: }
190:
191: buf.append(c);
192: }
193:
194: return i;
195: }
196:
197: // Question: We should read bytes or chars?
198: public ByteList sysread(int number) throws IOException,
199: BadDescriptorException {
200: if (!isOpen()) {
201: throw new IOException("File not open");
202: }
203: checkReadable();
204:
205: ByteList buf = new ByteList(number);
206: int position = 0;
207:
208: while (position < number) {
209: int s = sysread(buf, number - position);
210:
211: if (s == -1) {
212: if (position <= 0) {
213: throw new EOFException();
214: }
215: break;
216: }
217:
218: position += s;
219: }
220:
221: return buf;
222: }
223:
224: public abstract int sysread() throws IOException;
225:
226: public abstract InputStream getInputStream();
227:
228: public abstract OutputStream getOutputStream();
229:
230: public int ready() throws IOException {
231: return getInputStream().available();
232: }
233: }
|