Frames | No Frames |
1: /* StringReader.java -- permits a String to be read as a character input stream 2: Copyright (C) 1998, 1999, 2000, 2003 Free Software Foundation 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: package java.io; 39: 40: /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 41: * "The Java Language Specification", ISBN 0-201-63451-1 42: * plus online API docs for JDK 1.2 beta from http://www.javasoft.com. 43: * Status: Believed complete and correct 44: */ 45: 46: /** 47: * This class permits a <code>String</code> to be read as a character 48: * input stream. 49: * <p> 50: * The mark/reset functionality in this class behaves differently than 51: * normal. If no mark has been set, then calling the <code>reset()</code> 52: * method rewinds the read pointer to the beginning of the <code>String</code>. 53: * 54: * @author Aaron M. Renn (arenn@urbanophile.com) 55: * @author Warren Levy (warrenl@cygnus.com) 56: * @date October 19, 1998. 57: */ 58: public class StringReader extends Reader 59: { 60: /* A String provided by the creator of the stream. */ 61: private String buf; 62: 63: /* Position of the next char in buf to be read. */ 64: private int pos; 65: 66: /* The currently marked position in the stream. */ 67: private int markedPos; 68: 69: /* The index in buf one greater than the last valid character. */ 70: private int count; 71: 72: /** 73: * Create a new <code>StringReader</code> that will read chars from the 74: * passed in <code>String</code>. This stream will read from the beginning 75: * to the end of the <code>String</code>. 76: * 77: * @param buffer The <code>String</code> this stream will read from. 78: */ 79: public StringReader(String buffer) 80: { 81: super(); 82: buf = buffer; 83: 84: count = buffer.length(); 85: markedPos = pos = 0; 86: } 87: 88: public void close() 89: { 90: synchronized (lock) 91: { 92: buf = null; 93: } 94: } 95: 96: public void mark(int readAheadLimit) throws IOException 97: { 98: synchronized (lock) 99: { 100: if (buf == null) 101: throw new IOException("Stream closed"); 102: 103: // readAheadLimit is ignored per Java Class Lib. book, p. 1692. 104: markedPos = pos; 105: } 106: } 107: 108: public boolean markSupported() 109: { 110: return true; 111: } 112: 113: public int read() throws IOException 114: { 115: synchronized (lock) 116: { 117: if (buf == null) 118: throw new IOException("Stream closed"); 119: 120: if (pos < count) 121: return ((int) buf.charAt(pos++)) & 0xFFFF; 122: return -1; 123: } 124: } 125: 126: public int read(char[] b, int off, int len) throws IOException 127: { 128: synchronized (lock) 129: { 130: if (buf == null) 131: throw new IOException("Stream closed"); 132: 133: /* Don't need to check pos value, arraycopy will check it. */ 134: if (off < 0 || len < 0 || off + len > b.length) 135: throw new ArrayIndexOutOfBoundsException(); 136: 137: if (pos >= count) 138: return -1; 139: 140: int lastChar = Math.min(count, pos + len); 141: buf.getChars(pos, lastChar, b, off); 142: int numChars = lastChar - pos; 143: pos = lastChar; 144: return numChars; 145: } 146: } 147: 148: /** 149: * This method determines if the stream is ready to be read. This class 150: * is always ready to read and so always returns <code>true</code>, unless 151: * close() has previously been called in which case an IOException is 152: * thrown. 153: * 154: * @return <code>true</code> to indicate that this object is ready to be read. 155: * @exception IOException If the stream is closed. 156: */ 157: public boolean ready() throws IOException 158: { 159: if (buf == null) 160: throw new IOException("Stream closed"); 161: 162: return true; 163: } 164: 165: /** 166: * Sets the read position in the stream to the previously 167: * marked position or to 0 (i.e., the beginning of the stream) if the mark 168: * has not already been set. 169: */ 170: public void reset() throws IOException 171: { 172: synchronized (lock) 173: { 174: if (buf == null) 175: throw new IOException("Stream closed"); 176: 177: pos = markedPos; 178: } 179: } 180: 181: /** 182: * This method attempts to skip the requested number of chars in the 183: * input stream. It does this by advancing the <code>pos</code> value by 184: * the specified number of chars. It this would exceed the length of the 185: * buffer, then only enough chars are skipped to position the stream at 186: * the end of the buffer. The actual number of chars skipped is returned. 187: * 188: * @param n The requested number of chars to skip 189: * 190: * @return The actual number of chars skipped. 191: */ 192: public long skip(long n) throws IOException 193: { 194: synchronized (lock) 195: { 196: if (buf == null) 197: throw new IOException("Stream closed"); 198: 199: // Even though the var numChars is a long, in reality it can never 200: // be larger than an int since the result of subtracting 2 positive 201: // ints will always fit in an int. Since we have to return a long 202: // anyway, numChars might as well just be a long. 203: long numChars = Math.min((long) (count - pos), n < 0 ? 0L : n); 204: pos += numChars; 205: return numChars; 206: } 207: } 208: }