emul/compact/src/main/java/java/io/BufferedReader.java
changeset 772 d382dacfd73f
parent 771 4252bfc396fc
child 773 406faa8bc64f
     1.1 --- a/emul/compact/src/main/java/java/io/BufferedReader.java	Tue Feb 26 14:55:55 2013 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,523 +0,0 @@
     1.4 -/*
     1.5 - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 - *
     1.8 - * This code is free software; you can redistribute it and/or modify it
     1.9 - * under the terms of the GNU General Public License version 2 only, as
    1.10 - * published by the Free Software Foundation.  Oracle designates this
    1.11 - * particular file as subject to the "Classpath" exception as provided
    1.12 - * by Oracle in the LICENSE file that accompanied this code.
    1.13 - *
    1.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 - * version 2 for more details (a copy is included in the LICENSE file that
    1.18 - * accompanied this code).
    1.19 - *
    1.20 - * You should have received a copy of the GNU General Public License version
    1.21 - * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 - *
    1.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 - * or visit www.oracle.com if you need additional information or have any
    1.26 - * questions.
    1.27 - */
    1.28 -
    1.29 -package java.io;
    1.30 -
    1.31 -
    1.32 -
    1.33 -/**
    1.34 - * Reads text from a character-input stream, buffering characters so as to
    1.35 - * provide for the efficient reading of characters, arrays, and lines.
    1.36 - *
    1.37 - * <p> The buffer size may be specified, or the default size may be used.  The
    1.38 - * default is large enough for most purposes.
    1.39 - *
    1.40 - * <p> In general, each read request made of a Reader causes a corresponding
    1.41 - * read request to be made of the underlying character or byte stream.  It is
    1.42 - * therefore advisable to wrap a BufferedReader around any Reader whose read()
    1.43 - * operations may be costly, such as FileReaders and InputStreamReaders.  For
    1.44 - * example,
    1.45 - *
    1.46 - * <pre>
    1.47 - * BufferedReader in
    1.48 - *   = new BufferedReader(new FileReader("foo.in"));
    1.49 - * </pre>
    1.50 - *
    1.51 - * will buffer the input from the specified file.  Without buffering, each
    1.52 - * invocation of read() or readLine() could cause bytes to be read from the
    1.53 - * file, converted into characters, and then returned, which can be very
    1.54 - * inefficient.
    1.55 - *
    1.56 - * <p> Programs that use DataInputStreams for textual input can be localized by
    1.57 - * replacing each DataInputStream with an appropriate BufferedReader.
    1.58 - *
    1.59 - * @see FileReader
    1.60 - * @see InputStreamReader
    1.61 - * @see java.nio.file.Files#newBufferedReader
    1.62 - *
    1.63 - * @author      Mark Reinhold
    1.64 - * @since       JDK1.1
    1.65 - */
    1.66 -
    1.67 -public class BufferedReader extends Reader {
    1.68 -
    1.69 -    private Reader in;
    1.70 -
    1.71 -    private char cb[];
    1.72 -    private int nChars, nextChar;
    1.73 -
    1.74 -    private static final int INVALIDATED = -2;
    1.75 -    private static final int UNMARKED = -1;
    1.76 -    private int markedChar = UNMARKED;
    1.77 -    private int readAheadLimit = 0; /* Valid only when markedChar > 0 */
    1.78 -
    1.79 -    /** If the next character is a line feed, skip it */
    1.80 -    private boolean skipLF = false;
    1.81 -
    1.82 -    /** The skipLF flag when the mark was set */
    1.83 -    private boolean markedSkipLF = false;
    1.84 -
    1.85 -    private static int defaultCharBufferSize = 8192;
    1.86 -    private static int defaultExpectedLineLength = 80;
    1.87 -
    1.88 -    /**
    1.89 -     * Creates a buffering character-input stream that uses an input buffer of
    1.90 -     * the specified size.
    1.91 -     *
    1.92 -     * @param  in   A Reader
    1.93 -     * @param  sz   Input-buffer size
    1.94 -     *
    1.95 -     * @exception  IllegalArgumentException  If sz is <= 0
    1.96 -     */
    1.97 -    public BufferedReader(Reader in, int sz) {
    1.98 -        super(in);
    1.99 -        if (sz <= 0)
   1.100 -            throw new IllegalArgumentException("Buffer size <= 0");
   1.101 -        this.in = in;
   1.102 -        cb = new char[sz];
   1.103 -        nextChar = nChars = 0;
   1.104 -    }
   1.105 -
   1.106 -    /**
   1.107 -     * Creates a buffering character-input stream that uses a default-sized
   1.108 -     * input buffer.
   1.109 -     *
   1.110 -     * @param  in   A Reader
   1.111 -     */
   1.112 -    public BufferedReader(Reader in) {
   1.113 -        this(in, defaultCharBufferSize);
   1.114 -    }
   1.115 -
   1.116 -    /** Checks to make sure that the stream has not been closed */
   1.117 -    private void ensureOpen() throws IOException {
   1.118 -        if (in == null)
   1.119 -            throw new IOException("Stream closed");
   1.120 -    }
   1.121 -
   1.122 -    /**
   1.123 -     * Fills the input buffer, taking the mark into account if it is valid.
   1.124 -     */
   1.125 -    private void fill() throws IOException {
   1.126 -        int dst;
   1.127 -        if (markedChar <= UNMARKED) {
   1.128 -            /* No mark */
   1.129 -            dst = 0;
   1.130 -        } else {
   1.131 -            /* Marked */
   1.132 -            int delta = nextChar - markedChar;
   1.133 -            if (delta >= readAheadLimit) {
   1.134 -                /* Gone past read-ahead limit: Invalidate mark */
   1.135 -                markedChar = INVALIDATED;
   1.136 -                readAheadLimit = 0;
   1.137 -                dst = 0;
   1.138 -            } else {
   1.139 -                if (readAheadLimit <= cb.length) {
   1.140 -                    /* Shuffle in the current buffer */
   1.141 -                    System.arraycopy(cb, markedChar, cb, 0, delta);
   1.142 -                    markedChar = 0;
   1.143 -                    dst = delta;
   1.144 -                } else {
   1.145 -                    /* Reallocate buffer to accommodate read-ahead limit */
   1.146 -                    char ncb[] = new char[readAheadLimit];
   1.147 -                    System.arraycopy(cb, markedChar, ncb, 0, delta);
   1.148 -                    cb = ncb;
   1.149 -                    markedChar = 0;
   1.150 -                    dst = delta;
   1.151 -                }
   1.152 -                nextChar = nChars = delta;
   1.153 -            }
   1.154 -        }
   1.155 -
   1.156 -        int n;
   1.157 -        do {
   1.158 -            n = in.read(cb, dst, cb.length - dst);
   1.159 -        } while (n == 0);
   1.160 -        if (n > 0) {
   1.161 -            nChars = dst + n;
   1.162 -            nextChar = dst;
   1.163 -        }
   1.164 -    }
   1.165 -
   1.166 -    /**
   1.167 -     * Reads a single character.
   1.168 -     *
   1.169 -     * @return The character read, as an integer in the range
   1.170 -     *         0 to 65535 (<tt>0x00-0xffff</tt>), or -1 if the
   1.171 -     *         end of the stream has been reached
   1.172 -     * @exception  IOException  If an I/O error occurs
   1.173 -     */
   1.174 -    public int read() throws IOException {
   1.175 -        synchronized (lock) {
   1.176 -            ensureOpen();
   1.177 -            for (;;) {
   1.178 -                if (nextChar >= nChars) {
   1.179 -                    fill();
   1.180 -                    if (nextChar >= nChars)
   1.181 -                        return -1;
   1.182 -                }
   1.183 -                if (skipLF) {
   1.184 -                    skipLF = false;
   1.185 -                    if (cb[nextChar] == '\n') {
   1.186 -                        nextChar++;
   1.187 -                        continue;
   1.188 -                    }
   1.189 -                }
   1.190 -                return cb[nextChar++];
   1.191 -            }
   1.192 -        }
   1.193 -    }
   1.194 -
   1.195 -    /**
   1.196 -     * Reads characters into a portion of an array, reading from the underlying
   1.197 -     * stream if necessary.
   1.198 -     */
   1.199 -    private int read1(char[] cbuf, int off, int len) throws IOException {
   1.200 -        if (nextChar >= nChars) {
   1.201 -            /* If the requested length is at least as large as the buffer, and
   1.202 -               if there is no mark/reset activity, and if line feeds are not
   1.203 -               being skipped, do not bother to copy the characters into the
   1.204 -               local buffer.  In this way buffered streams will cascade
   1.205 -               harmlessly. */
   1.206 -            if (len >= cb.length && markedChar <= UNMARKED && !skipLF) {
   1.207 -                return in.read(cbuf, off, len);
   1.208 -            }
   1.209 -            fill();
   1.210 -        }
   1.211 -        if (nextChar >= nChars) return -1;
   1.212 -        if (skipLF) {
   1.213 -            skipLF = false;
   1.214 -            if (cb[nextChar] == '\n') {
   1.215 -                nextChar++;
   1.216 -                if (nextChar >= nChars)
   1.217 -                    fill();
   1.218 -                if (nextChar >= nChars)
   1.219 -                    return -1;
   1.220 -            }
   1.221 -        }
   1.222 -        int n = Math.min(len, nChars - nextChar);
   1.223 -        System.arraycopy(cb, nextChar, cbuf, off, n);
   1.224 -        nextChar += n;
   1.225 -        return n;
   1.226 -    }
   1.227 -
   1.228 -    /**
   1.229 -     * Reads characters into a portion of an array.
   1.230 -     *
   1.231 -     * <p> This method implements the general contract of the corresponding
   1.232 -     * <code>{@link Reader#read(char[], int, int) read}</code> method of the
   1.233 -     * <code>{@link Reader}</code> class.  As an additional convenience, it
   1.234 -     * attempts to read as many characters as possible by repeatedly invoking
   1.235 -     * the <code>read</code> method of the underlying stream.  This iterated
   1.236 -     * <code>read</code> continues until one of the following conditions becomes
   1.237 -     * true: <ul>
   1.238 -     *
   1.239 -     *   <li> The specified number of characters have been read,
   1.240 -     *
   1.241 -     *   <li> The <code>read</code> method of the underlying stream returns
   1.242 -     *   <code>-1</code>, indicating end-of-file, or
   1.243 -     *
   1.244 -     *   <li> The <code>ready</code> method of the underlying stream
   1.245 -     *   returns <code>false</code>, indicating that further input requests
   1.246 -     *   would block.
   1.247 -     *
   1.248 -     * </ul> If the first <code>read</code> on the underlying stream returns
   1.249 -     * <code>-1</code> to indicate end-of-file then this method returns
   1.250 -     * <code>-1</code>.  Otherwise this method returns the number of characters
   1.251 -     * actually read.
   1.252 -     *
   1.253 -     * <p> Subclasses of this class are encouraged, but not required, to
   1.254 -     * attempt to read as many characters as possible in the same fashion.
   1.255 -     *
   1.256 -     * <p> Ordinarily this method takes characters from this stream's character
   1.257 -     * buffer, filling it from the underlying stream as necessary.  If,
   1.258 -     * however, the buffer is empty, the mark is not valid, and the requested
   1.259 -     * length is at least as large as the buffer, then this method will read
   1.260 -     * characters directly from the underlying stream into the given array.
   1.261 -     * Thus redundant <code>BufferedReader</code>s will not copy data
   1.262 -     * unnecessarily.
   1.263 -     *
   1.264 -     * @param      cbuf  Destination buffer
   1.265 -     * @param      off   Offset at which to start storing characters
   1.266 -     * @param      len   Maximum number of characters to read
   1.267 -     *
   1.268 -     * @return     The number of characters read, or -1 if the end of the
   1.269 -     *             stream has been reached
   1.270 -     *
   1.271 -     * @exception  IOException  If an I/O error occurs
   1.272 -     */
   1.273 -    public int read(char cbuf[], int off, int len) throws IOException {
   1.274 -        synchronized (lock) {
   1.275 -            ensureOpen();
   1.276 -            if ((off < 0) || (off > cbuf.length) || (len < 0) ||
   1.277 -                ((off + len) > cbuf.length) || ((off + len) < 0)) {
   1.278 -                throw new IndexOutOfBoundsException();
   1.279 -            } else if (len == 0) {
   1.280 -                return 0;
   1.281 -            }
   1.282 -
   1.283 -            int n = read1(cbuf, off, len);
   1.284 -            if (n <= 0) return n;
   1.285 -            while ((n < len) && in.ready()) {
   1.286 -                int n1 = read1(cbuf, off + n, len - n);
   1.287 -                if (n1 <= 0) break;
   1.288 -                n += n1;
   1.289 -            }
   1.290 -            return n;
   1.291 -        }
   1.292 -    }
   1.293 -
   1.294 -    /**
   1.295 -     * Reads a line of text.  A line is considered to be terminated by any one
   1.296 -     * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
   1.297 -     * followed immediately by a linefeed.
   1.298 -     *
   1.299 -     * @param      ignoreLF  If true, the next '\n' will be skipped
   1.300 -     *
   1.301 -     * @return     A String containing the contents of the line, not including
   1.302 -     *             any line-termination characters, or null if the end of the
   1.303 -     *             stream has been reached
   1.304 -     *
   1.305 -     * @see        java.io.LineNumberReader#readLine()
   1.306 -     *
   1.307 -     * @exception  IOException  If an I/O error occurs
   1.308 -     */
   1.309 -    String readLine(boolean ignoreLF) throws IOException {
   1.310 -        StringBuffer s = null;
   1.311 -        int startChar;
   1.312 -
   1.313 -        synchronized (lock) {
   1.314 -            ensureOpen();
   1.315 -            boolean omitLF = ignoreLF || skipLF;
   1.316 -
   1.317 -        bufferLoop:
   1.318 -            for (;;) {
   1.319 -
   1.320 -                if (nextChar >= nChars)
   1.321 -                    fill();
   1.322 -                if (nextChar >= nChars) { /* EOF */
   1.323 -                    if (s != null && s.length() > 0)
   1.324 -                        return s.toString();
   1.325 -                    else
   1.326 -                        return null;
   1.327 -                }
   1.328 -                boolean eol = false;
   1.329 -                char c = 0;
   1.330 -                int i;
   1.331 -
   1.332 -                /* Skip a leftover '\n', if necessary */
   1.333 -                if (omitLF && (cb[nextChar] == '\n'))
   1.334 -                    nextChar++;
   1.335 -                skipLF = false;
   1.336 -                omitLF = false;
   1.337 -
   1.338 -            charLoop:
   1.339 -                for (i = nextChar; i < nChars; i++) {
   1.340 -                    c = cb[i];
   1.341 -                    if ((c == '\n') || (c == '\r')) {
   1.342 -                        eol = true;
   1.343 -                        break charLoop;
   1.344 -                    }
   1.345 -                }
   1.346 -
   1.347 -                startChar = nextChar;
   1.348 -                nextChar = i;
   1.349 -
   1.350 -                if (eol) {
   1.351 -                    String str;
   1.352 -                    if (s == null) {
   1.353 -                        str = new String(cb, startChar, i - startChar);
   1.354 -                    } else {
   1.355 -                        s.append(cb, startChar, i - startChar);
   1.356 -                        str = s.toString();
   1.357 -                    }
   1.358 -                    nextChar++;
   1.359 -                    if (c == '\r') {
   1.360 -                        skipLF = true;
   1.361 -                    }
   1.362 -                    return str;
   1.363 -                }
   1.364 -
   1.365 -                if (s == null)
   1.366 -                    s = new StringBuffer(defaultExpectedLineLength);
   1.367 -                s.append(cb, startChar, i - startChar);
   1.368 -            }
   1.369 -        }
   1.370 -    }
   1.371 -
   1.372 -    /**
   1.373 -     * Reads a line of text.  A line is considered to be terminated by any one
   1.374 -     * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
   1.375 -     * followed immediately by a linefeed.
   1.376 -     *
   1.377 -     * @return     A String containing the contents of the line, not including
   1.378 -     *             any line-termination characters, or null if the end of the
   1.379 -     *             stream has been reached
   1.380 -     *
   1.381 -     * @exception  IOException  If an I/O error occurs
   1.382 -     *
   1.383 -     * @see java.nio.file.Files#readAllLines
   1.384 -     */
   1.385 -    public String readLine() throws IOException {
   1.386 -        return readLine(false);
   1.387 -    }
   1.388 -
   1.389 -    /**
   1.390 -     * Skips characters.
   1.391 -     *
   1.392 -     * @param  n  The number of characters to skip
   1.393 -     *
   1.394 -     * @return    The number of characters actually skipped
   1.395 -     *
   1.396 -     * @exception  IllegalArgumentException  If <code>n</code> is negative.
   1.397 -     * @exception  IOException  If an I/O error occurs
   1.398 -     */
   1.399 -    public long skip(long n) throws IOException {
   1.400 -        if (n < 0L) {
   1.401 -            throw new IllegalArgumentException("skip value is negative");
   1.402 -        }
   1.403 -        synchronized (lock) {
   1.404 -            ensureOpen();
   1.405 -            long r = n;
   1.406 -            while (r > 0) {
   1.407 -                if (nextChar >= nChars)
   1.408 -                    fill();
   1.409 -                if (nextChar >= nChars) /* EOF */
   1.410 -                    break;
   1.411 -                if (skipLF) {
   1.412 -                    skipLF = false;
   1.413 -                    if (cb[nextChar] == '\n') {
   1.414 -                        nextChar++;
   1.415 -                    }
   1.416 -                }
   1.417 -                long d = nChars - nextChar;
   1.418 -                if (r <= d) {
   1.419 -                    nextChar += r;
   1.420 -                    r = 0;
   1.421 -                    break;
   1.422 -                }
   1.423 -                else {
   1.424 -                    r -= d;
   1.425 -                    nextChar = nChars;
   1.426 -                }
   1.427 -            }
   1.428 -            return n - r;
   1.429 -        }
   1.430 -    }
   1.431 -
   1.432 -    /**
   1.433 -     * Tells whether this stream is ready to be read.  A buffered character
   1.434 -     * stream is ready if the buffer is not empty, or if the underlying
   1.435 -     * character stream is ready.
   1.436 -     *
   1.437 -     * @exception  IOException  If an I/O error occurs
   1.438 -     */
   1.439 -    public boolean ready() throws IOException {
   1.440 -        synchronized (lock) {
   1.441 -            ensureOpen();
   1.442 -
   1.443 -            /*
   1.444 -             * If newline needs to be skipped and the next char to be read
   1.445 -             * is a newline character, then just skip it right away.
   1.446 -             */
   1.447 -            if (skipLF) {
   1.448 -                /* Note that in.ready() will return true if and only if the next
   1.449 -                 * read on the stream will not block.
   1.450 -                 */
   1.451 -                if (nextChar >= nChars && in.ready()) {
   1.452 -                    fill();
   1.453 -                }
   1.454 -                if (nextChar < nChars) {
   1.455 -                    if (cb[nextChar] == '\n')
   1.456 -                        nextChar++;
   1.457 -                    skipLF = false;
   1.458 -                }
   1.459 -            }
   1.460 -            return (nextChar < nChars) || in.ready();
   1.461 -        }
   1.462 -    }
   1.463 -
   1.464 -    /**
   1.465 -     * Tells whether this stream supports the mark() operation, which it does.
   1.466 -     */
   1.467 -    public boolean markSupported() {
   1.468 -        return true;
   1.469 -    }
   1.470 -
   1.471 -    /**
   1.472 -     * Marks the present position in the stream.  Subsequent calls to reset()
   1.473 -     * will attempt to reposition the stream to this point.
   1.474 -     *
   1.475 -     * @param readAheadLimit   Limit on the number of characters that may be
   1.476 -     *                         read while still preserving the mark. An attempt
   1.477 -     *                         to reset the stream after reading characters
   1.478 -     *                         up to this limit or beyond may fail.
   1.479 -     *                         A limit value larger than the size of the input
   1.480 -     *                         buffer will cause a new buffer to be allocated
   1.481 -     *                         whose size is no smaller than limit.
   1.482 -     *                         Therefore large values should be used with care.
   1.483 -     *
   1.484 -     * @exception  IllegalArgumentException  If readAheadLimit is < 0
   1.485 -     * @exception  IOException  If an I/O error occurs
   1.486 -     */
   1.487 -    public void mark(int readAheadLimit) throws IOException {
   1.488 -        if (readAheadLimit < 0) {
   1.489 -            throw new IllegalArgumentException("Read-ahead limit < 0");
   1.490 -        }
   1.491 -        synchronized (lock) {
   1.492 -            ensureOpen();
   1.493 -            this.readAheadLimit = readAheadLimit;
   1.494 -            markedChar = nextChar;
   1.495 -            markedSkipLF = skipLF;
   1.496 -        }
   1.497 -    }
   1.498 -
   1.499 -    /**
   1.500 -     * Resets the stream to the most recent mark.
   1.501 -     *
   1.502 -     * @exception  IOException  If the stream has never been marked,
   1.503 -     *                          or if the mark has been invalidated
   1.504 -     */
   1.505 -    public void reset() throws IOException {
   1.506 -        synchronized (lock) {
   1.507 -            ensureOpen();
   1.508 -            if (markedChar < 0)
   1.509 -                throw new IOException((markedChar == INVALIDATED)
   1.510 -                                      ? "Mark invalid"
   1.511 -                                      : "Stream not marked");
   1.512 -            nextChar = markedChar;
   1.513 -            skipLF = markedSkipLF;
   1.514 -        }
   1.515 -    }
   1.516 -
   1.517 -    public void close() throws IOException {
   1.518 -        synchronized (lock) {
   1.519 -            if (in == null)
   1.520 -                return;
   1.521 -            in.close();
   1.522 -            in = null;
   1.523 -            cb = null;
   1.524 -        }
   1.525 -    }
   1.526 -}