01: /*
02: * Copyright 2004-2006 the original author or authors.
03: *
04: * Licensed under the Apache License, Version 2.0 (the "License");
05: * you may not use this file except in compliance with the License.
06: * You may obtain a copy of the License at
07: *
08: * http://www.apache.org/licenses/LICENSE-2.0
09: *
10: * Unless required by applicable law or agreed to in writing, software
11: * distributed under the License is distributed on an "AS IS" BASIS,
12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13: * See the License for the specific language governing permissions and
14: * limitations under the License.
15: */
16:
17: package org.compass.core.util.reader;
18:
19: import java.io.Reader;
20:
21: import org.compass.core.engine.RepeatableReader;
22:
23: /**
24: * A character stream whose source is a string. Allows for
25: * repeatable reads from the same string.
26: * <p/>
27: * Note, this is an unsafe reader in terms of {@link IndexOutOfBoundsException}.
28: *
29: * @author kimchy
30: */
31: public class StringReader extends Reader implements RepeatableReader {
32:
33: private String str;
34: private int length;
35: private int next = 0;
36: private int mark = 0;
37:
38: public StringReader(String s) {
39: this .str = s;
40: this .length = s.length();
41: }
42:
43: public int read() {
44: if (next >= length)
45: return -1;
46: return str.charAt(next++);
47: }
48:
49: public int read(char cbuf[], int off, int len) {
50: if (len == 0) {
51: return 0;
52: }
53: if (next >= length) {
54: // reset the reader for a possible next read
55: close();
56: // and return -1 to indicate no more data
57: return -1;
58: }
59: int n = Math.min(length - next, len);
60: str.getChars(next, next + n, cbuf, off);
61: next += n;
62: return n;
63: }
64:
65: public long skip(long ns) {
66: if (next >= length)
67: return 0;
68: long n = Math.min(length - next, ns);
69: next += n;
70: return n;
71: }
72:
73: public boolean ready() {
74: return true;
75: }
76:
77: public boolean markSupported() {
78: return true;
79: }
80:
81: public void mark(int readAheadLimit) {
82: if (readAheadLimit < 0) {
83: throw new IllegalArgumentException("Read-ahead limit < 0");
84: }
85: mark = next;
86: }
87:
88: public void reset() {
89: next = mark;
90: }
91:
92: public void close() {
93: next = 0;
94: mark = 0;
95: }
96:
97: }
|