001: /*
002: * FastStringReader.java
003: *
004: * Copyright (C) 2002 Peter Graves
005: * $Id: FastStringReader.java,v 1.2 2002/12/07 10:51:08 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.j;
023:
024: import java.io.Reader;
025:
026: public final class FastStringReader extends Reader {
027: private final String s;
028: private final int length;
029: private int index;
030: private int mark;
031:
032: public FastStringReader(String s) {
033: this .s = s;
034: length = s.length();
035: }
036:
037: public final char readChar() {
038: return index < length ? s.charAt(index++) : 0;
039: }
040:
041: public final void unreadChar() {
042: Debug.assertTrue(index > 0);
043: if (index > 0)
044: --index;
045: }
046:
047: public int read() {
048: return index < length ? s.charAt(index++) : -1;
049: }
050:
051: public int read(char array[], int offset, int count) {
052: if (offset < 0 || count < 0 || offset + count > array.length)
053: throw new IndexOutOfBoundsException();
054: if (count == 0)
055: return 0;
056: final int actual = Math.min(count, length - index);
057: s.getChars(index, index + actual, array, offset);
058: index += actual;
059: return actual;
060: }
061:
062: // Returns next word (delimited by whitespace) or quoted substring,
063: // without enclosing quotes (if any).
064: public String readToken() {
065: skipWhitespace();
066: if (index == length)
067: return "";
068: char quoteChar = 0;
069: int begin = index;
070: char c = s.charAt(index++);
071: if (c == '"' || c == '\'') {
072: quoteChar = c;
073: ++begin;
074: }
075: while (index < length) {
076: c = s.charAt(index);
077: if (quoteChar != 0 && c == quoteChar) {
078: // Reached end of pattern.
079: int end = index;
080: // Skip closing quote.
081: ++index;
082: return s.substring(begin, end);
083: }
084: if (quoteChar == 0 && Character.isWhitespace(c)) {
085: // If not quoted, whitespace terminates string.
086: return s.substring(begin, index);
087: } else
088: ++index;
089: }
090: return s.substring(begin, index);
091: }
092:
093: public String readLine() {
094: final int limit = length;
095: if (index >= limit)
096: return null;
097: final int begin = index;
098: do {
099: switch (s.charAt(index)) {
100: case '\n':
101: return s.substring(begin, index++);
102: case '\r': {
103: final int end = index++;
104: // Skip following LF if any.
105: if (index < limit && s.charAt(index) == '\n')
106: ++index;
107: return s.substring(begin, end);
108: }
109: // Fall through...
110: }
111: } while (++index < limit);
112: return s.substring(begin, index);
113: }
114:
115: public long skip(long count) {
116: final long actual = Math.min(count, length - index);
117: index += actual;
118: return actual;
119: }
120:
121: public boolean ready() {
122: return true;
123: }
124:
125: public boolean markSupported() {
126: return true;
127: }
128:
129: public void mark(int readAheadLimit) {
130: if (readAheadLimit < 0)
131: throw new IllegalArgumentException("Read-ahead limit < 0");
132: mark = index;
133: }
134:
135: public void reset() {
136: index = mark;
137: }
138:
139: public void close() {
140: }
141:
142: public final String remainder() {
143: return s.substring(index);
144: }
145:
146: public final void skipWhitespace() {
147: while (index < length
148: && Character.isWhitespace(s.charAt(index)))
149: ++index;
150: }
151: }
|