resolve darcs stupidity
[org.ibex.core.git] / src / gnu / regexp / CharIndexedReader.java
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
21 package gnu.regexp;
22 import java.io.Reader;
23 import java.io.BufferedReader;
24 import java.io.IOException;
25
26 // TODO: move(x) shouldn't rely on calling next() x times
27
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
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 }