source: branches/0.22.x/abcl/src/org/armedbear/lisp/TwoWayStream.java

Last change on this file was 12362, checked in by vvoutilainen, 15 years ago

Make Stream extend StructureObject?, modify Stream derivatives
to set a StructureClass? symbol when invoking the superclass
constructor. Fix clinit order in Lisp.java to cope. Some
structure-classes need refining, at least TwoWayStream? needs
to allow (but not force) its derivatives to set a structure
class other than TWO-WAY-STREAM (SOCKET-STREAM being one
specific example). Thanks to Alessio Stalla and Erik Huelsmann
for helping with getting this patch into a state where
ansi tests run again.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.8 KB
Line 
1/*
2 * TwoWayStream.java
3 *
4 * Copyright (C) 2003-2005 Peter Graves
5 * $Id: TwoWayStream.java 12362 2010-01-11 20:03:29Z vvoutilainen $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36import static org.armedbear.lisp.Lisp.*;
37
38public class TwoWayStream extends Stream
39{
40    public final Stream in;
41    public final Stream out;
42
43    public TwoWayStream(Stream in, Stream out)
44    {
45        super(Symbol.TWO_WAY_STREAM);
46        this.in = in;
47        this.out = out;
48        isInputStream = true;
49        isOutputStream = true;
50    }
51
52    public TwoWayStream(Stream in, Stream out, boolean interactive)
53    {
54        this(in, out);
55        setInteractive(interactive);
56    }
57
58    @Override
59    public LispObject getElementType()
60    {
61        LispObject itype = in.getElementType();
62        LispObject otype = out.getElementType();
63        if (itype.equal(otype))
64            return itype;
65        return list(Symbol.AND, itype, otype);
66    }
67
68    public Stream getInputStream()
69    {
70        return in;
71    }
72
73    public Stream getOutputStream()
74    {
75        return out;
76    }
77
78    @Override
79    public boolean isCharacterInputStream()
80    {
81        return in.isCharacterInputStream();
82    }
83
84    @Override
85    public boolean isBinaryInputStream()
86    {
87        return in.isBinaryInputStream();
88    }
89
90    @Override
91    public boolean isCharacterOutputStream()
92    {
93        return out.isCharacterOutputStream();
94    }
95
96    @Override
97    public boolean isBinaryOutputStream()
98    {
99        return out.isBinaryOutputStream();
100    }
101
102    @Override
103    public LispObject typeOf()
104    {
105        return Symbol.TWO_WAY_STREAM;
106    }
107
108    @Override
109    public LispObject classOf()
110    {
111        return BuiltInClass.TWO_WAY_STREAM;
112    }
113
114    @Override
115    public LispObject typep(LispObject type)
116    {
117        if (type == Symbol.TWO_WAY_STREAM)
118            return T;
119        if (type == BuiltInClass.TWO_WAY_STREAM)
120            return T;
121        return super.typep(type);
122    }
123
124    // Returns -1 at end of file.
125    @Override
126    protected int _readChar() throws java.io.IOException
127    {
128        return in._readChar();
129    }
130
131    @Override
132    protected void _unreadChar(int n) throws java.io.IOException
133    {
134        in._unreadChar(n);
135    }
136
137    @Override
138    protected boolean _charReady() throws java.io.IOException
139    {
140        return in._charReady();
141    }
142
143    @Override
144    public void _writeChar(char c)
145    {
146        out._writeChar(c);
147    }
148
149    @Override
150    public void _writeChars(char[] chars, int start, int end)
151
152    {
153        out._writeChars(chars, start, end);
154    }
155
156    @Override
157    public void _writeString(String s)
158    {
159        out._writeString(s);
160    }
161
162    @Override
163    public void _writeLine(String s)
164    {
165        out._writeLine(s);
166    }
167
168    // Reads an 8-bit byte.
169    @Override
170    public int _readByte()
171    {
172        return in._readByte();
173    }
174
175    // Writes an 8-bit byte.
176    @Override
177    public void _writeByte(int n)
178    {
179        out._writeByte(n);
180    }
181
182    @Override
183    public void _finishOutput()
184    {
185        out._finishOutput();
186    }
187
188    @Override
189    public void _clearInput()
190    {
191        in._clearInput();
192    }
193
194    @Override
195    public LispObject listen()
196    {
197        return in.listen();
198    }
199
200    @Override
201    public LispObject freshLine()
202    {
203        return out.freshLine();
204    }
205
206    @Override
207    public LispObject close(LispObject abort)
208    {
209        // "The effect of CLOSE on a constructed stream is to close the
210        // argument stream only. There is no effect on the constituents of
211        // composite streams."
212        setOpen(false);
213        return T;
214    }
215
216    @Override
217    public String writeToString()
218    {
219        return unreadableString(Symbol.TWO_WAY_STREAM);
220    }
221
222    // ### make-two-way-stream input-stream output-stream => two-way-stream
223    private static final Primitive MAKE_TWO_WAY_STREAM =
224        new Primitive(Symbol.MAKE_TWO_WAY_STREAM, "input-stream output-stream")
225    {
226        @Override
227        public LispObject execute(LispObject first, LispObject second)
228
229        {
230            final Stream in = checkStream(first);
231            final Stream out = checkStream(second);
232            if (!in.isInputStream())
233                return type_error(in, list(Symbol.SATISFIES,
234                                                 Symbol.INPUT_STREAM_P));
235            if (!out.isOutputStream())
236                return type_error(out, list(Symbol.SATISFIES,
237                                                  Symbol.OUTPUT_STREAM_P));
238            return new TwoWayStream(in, out);
239        }
240    };
241
242    // ### two-way-stream-input-stream two-way-stream => input-stream
243    private static final Primitive TWO_WAY_STREAM_INPUT_STREAM =
244        new Primitive(Symbol.TWO_WAY_STREAM_INPUT_STREAM, "two-way-stream")
245    {
246        @Override
247        public LispObject execute(LispObject arg)
248        {
249           if (arg instanceof TwoWayStream) 
250               return ((TwoWayStream)arg).in;               
251           return type_error(arg, Symbol.TWO_WAY_STREAM);
252        }
253    };
254
255    // ### two-way-stream-output-stream two-way-stream => output-stream
256    private static final Primitive TWO_WAY_STREAM_OUTPUT_STREAM =
257        new Primitive(Symbol.TWO_WAY_STREAM_OUTPUT_STREAM, "two-way-stream")
258    {
259        @Override
260        public LispObject execute(LispObject arg)
261        {
262           if (arg instanceof TwoWayStream) 
263               return ((TwoWayStream)arg).out;               
264           return type_error(arg, Symbol.TWO_WAY_STREAM);
265        }
266    };
267}
Note: See TracBrowser for help on using the repository browser.