/* Copyright (C) 1998, 1999 Cygnus Solutions This file is part of libgcj. This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ package java.io; /** * @author Warren Levy * @date October 16, 1998. */ /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 * "The Java Language Specification", ISBN 0-201-63451-1 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com. * Status: Believed complete and correct. */ public class PushbackReader extends FilterReader { /* Internal buffer array for data. */ private char[] buf; /* The current position in the buffer. */ private int pos; public PushbackReader(Reader in) { this(in, 1); } public PushbackReader(Reader in, int size) { super(in); if (size < 0) throw new IllegalArgumentException(); buf = new char[size]; pos = buf.length; } public void close() throws IOException { synchronized (lock) { buf = null; super.close(); } } public boolean markSupported() { return false; } public int read() throws IOException { synchronized (lock) { if (buf == null) throw new IOException(); if (pos < buf.length) return ((int) buf[pos++]) & 0xFFFF; return super.read(); } } public int read(char[] b, int off, int len) throws IOException { synchronized (lock) { if (buf == null) throw new IOException(); if (off < 0 || len < 0 || off + len > b.length) throw new ArrayIndexOutOfBoundsException(); int numBytes = Math.min(buf.length - pos, len); for (int i = 0; i < numBytes; i++) b[off++] = buf[pos++]; return numBytes + super.read(b, off, len - numBytes); } } public boolean ready() throws IOException { synchronized (lock) { if (buf == null) throw new IOException(); if (buf.length - pos > 0) return true; return super.ready(); } } public void unread(int b) throws IOException { synchronized (lock) { if (buf == null || pos <= 0) throw new IOException(); buf[--pos] = (char) b; } } public void unread(char[] b) throws IOException { unread(b, 0, b.length); } public void unread(char[] b, int off, int len) throws IOException { synchronized (lock) { if (buf == null || pos < len) throw new IOException(); // Note the order that these chars are being added is the opposite // of what would be done if they were added to the buffer one at a time. // See the Java Class Libraries book p. 1397. System.arraycopy(b, off, buf, pos - len, len); // Don't put this into the arraycopy above, an exception might be thrown // and in that case we don't want to modify pos. pos -= len; } } }