diff options
Diffstat (limited to 'libjava/gnu/regexp/CharIndexedReader.java')
-rw-r--r-- | libjava/gnu/regexp/CharIndexedReader.java | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/libjava/gnu/regexp/CharIndexedReader.java b/libjava/gnu/regexp/CharIndexedReader.java new file mode 100644 index 0000000..aa0fa5a --- /dev/null +++ b/libjava/gnu/regexp/CharIndexedReader.java @@ -0,0 +1,142 @@ +/* + * gnu/regexp/CharIndexedReader.java + * Copyright (C) 2001 Lee Sau Dan + * Based on gnu.regexp.CharIndexedInputStream by Wes Biggs + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package gnu.regexp; +import java.io.Reader; +import java.io.BufferedReader; +import java.io.IOException; + +// TODO: move(x) shouldn't rely on calling next() x times + +class CharIndexedReader implements CharIndexed { + private static final int BUFFER_INCREMENT = 1024; + private static final int UNKNOWN = Integer.MAX_VALUE; // value for end + + private final BufferedReader br; + // so that we don't try to reset() right away + private int index = -1; + + private int bufsize = BUFFER_INCREMENT; + + private int end = UNKNOWN; + + private char cached = OUT_OF_BOUNDS; + + // Big enough for a \r\n pair + // lookBehind[0] = most recent + // lookBehind[1] = second most recent + private char[] lookBehind = new char[] { OUT_OF_BOUNDS, OUT_OF_BOUNDS }; + + CharIndexedReader(Reader reader, int index) { + if (reader instanceof BufferedReader) { + br = (BufferedReader) reader; + } else { + br = new BufferedReader(reader,BUFFER_INCREMENT); + } + next(); + if (index > 0) move(index); + } + + private boolean next() { + lookBehind[1] = lookBehind[0]; + lookBehind[0] = cached; + + if (end == 1) { + cached = OUT_OF_BOUNDS; + return false; + } + end--; // closer to end + + try { + if (index != -1) { + br.reset(); + } + int i = br.read(); + br.mark(bufsize); + if (i == -1) { + end = 1; + cached = OUT_OF_BOUNDS; + return false; + } + + // convert the byte read into a char + cached = (char) i; + index = 1; + } catch (IOException e) { + e.printStackTrace(); + cached = OUT_OF_BOUNDS; + return false; + } + return true; + } + + public char charAt(int index) { + if (index == 0) { + return cached; + } else if (index >= end) { + return OUT_OF_BOUNDS; + } else if (index >= bufsize) { + // Allocate more space in the buffer. + try { + while (bufsize <= index) bufsize += BUFFER_INCREMENT; + br.reset(); + br.mark(bufsize); + br.skip(index-1); + } catch (IOException e) { } + } else if (this.index != index) { + try { + br.reset(); + br.skip(index-1); + } catch (IOException e) { } + } else if (index == -1) { + return lookBehind[0]; + } else if (index == -2) { + return lookBehind[1]; + } else if (index < -2) { + return OUT_OF_BOUNDS; + } + + char ch = OUT_OF_BOUNDS; + + try { + int i = br.read(); + this.index = index+1; // this.index is index of next pos relative to charAt(0) + if (i == -1) { + // set flag that next should fail next time? + end = index; + return ch; + } + ch = (char) i; + } catch (IOException ie) { } + + return ch; + } + + public boolean move(int index) { + // move read position [index] clicks from 'charAt(0)' + boolean retval = true; + while (retval && (index-- > 0)) retval = next(); + return retval; + } + + public boolean isValid() { + return (cached != OUT_OF_BOUNDS); + } +} |