001: /*
002: * TwoWayStream.java
003: *
004: * Copyright (C) 2003-2004 Peter Graves
005: * $Id: TwoWayStream.java,v 1.22 2004/06/23 01:42:33 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.lisp;
023:
024: public class TwoWayStream extends Stream {
025: private final Stream in;
026: private final Stream out;
027:
028: public TwoWayStream(Stream in, Stream out) {
029: this .in = in;
030: this .out = out;
031: isInputStream = true;
032: isOutputStream = true;
033: }
034:
035: public TwoWayStream(Stream in, Stream out, boolean interactive) {
036: this (in, out);
037: setInteractive(interactive);
038: }
039:
040: public LispObject getElementType() throws ConditionThrowable {
041: LispObject itype = in.getElementType();
042: LispObject otype = out.getElementType();
043: if (itype.equal(otype))
044: return itype;
045: return list3(Symbol.AND, itype, otype);
046: }
047:
048: public Stream getInputStream() {
049: return in;
050: }
051:
052: public Stream getOutputStream() {
053: return out;
054: }
055:
056: public boolean isCharacterInputStream() throws ConditionThrowable {
057: return in.isCharacterInputStream();
058: }
059:
060: public boolean isBinaryInputStream() throws ConditionThrowable {
061: return in.isBinaryInputStream();
062: }
063:
064: public boolean isCharacterOutputStream() throws ConditionThrowable {
065: return out.isCharacterOutputStream();
066: }
067:
068: public boolean isBinaryOutputStream() throws ConditionThrowable {
069: return out.isBinaryOutputStream();
070: }
071:
072: public LispObject typeOf() {
073: return Symbol.TWO_WAY_STREAM;
074: }
075:
076: public LispClass classOf() {
077: return BuiltInClass.TWO_WAY_STREAM;
078: }
079:
080: public LispObject typep(LispObject type) throws ConditionThrowable {
081: if (type == Symbol.TWO_WAY_STREAM)
082: return T;
083: if (type == BuiltInClass.TWO_WAY_STREAM)
084: return T;
085: return super .typep(type);
086: }
087:
088: // Returns -1 at end of file.
089: protected int _readChar() throws ConditionThrowable {
090: return in._readChar();
091: }
092:
093: protected void _unreadChar(int n) throws ConditionThrowable {
094: in._unreadChar(n);
095: }
096:
097: protected boolean _charReady() throws ConditionThrowable {
098: return in._charReady();
099: }
100:
101: public void _writeChar(char c) throws ConditionThrowable {
102: out._writeChar(c);
103: }
104:
105: public void _writeChars(char[] chars, int start, int end)
106: throws ConditionThrowable {
107: out._writeChars(chars, start, end);
108: }
109:
110: public void _writeString(String s) throws ConditionThrowable {
111: out._writeString(s);
112: }
113:
114: public void _writeLine(String s) throws ConditionThrowable {
115: out._writeLine(s);
116: }
117:
118: // Reads an 8-bit byte.
119: public int _readByte() throws ConditionThrowable {
120: return in._readByte();
121: }
122:
123: // Writes an 8-bit byte.
124: public void _writeByte(int n) throws ConditionThrowable {
125: out._writeByte(n);
126: }
127:
128: public void _finishOutput() throws ConditionThrowable {
129: out._finishOutput();
130: }
131:
132: public void _clearInput() throws ConditionThrowable {
133: in._clearInput();
134: }
135:
136: public LispObject listen() throws ConditionThrowable {
137: return in.listen();
138: }
139:
140: public LispObject freshLine() throws ConditionThrowable {
141: return out.freshLine();
142: }
143:
144: public LispObject close(LispObject abort) throws ConditionThrowable {
145: // "The effect of CLOSE on a constructed stream is to close the
146: // argument stream only. There is no effect on the constituents of
147: // composite streams."
148: setOpen(false);
149: return T;
150: }
151:
152: public String writeToString() {
153: return unreadableString("TWO-WAY-STREAM");
154: }
155:
156: // ### make-two-way-stream
157: // input-stream output-stream => two-way-stream
158: private static final Primitive2 MAKE_TWO_WAY_STREAM = new Primitive2(
159: "make-two-way-stream", "input-stream output-stream") {
160: public LispObject execute(LispObject first, LispObject second)
161: throws ConditionThrowable {
162: if (!(first instanceof Stream))
163: return signal(new TypeError(first, Symbol.STREAM));
164: if (!(second instanceof Stream))
165: return signal(new TypeError(second, Symbol.STREAM));
166: Stream in = (Stream) first;
167: if (!in.isInputStream())
168: return signal(new TypeError(in, "input stream"));
169: Stream out = (Stream) second;
170: if (!out.isOutputStream())
171: return signal(new TypeError(out, "output stream"));
172: return new TwoWayStream(in, out);
173: }
174: };
175:
176: // ### two-way-stream-input-stream
177: // two-way-stream => input-stream
178: private static final Primitive1 TWO_WAY_STREAM_INPUT_STREAM = new Primitive1(
179: "two-way-stream-input-stream", "two-way-stream") {
180: public LispObject execute(LispObject arg)
181: throws ConditionThrowable {
182: if (arg instanceof TwoWayStream)
183: return ((TwoWayStream) arg).getInputStream();
184: return signal(new TypeError(arg, Symbol.TWO_WAY_STREAM));
185: }
186: };
187:
188: // ### two-way-stream-output-stream
189: // two-way-stream => output-stream
190: private static final Primitive1 TWO_WAY_STREAM_OUTPUT_STREAM = new Primitive1(
191: "two-way-stream-output-stream", "two-way-stream") {
192: public LispObject execute(LispObject arg)
193: throws ConditionThrowable {
194: if (arg instanceof TwoWayStream)
195: return ((TwoWayStream) arg).getOutputStream();
196: return signal(new TypeError(arg, Symbol.TWO_WAY_STREAM));
197: }
198: };
199: }
|