151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1996, 2011, 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 reader that allows characters to be pushed back into the
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream.
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author      Mark Reinhold
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since       JDK1.1
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class PushbackReader extends FilterReader {
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /** Pushback buffer */
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private char[] buf;
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /** Current position in buffer */
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int pos;
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates a new pushback reader with a pushback buffer of the given size.
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   in   The reader from which characters will be read
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   size The size of the pushback buffer
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IllegalArgumentException if size is <= 0
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public PushbackReader(Reader in, int size) {
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super(in);
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (size <= 0) {
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("size <= 0");
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.buf = new char[size];
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.pos = size;
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates a new pushback reader with a one-character pushback buffer.
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   in  The reader from which characters will be read
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public PushbackReader(Reader in) {
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(in, 1);
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /** Checks to make sure that the stream has not been closed. */
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void ensureOpen() throws IOException {
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (buf == null)
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IOException("Stream closed");
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads a single character.
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return     The character read, or -1 if the end of the stream has been
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             reached
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int read() throws IOException {
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (pos < buf.length)
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return buf[pos++];
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            else
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return super.read();
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads characters into a portion of an array.
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      cbuf  Destination buffer
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      off   Offset at which to start writing characters
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      len   Maximum number of characters to read
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return     The number of characters read, or -1 if the end of the
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             stream has been reached
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int read(char cbuf[], int off, int len) throws IOException {
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (len <= 0) {
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (len < 0) {
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new IndexOutOfBoundsException();
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else if ((off < 0) || (off > cbuf.length)) {
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new IndexOutOfBoundsException();
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return 0;
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int avail = buf.length - pos;
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (avail > 0) {
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (len < avail)
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        avail = len;
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    System.arraycopy(buf, pos, cbuf, off, avail);
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    pos += avail;
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    off += avail;
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    len -= avail;
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (len > 0) {
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    len = super.read(cbuf, off, len);
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (len == -1) {
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (avail == 0) ? -1 : avail;
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return avail + len;
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return avail;
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (ArrayIndexOutOfBoundsException e) {
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new IndexOutOfBoundsException();
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Pushes back a single character by copying it to the front of the
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * pushback buffer. After this method returns, the next character to be read
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * will have the value <code>(char)c</code>.
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  c  The int value representing a character to be pushed back
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If the pushback buffer is full,
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          or if some other I/O error occurs
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void unread(int c) throws IOException {
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (pos == 0)
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new IOException("Pushback buffer overflow");
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            buf[--pos] = (char) c;
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Pushes back a portion of an array of characters by copying it to the
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * front of the pushback buffer.  After this method returns, the next
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * character to be read will have the value <code>cbuf[off]</code>, the
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * character after that will have the value <code>cbuf[off+1]</code>, and
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * so forth.
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  cbuf  Character array
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  off   Offset of first character to push back
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  len   Number of characters to push back
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If there is insufficient room in the pushback
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          buffer, or if some other I/O error occurs
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void unread(char cbuf[], int off, int len) throws IOException {
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (len > pos)
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new IOException("Pushback buffer overflow");
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            pos -= len;
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            System.arraycopy(cbuf, off, buf, pos, len);
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Pushes back an array of characters by copying it to the front of the
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * pushback buffer.  After this method returns, the next character to be
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * read will have the value <code>cbuf[0]</code>, the character after that
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * will have the value <code>cbuf[1]</code>, and so forth.
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  cbuf  Character array to push back
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If there is insufficient room in the pushback
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          buffer, or if some other I/O error occurs
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void unread(char cbuf[]) throws IOException {
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        unread(cbuf, 0, cbuf.length);
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Tells whether this stream is ready to be read.
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean ready() throws IOException {
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return (pos < buf.length) || super.ready();
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Marks the present position in the stream. The <code>mark</code>
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for class <code>PushbackReader</code> always throws an exception.
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  Always, since mark is not supported
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void mark(int readAheadLimit) throws IOException {
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throw new IOException("mark/reset not supported");
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Resets the stream. The <code>reset</code> method of
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>PushbackReader</code> always throws an exception.
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  Always, since reset is not supported
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void reset() throws IOException {
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throw new IOException("mark/reset not supported");
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Tells whether this stream supports the mark() operation, which it does
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * not.
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean markSupported() {
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return false;
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Closes the stream and releases any system resources associated with
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * it. Once the stream has been closed, further read(),
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * unread(), ready(), or skip() invocations will throw an IOException.
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Closing a previously closed stream has no effect.
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void close() throws IOException {
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super.close();
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        buf = null;
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Skips characters.  This method will block until some characters are
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * available, an I/O error occurs, or the end of the stream is reached.
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  n  The number of characters to skip
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return    The number of characters actually skipped
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IllegalArgumentException  If <code>n</code> is negative.
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public long skip(long n) throws IOException {
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (n < 0L)
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("skip value is negative");
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int avail = buf.length - pos;
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (avail > 0) {
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (n <= avail) {
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    pos += n;
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return n;
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    pos = buf.length;
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    n -= avail;
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return avail + super.skip(n);
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
282