Home | History | Annotate | Download | only in io
      1 /*
      2  * Copyright (C) 2007 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.io;
     18 
     19 import static com.google.common.base.Preconditions.checkNotNull;
     20 
     21 import com.google.common.annotations.Beta;
     22 
     23 import java.io.IOException;
     24 import java.io.Reader;
     25 import java.nio.CharBuffer;
     26 import java.util.LinkedList;
     27 import java.util.Queue;
     28 
     29 /**
     30  * A class for reading lines of text. Provides the same functionality
     31  * as {@link java.io.BufferedReader#readLine()} but for all {@link Readable}
     32  * objects, not just instances of {@link Reader}.
     33  *
     34  * @author Chris Nokleberg
     35  * @since 1.0
     36  */
     37 @Beta
     38 public final class LineReader {
     39   private final Readable readable;
     40   private final Reader reader;
     41   private final char[] buf = new char[0x1000]; // 4K
     42   private final CharBuffer cbuf = CharBuffer.wrap(buf);
     43 
     44   private final Queue<String> lines = new LinkedList<String>();
     45   private final LineBuffer lineBuf = new LineBuffer() {
     46     @Override protected void handleLine(String line, String end) {
     47       lines.add(line);
     48     }
     49   };
     50 
     51   /**
     52    * Creates a new instance that will read lines from the given
     53    * {@code Readable} object.
     54    */
     55   public LineReader(Readable readable) {
     56     this.readable = checkNotNull(readable);
     57     this.reader = (readable instanceof Reader) ? (Reader) readable : null;
     58   }
     59 
     60   /**
     61    * Reads a line of text. A line is considered to be terminated by any
     62    * one of a line feed ({@code '\n'}), a carriage return
     63    * ({@code '\r'}), or a carriage return followed immediately by a linefeed
     64    * ({@code "\r\n"}).
     65    *
     66    * @return a {@code String} containing the contents of the line, not
     67    *     including any line-termination characters, or {@code null} if the
     68    *     end of the stream has been reached.
     69    * @throws IOException if an I/O error occurs
     70    */
     71   public String readLine() throws IOException {
     72     while (lines.peek() == null) {
     73       cbuf.clear();
     74       // The default implementation of Reader#read(CharBuffer) allocates a
     75       // temporary char[], so we call Reader#read(char[], int, int) instead.
     76       int read = (reader != null)
     77           ? reader.read(buf, 0, buf.length)
     78           : readable.read(cbuf);
     79       if (read == -1) {
     80         lineBuf.finish();
     81         break;
     82       }
     83       lineBuf.add(buf, 0, read);
     84     }
     85     return lines.poll();
     86   }
     87 }
     88