151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 261cf642f86a0af82e88fb27f31e6842435326b5aPrzemyslaw Szczepaniak * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.io; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A character stream whose source is a string. 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Mark Reinhold 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.1 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class StringReader extends Reader { 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String str; 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int length; 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int next = 0; 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int mark = 0; 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a new string reader. 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param s String providing the character stream. 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public StringReader(String s) { 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.str = s; 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.length = s.length(); 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Check to make sure that the stream has not been closed */ 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void ensureOpen() throws IOException { 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (str == null) 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Stream closed"); 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads a single character. 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return The character read, or -1 if the end of the stream has been 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * reached 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException If an I/O error occurs 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read() throws IOException { 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (next >= length) 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return str.charAt(next++); 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads characters into a portion of an array. 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param cbuf Destination buffer 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param off Offset at which to start writing characters 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param len Maximum number of characters to read 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return The number of characters read, or -1 if the end of the 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream has been reached 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException If an I/O error occurs 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read(char cbuf[], int off, int len) throws IOException { 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((off < 0) || (off > cbuf.length) || (len < 0) || 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((off + len) > cbuf.length) || ((off + len) < 0)) { 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (len == 0) { 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (next >= length) 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = Math.min(length - next, len); 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski str.getChars(next, next + n, cbuf, off); 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski next += n; 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return n; 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Skips the specified number of characters in the stream. Returns 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the number of characters that were skipped. 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The <code>ns</code> parameter may be negative, even though the 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>skip</code> method of the {@link Reader} superclass throws 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * an exception in this case. Negative values of <code>ns</code> cause the 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream to skip backwards. Negative return values indicate a skip 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * backwards. It is not possible to skip backwards past the beginning of 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the string. 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If the entire string has been read or skipped, then this method has 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * no effect and always returns 0. 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException If an I/O error occurs 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long skip(long ns) throws IOException { 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (next >= length) 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Bound skip by beginning and end of the source 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long n = Math.min(length - next, ns); 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = Math.max(-next, n); 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski next += n; 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return n; 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Tells whether this stream is ready to be read. 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return True if the next read() is guaranteed not to block for input 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException If the stream is closed 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean ready() throws IOException { 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Tells whether this stream supports the mark() operation, which it does. 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean markSupported() { 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Marks the present position in the stream. Subsequent calls to reset() 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * will reposition the stream to this point. 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param readAheadLimit Limit on the number of characters that may be 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * read while still preserving the mark. Because 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the stream's input comes from a string, there 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is no actual limit, so this argument must not 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be negative, but is otherwise ignored. 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 16661cf642f86a0af82e88fb27f31e6842435326b5aPrzemyslaw Szczepaniak * @exception IllegalArgumentException If {@code readAheadLimit < 0} 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException If an I/O error occurs 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void mark(int readAheadLimit) throws IOException { 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (readAheadLimit < 0){ 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Read-ahead limit < 0"); 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mark = next; 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Resets the stream to the most recent mark, or to the beginning of the 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * string if it has never been marked. 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException If an I/O error occurs 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void reset() throws IOException { 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski next = mark; 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Closes the stream and releases any system resources associated with 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it. Once the stream has been closed, further read(), 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ready(), mark(), or reset() invocations will throw an IOException. 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Closing a previously closed stream has no effect. 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void close() { 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski str = null; 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 202