2 * gnu/regexp/CharIndexedReader.java
3 * Copyright (C) 2001 Lee Sau Dan
4 * Based on gnu.regexp.CharIndexedInputStream by Wes Biggs
6 * This library is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 import java.io.Reader;
23 import java.io.BufferedReader;
24 import java.io.IOException;
26 // TODO: move(x) shouldn't rely on calling next() x times
28 class CharIndexedReader implements CharIndexed {
29 private static final int BUFFER_INCREMENT = 1024;
30 private static final int UNKNOWN = Integer.MAX_VALUE; // value for end
32 private final BufferedReader br;
33 // so that we don't try to reset() right away
34 private int index = -1;
36 private int bufsize = BUFFER_INCREMENT;
38 private int end = UNKNOWN;
40 private char cached = OUT_OF_BOUNDS;
42 // Big enough for a \r\n pair
43 // lookBehind[0] = most recent
44 // lookBehind[1] = second most recent
45 private char[] lookBehind = new char[] { OUT_OF_BOUNDS, OUT_OF_BOUNDS };
47 CharIndexedReader(Reader reader, int index) {
48 if (reader instanceof BufferedReader) {
49 br = (BufferedReader) reader;
51 br = new BufferedReader(reader,BUFFER_INCREMENT);
54 if (index > 0) move(index);
57 private boolean next() {
58 lookBehind[1] = lookBehind[0];
59 lookBehind[0] = cached;
62 cached = OUT_OF_BOUNDS;
65 end--; // closer to end
75 cached = OUT_OF_BOUNDS;
79 // convert the byte read into a char
82 } catch (IOException e) {
84 cached = OUT_OF_BOUNDS;
90 public char charAt(int index) {
93 } else if (index >= end) {
95 } else if (index >= bufsize) {
96 // Allocate more space in the buffer.
98 while (bufsize <= index) bufsize += BUFFER_INCREMENT;
102 } catch (IOException e) { }
103 } else if (this.index != index) {
107 } catch (IOException e) { }
108 } else if (index == -1) {
109 return lookBehind[0];
110 } else if (index == -2) {
111 return lookBehind[1];
112 } else if (index < -2) {
113 return OUT_OF_BOUNDS;
116 char ch = OUT_OF_BOUNDS;
120 this.index = index+1; // this.index is index of next pos relative to charAt(0)
122 // set flag that next should fail next time?
127 } catch (IOException ie) { }
132 public boolean move(int index) {
133 // move read position [index] clicks from 'charAt(0)'
134 boolean retval = true;
135 while (retval && (index-- > 0)) retval = next();
139 public boolean isValid() {
140 return (cached != OUT_OF_BOUNDS);