/jEdit/tags/jedit-4-0-pre5/gnu/regexp/CharIndexedReader.java
Java | 142 lines | 95 code | 19 blank | 28 comment | 32 complexity | b9cc9a50c28e53c8c1cbcc91d4d1eccf MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
1/*
2 * gnu/regexp/CharIndexedReader.java
3 * Copyright (C) 2001 Lee Sau Dan
4 * Based on gnu.regexp.CharIndexedInputStream by Wes Biggs
5 *
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.
10 *
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.
15 *
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.
19 */
20
21package gnu.regexp;
22import java.io.Reader;
23import java.io.BufferedReader;
24import java.io.IOException;
25
26// TODO: move(x) shouldn't rely on calling next() x times
27
28class CharIndexedReader implements CharIndexed {
29 private static final int BUFFER_INCREMENT = 1024;
30 private static final int UNKNOWN = Integer.MAX_VALUE; // value for end
31
32 private final BufferedReader br;
33 // so that we don't try to reset() right away
34 private int index = -1;
35
36 private int bufsize = BUFFER_INCREMENT;
37
38 private int end = UNKNOWN;
39
40 private char cached = OUT_OF_BOUNDS;
41
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 };
46
47 CharIndexedReader(Reader reader, int index) {
48 if (reader instanceof BufferedReader) {
49 br = (BufferedReader) reader;
50 } else {
51 br = new BufferedReader(reader,BUFFER_INCREMENT);
52 }
53 next();
54 if (index > 0) move(index);
55 }
56
57 private boolean next() {
58 lookBehind[1] = lookBehind[0];
59 lookBehind[0] = cached;
60
61 if (end == 1) {
62 cached = OUT_OF_BOUNDS;
63 return false;
64 }
65 end--; // closer to end
66
67 try {
68 if (index != -1) {
69 br.reset();
70 }
71 int i = br.read();
72 br.mark(bufsize);
73 if (i == -1) {
74 end = 1;
75 cached = OUT_OF_BOUNDS;
76 return false;
77 }
78
79 // convert the byte read into a char
80 cached = (char) i;
81 index = 1;
82 } catch (IOException e) {
83 e.printStackTrace();
84 cached = OUT_OF_BOUNDS;
85 return false;
86 }
87 return true;
88 }
89
90 public char charAt(int index) {
91 if (index == 0) {
92 return cached;
93 } else if (index >= end) {
94 return OUT_OF_BOUNDS;
95 } else if (index >= bufsize) {
96 // Allocate more space in the buffer.
97 try {
98 while (bufsize <= index) bufsize += BUFFER_INCREMENT;
99 br.reset();
100 br.mark(bufsize);
101 br.skip(index-1);
102 } catch (IOException e) { }
103 } else if (this.index != index) {
104 try {
105 br.reset();
106 br.skip(index-1);
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;
114 }
115
116 char ch = OUT_OF_BOUNDS;
117
118 try {
119 int i = br.read();
120 this.index = index+1; // this.index is index of next pos relative to charAt(0)
121 if (i == -1) {
122 // set flag that next should fail next time?
123 end = index;
124 return ch;
125 }
126 ch = (char) i;
127 } catch (IOException ie) { }
128
129 return ch;
130 }
131
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();
136 return retval;
137 }
138
139 public boolean isValid() {
140 return (cached != OUT_OF_BOUNDS);
141 }
142}