001: /*
002: * StringInputStream.java
003: *
004: * Copyright (C) 2003-2004 Peter Graves
005: * $Id: StringInputStream.java,v 1.15 2004/03/11 11:29:04 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 StringInputStream extends Stream {
025: final String s;
026: final int start;
027: final int end;
028:
029: public StringInputStream(String s) {
030: this (s, 0, s.length());
031: }
032:
033: public StringInputStream(String s, int start) {
034: this (s, start, s.length());
035: }
036:
037: public StringInputStream(String s, int start, int end) {
038: elementType = Symbol.CHARACTER;
039: isInputStream = true;
040: isOutputStream = false;
041: isCharacterStream = true;
042: isBinaryStream = false;
043: this .s = s;
044: this .start = start;
045: this .end = end;
046: offset = start;
047: }
048:
049: public LispObject typeOf() {
050: return Symbol.STRING_INPUT_STREAM;
051: }
052:
053: public LispClass classOf() {
054: return BuiltInClass.STRING_INPUT_STREAM;
055: }
056:
057: public LispObject typep(LispObject type) throws ConditionThrowable {
058: if (type == Symbol.STRING_INPUT_STREAM)
059: return T;
060: if (type == Symbol.STRING_STREAM)
061: return T;
062: if (type == BuiltInClass.STRING_INPUT_STREAM)
063: return T;
064: if (type == BuiltInClass.STRING_STREAM)
065: return T;
066: return super .typep(type);
067: }
068:
069: public LispObject close(LispObject abort) throws ConditionThrowable {
070: setOpen(false);
071: return T;
072: }
073:
074: public LispObject listen() {
075: return offset < end ? T : NIL;
076: }
077:
078: protected int _readChar() {
079: if (offset >= end)
080: return -1;
081: int n = s.charAt(offset);
082: ++offset;
083: if (n == '\n')
084: ++lineNumber;
085: return n;
086: }
087:
088: protected void _unreadChar(int n) {
089: if (offset > start) {
090: --offset;
091: if (n == '\n')
092: --lineNumber;
093: }
094: }
095:
096: protected boolean _charReady() {
097: return true;
098: }
099:
100: public String toString() {
101: return unreadableString("STRING-INPUT-STREAM");
102: }
103:
104: // ### make-string-input-stream
105: // make-string-input-stream string &optional start end => string-stream
106: private static final Primitive MAKE_STRING_INPUT_STREAM = new Primitive(
107: "make-string-input-stream", "string &optional start end") {
108: public LispObject execute(LispObject arg)
109: throws ConditionThrowable {
110: return new StringInputStream(arg.getStringValue());
111: }
112:
113: public LispObject execute(LispObject first, LispObject second)
114: throws ConditionThrowable {
115: String s = first.getStringValue();
116: int start = Fixnum.getValue(second);
117: return new StringInputStream(s, start);
118: }
119:
120: public LispObject execute(LispObject first, LispObject second,
121: LispObject third) throws ConditionThrowable {
122: String s = first.getStringValue();
123: int start = Fixnum.getValue(second);
124: if (third == NIL)
125: return new StringInputStream(s, start);
126: int end = Fixnum.getValue(third);
127: return new StringInputStream(s, start, end);
128: }
129: };
130:
131: // ### string-input-stream-current
132: private static final Primitive1 STRING_INPUT_STREAM_CURRENT = new Primitive1(
133: "string-input-stream-current", PACKAGE_EXT, true, "stream") {
134: public LispObject execute(LispObject arg)
135: throws ConditionThrowable {
136: if (arg instanceof StringInputStream)
137: return new Fixnum(((StringInputStream) arg).getOffset());
138: return signal(new TypeError(String.valueOf(arg)
139: + " is not a string input stream."));
140: }
141: };
142: }
|