001: /*
002: * BroadcastStream.java
003: *
004: * Copyright (C) 2004 Peter Graves
005: * $Id: BroadcastStream.java,v 1.7 2004/03/10 01:54:45 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 final class BroadcastStream extends Stream {
025: private final Stream[] streams;
026:
027: private BroadcastStream(Stream[] streams) throws ConditionThrowable {
028: this .streams = streams;
029: isOutputStream = true;
030: if (streams.length == 0) {
031: elementType = T;
032: isBinaryStream = true;
033: isCharacterStream = true;
034: } else {
035: elementType = streams[streams.length - 1].getElementType();
036: if (elementType == Symbol.CHARACTER
037: || elementType == Symbol.BASE_CHAR)
038: isCharacterStream = true;
039: else
040: isBinaryStream = true;
041: }
042: }
043:
044: public Stream[] getStreams() {
045: return streams;
046: }
047:
048: public LispObject typeOf() {
049: return Symbol.BROADCAST_STREAM;
050: }
051:
052: public LispClass classOf() {
053: return BuiltInClass.BROADCAST_STREAM;
054: }
055:
056: public LispObject typep(LispObject typeSpecifier)
057: throws ConditionThrowable {
058: if (typeSpecifier == Symbol.BROADCAST_STREAM)
059: return T;
060: if (typeSpecifier == BuiltInClass.BROADCAST_STREAM)
061: return T;
062: return super .typep(typeSpecifier);
063: }
064:
065: public LispObject listen() throws ConditionThrowable {
066: notSupported();
067: // Not reached.
068: return NIL;
069: }
070:
071: public LispObject fileLength() throws ConditionThrowable {
072: if (streams.length > 0)
073: return streams[streams.length - 1].fileLength();
074: else
075: return Fixnum.ZERO;
076: }
077:
078: public LispObject fileStringLength(LispObject arg)
079: throws ConditionThrowable {
080: if (streams.length > 0)
081: return streams[streams.length - 1].fileStringLength(arg);
082: else
083: return Fixnum.ONE;
084: }
085:
086: // Returns -1 at end of file.
087: protected int _readChar() throws ConditionThrowable {
088: notSupported();
089: // Not reached.
090: return -1;
091: }
092:
093: protected void _unreadChar(int n) throws ConditionThrowable {
094: notSupported();
095: }
096:
097: protected boolean _charReady() throws ConditionThrowable {
098: notSupported();
099: // Not reached.
100: return false;
101: }
102:
103: public void _writeChar(char c) throws ConditionThrowable {
104: for (int i = 0; i < streams.length; i++)
105: streams[i]._writeChar(c);
106: }
107:
108: public void _writeChars(char[] chars, int start, int end)
109: throws ConditionThrowable {
110: for (int i = 0; i < streams.length; i++)
111: streams[i]._writeChars(chars, start, end);
112: }
113:
114: public void _writeString(String s) throws ConditionThrowable {
115: for (int i = 0; i < streams.length; i++)
116: streams[i]._writeString(s);
117: }
118:
119: public void _writeLine(String s) throws ConditionThrowable {
120: for (int i = 0; i < streams.length; i++)
121: streams[i]._writeLine(s);
122: }
123:
124: // Reads an 8-bit byte.
125: public int _readByte() throws ConditionThrowable {
126: notSupported();
127: // Not reached.
128: return -1;
129: }
130:
131: // Writes an 8-bit byte.
132: public void _writeByte(int n) throws ConditionThrowable {
133: for (int i = 0; i < streams.length; i++)
134: streams[i]._writeByte(n);
135: }
136:
137: public void _finishOutput() throws ConditionThrowable {
138: for (int i = 0; i < streams.length; i++)
139: streams[i]._finishOutput();
140: }
141:
142: public void _clearInput() throws ConditionThrowable {
143: notSupported();
144: }
145:
146: protected long _getFilePosition() throws ConditionThrowable {
147: if (streams.length == 0)
148: return 0;
149: else
150: return streams[streams.length - 1]._getFilePosition();
151: }
152:
153: protected boolean _setFilePosition(LispObject arg)
154: throws ConditionThrowable {
155: return false;
156: }
157:
158: public void _close() throws ConditionThrowable {
159: setOpen(false);
160: }
161:
162: private void notSupported() throws ConditionThrowable {
163: signal(new TypeError(
164: "Operation is not supported for streams of type BROADCAST-STREAM."));
165: }
166:
167: // ### make-broadcast-stream &rest streams => broadcast-stream
168: private static final Primitive MAKE_BROADCAST_STREAM = new Primitive(
169: "make-broadcast-stream", "&rest streams") {
170: public LispObject execute(LispObject[] args)
171: throws ConditionThrowable {
172: Stream[] streams = new Stream[args.length];
173: for (int i = 0; i < args.length; i++) {
174: if (args[i] instanceof Stream) {
175: if (((Stream) args[i]).isOutputStream()) {
176: streams[i] = (Stream) args[i];
177: continue;
178: }
179: }
180: signal(new TypeError(String.valueOf(args[i])
181: + " is not an output stream."));
182: }
183: // All is well.
184: return new BroadcastStream(streams);
185: }
186: };
187:
188: // ### broadcast-stream-streams broadcast-stream => streams
189: private static final Primitive1 BROADCAST_STREAM_STREAMS = new Primitive1(
190: "broadcast-stream-streams", "broadcast-stream") {
191: public LispObject execute(LispObject arg)
192: throws ConditionThrowable {
193: try {
194: BroadcastStream stream = (BroadcastStream) arg;
195: Stream[] streams = stream.streams;
196: LispObject result = NIL;
197: for (int i = streams.length; i-- > 0;)
198: result = new Cons(streams[i], result);
199: return result;
200: } catch (ClassCastException e) {
201: return signal(new TypeError(arg,
202: Symbol.BROADCAST_STREAM));
203: }
204: }
205: };
206: }
|