< prev index next >

src/java.base/share/classes/java/io/LineNumberReader.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 23,56 **** * questions. */ package java.io; - /** * A buffered character-input stream that keeps track of line numbers. This * class defines methods {@link #setLineNumber(int)} and {@link * #getLineNumber()} for setting and getting the current line number * respectively. * * <p> By default, line numbering begins at 0. This number increments at every ! * <a href="#lt">line terminator</a> as the data is read, and can be changed ! * with a call to {@code setLineNumber(int)}. Note however, that ! * {@code setLineNumber(int)} does not actually change the current position in ! * the stream; it only changes the value that will be returned by * {@code getLineNumber()}. * * <p> A line is considered to be <a id="lt">terminated</a> by any one of a * line feed ('\n'), a carriage return ('\r'), or a carriage return followed ! * immediately by a linefeed. * * @author Mark Reinhold * @since 1.1 */ public class LineNumberReader extends BufferedReader { /** The current line number */ private int lineNumber = 0; /** The line number of the mark, if any */ private int markedLineNumber; // Defaults to 0 --- 23,66 ---- * questions. */ package java.io; /** * A buffered character-input stream that keeps track of line numbers. This * class defines methods {@link #setLineNumber(int)} and {@link * #getLineNumber()} for setting and getting the current line number * respectively. * * <p> By default, line numbering begins at 0. This number increments at every ! * <a href="#lt">line terminator</a> as the data is read, and at the end of the ! * stream if the last character in the stream is not a line terminator. This ! * number can be changed with a call to {@code setLineNumber(int)}. Note ! * however, that {@code setLineNumber(int)} does not actually change the current ! * position in the stream; it only changes the value that will be returned by * {@code getLineNumber()}. * * <p> A line is considered to be <a id="lt">terminated</a> by any one of a * line feed ('\n'), a carriage return ('\r'), or a carriage return followed ! * immediately by a linefeed, or any of the previous terminators followed by ! * end of stream, or end of stream not preceded by another terminator. * * @author Mark Reinhold * @since 1.1 */ public class LineNumberReader extends BufferedReader { + /** Previous character types */ + private static final int NONE = 0; // no previous character + private static final int CHAR = 1; // non-line terminator + private static final int EOL = 2; // line terminator + private static final int EOF = 3; // end-of-file + + /** The previous character type */ + private int prevChar = NONE; + /** The current line number */ private int lineNumber = 0; /** The line number of the mark, if any */ private int markedLineNumber; // Defaults to 0
*** 109,120 **** return lineNumber; } /** * Read a single character. <a href="#lt">Line terminators</a> are ! * compressed into single newline ('\n') characters. Whenever a line ! * terminator is read the current line number is incremented. * * @return The character read, or -1 if the end of the stream has been * reached * * @throws IOException --- 119,132 ---- return lineNumber; } /** * Read a single character. <a href="#lt">Line terminators</a> are ! * compressed into single newline ('\n') characters. The current line ! * number is incremented whenever a line terminator is read, or when the ! * end of the stream is reached and the last character in the stream is ! * not a line terminator. * * @return The character read, or -1 if the end of the stream has been * reached * * @throws IOException
*** 132,151 **** switch (c) { case '\r': skipLF = true; case '\n': /* Fall through */ lineNumber++; return '\n'; } return c; } } /** ! * Read characters into a portion of an array. Whenever a <a ! * href="#lt">line terminator</a> is read the current line number is ! * incremented. * * @param cbuf * Destination buffer * * @param off --- 144,173 ---- switch (c) { case '\r': skipLF = true; case '\n': /* Fall through */ lineNumber++; + prevChar = EOL; return '\n'; + case -1: + if (prevChar == CHAR) + lineNumber++; + prevChar = EOF; + break; + default: + prevChar = CHAR; + break; } return c; } } /** ! * Read characters into a portion of an array. The current line ! * number is incremented whenever a line terminator is read, or when the ! * end of the stream is reached and the last character in the stream is ! * not a line terminator. * * @param cbuf * Destination buffer * * @param off
*** 165,174 **** --- 187,203 ---- @SuppressWarnings("fallthrough") public int read(char cbuf[], int off, int len) throws IOException { synchronized (lock) { int n = super.read(cbuf, off, len); + if (n == -1) { + if (prevChar == CHAR) + lineNumber++; + prevChar = EOF; + return -1; + } + for (int i = off; i < off + n; i++) { int c = cbuf[i]; if (skipLF) { skipLF = false; if (c == '\n')
*** 181,211 **** lineNumber++; break; } } return n; } } /** ! * Read a line of text. Whenever a <a href="#lt">line terminator</a> is ! * read the current line number is incremented. * * @return A String containing the contents of the line, not including * any <a href="#lt">line termination characters</a>, or * {@code null} if the end of the stream has been reached * * @throws IOException * If an I/O error occurs */ public String readLine() throws IOException { synchronized (lock) { ! String l = super.readLine(skipLF); skipLF = false; ! if (l != null) lineNumber++; return l; } } /** Maximum skip-buffer size */ --- 210,260 ---- lineNumber++; break; } } + if (n > 0) { + switch ((int)cbuf[off + n - 1]) { + case '\r': + case '\n': /* Fall through */ + prevChar = EOL; + break; + default: + prevChar = CHAR; + break; + } + } + return n; } } /** ! * Read a line of text. The current line number is incremented whenever ! * a line terminator is read, or when the end of the stream is reached and ! * the last character in the stream is not a line terminator. * * @return A String containing the contents of the line, not including * any <a href="#lt">line termination characters</a>, or * {@code null} if the end of the stream has been reached * * @throws IOException * If an I/O error occurs */ public String readLine() throws IOException { synchronized (lock) { ! boolean[] term = new boolean[1]; ! String l = super.readLine(skipLF, term); skipLF = false; ! if (l != null) { ! lineNumber++; ! prevChar = term[0] ? EOL : EOF; ! } else { // l == null ! if (prevChar == CHAR) lineNumber++; + prevChar = EOF; + } return l; } } /** Maximum skip-buffer size */
*** 240,249 **** --- 289,301 ---- int nc = read(skipBuffer, 0, (int) Math.min(r, nn)); if (nc == -1) break; r -= nc; } + if (n - r > 0) { + prevChar = NONE; + } return n - r; } } /**
< prev index next >