1 21 22 package org.armedbear.lisp; 23 24 public final class BroadcastStream extends Stream 25 { 26 private final Stream[] streams; 27 28 private BroadcastStream(Stream[] streams) throws ConditionThrowable 29 { 30 this.streams = streams; 31 isOutputStream = true; 32 if (streams.length == 0) { 33 elementType = T; 34 isBinaryStream = true; 35 isCharacterStream = true; 36 } else { 37 elementType = streams[streams.length-1].getElementType(); 38 if (elementType == Symbol.CHARACTER || elementType == Symbol.BASE_CHAR) 39 isCharacterStream = true; 40 else 41 isBinaryStream = true; 42 } 43 } 44 45 public Stream[] getStreams() 46 { 47 return streams; 48 } 49 50 public LispObject typeOf() 51 { 52 return Symbol.BROADCAST_STREAM; 53 } 54 55 public LispClass classOf() 56 { 57 return BuiltInClass.BROADCAST_STREAM; 58 } 59 60 public LispObject typep(LispObject typeSpecifier) throws ConditionThrowable 61 { 62 if (typeSpecifier == Symbol.BROADCAST_STREAM) 63 return T; 64 if (typeSpecifier == BuiltInClass.BROADCAST_STREAM) 65 return T; 66 return super.typep(typeSpecifier); 67 } 68 69 public LispObject listen() throws ConditionThrowable 70 { 71 notSupported(); 72 return NIL; 74 } 75 76 public LispObject fileLength() throws ConditionThrowable 77 { 78 if (streams.length > 0) 79 return streams[streams.length - 1].fileLength(); 80 else 81 return Fixnum.ZERO; 82 } 83 84 public LispObject fileStringLength(LispObject arg) throws ConditionThrowable 85 { 86 if (streams.length > 0) 87 return streams[streams.length - 1].fileStringLength(arg); 88 else 89 return Fixnum.ONE; 90 } 91 92 protected int _readChar() throws ConditionThrowable 94 { 95 notSupported(); 96 return -1; 98 } 99 100 protected void _unreadChar(int n) throws ConditionThrowable 101 { 102 notSupported(); 103 } 104 105 protected boolean _charReady() throws ConditionThrowable 106 { 107 notSupported(); 108 return false; 110 } 111 112 public void _writeChar(char c) throws ConditionThrowable 113 { 114 for (int i = 0; i < streams.length; i++) 115 streams[i]._writeChar(c); 116 } 117 118 public void _writeChars(char[] chars, int start, int end) 119 throws ConditionThrowable 120 { 121 for (int i = 0; i < streams.length; i++) 122 streams[i]._writeChars(chars, start, end); 123 } 124 125 public void _writeString(String s) throws ConditionThrowable 126 { 127 for (int i = 0; i < streams.length; i++) 128 streams[i]._writeString(s); 129 } 130 131 public void _writeLine(String s) throws ConditionThrowable 132 { 133 for (int i = 0; i < streams.length; i++) 134 streams[i]._writeLine(s); 135 } 136 137 public int _readByte() throws ConditionThrowable 139 { 140 notSupported(); 141 return -1; 143 } 144 145 public void _writeByte(int n) throws ConditionThrowable 147 { 148 for (int i = 0; i < streams.length; i++) 149 streams[i]._writeByte(n); 150 } 151 152 public void _finishOutput() throws ConditionThrowable 153 { 154 for (int i = 0; i < streams.length; i++) 155 streams[i]._finishOutput(); 156 } 157 158 public void _clearInput() throws ConditionThrowable 159 { 160 notSupported(); 161 } 162 163 protected long _getFilePosition() throws ConditionThrowable 164 { 165 if (streams.length == 0) 166 return 0; 167 else 168 return streams[streams.length-1]._getFilePosition(); 169 } 170 171 protected boolean _setFilePosition(LispObject arg) throws ConditionThrowable 172 { 173 return false; 174 } 175 176 public void _close() throws ConditionThrowable 177 { 178 setOpen(false); 179 } 180 181 private void notSupported() throws ConditionThrowable 182 { 183 signal(new TypeError("Operation is not supported for streams of type BROADCAST-STREAM.")); 184 } 185 186 private static final Primitive MAKE_BROADCAST_STREAM = 188 new Primitive("make-broadcast-stream", "&rest streams") 189 { 190 public LispObject execute(LispObject[] args) throws ConditionThrowable 191 { 192 Stream[] streams = new Stream[args.length]; 193 for (int i = 0; i < args.length; i++) { 194 if (args[i] instanceof Stream) { 195 if (((Stream)args[i]).isOutputStream()) { 196 streams[i] = (Stream) args[i]; 197 continue; 198 } 199 } 200 signal(new TypeError(String.valueOf(args[i]) + 201 " is not an output stream.")); 202 } 203 return new BroadcastStream(streams); 205 } 206 }; 207 208 private static final Primitive1 BROADCAST_STREAM_STREAMS = 210 new Primitive1("broadcast-stream-streams", "broadcast-stream") 211 { 212 public LispObject execute(LispObject arg) throws ConditionThrowable 213 { 214 try { 215 BroadcastStream stream = (BroadcastStream) arg; 216 Stream[] streams = stream.streams; 217 LispObject result = NIL; 218 for (int i = streams.length; i-- > 0;) 219 result = new Cons(streams[i], result); 220 return result; 221 } 222 catch (ClassCastException e) { 223 return signal(new TypeError(arg, Symbol.BROADCAST_STREAM)); 224 } 225 } 226 }; 227 } 228 | Popular Tags |