/* * Copyright (C) 2007 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.io; import com.google.common.base.Function; import com.google.common.collect.Lists; import java.io.BufferedReader; import java.io.FilterReader; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.nio.CharBuffer; import java.util.Arrays; import java.util.List; /** * Unit tests for {@link LineBuffer} and {@link LineReader}. * * @author Chris Nokleberg */ public class LineBufferTest extends IoTestCase { public void testProcess() throws IOException { bufferHelper(""); bufferHelper("\n", "\n"); bufferHelper("\r\n", "\r\n"); bufferHelper("\n\r", "\n", "\r"); bufferHelper("\r", "\r"); bufferHelper("\n\n", "\n", "\n"); bufferHelper("\r\n\r\n", "\r\n", "\r\n"); bufferHelper("\r\r", "\r", "\r"); bufferHelper("\ra\r\n\n\r\r", "\r", "a\r\n", "\n", "\r", "\r"); bufferHelper("no newlines at all", "no newlines at all"); bufferHelper("two lines\nbut no newline at end", "two lines\n", "but no newline at end"); bufferHelper("\nempty first line\nno newline at end", "\n", "empty first line\n", "no newline at end"); bufferHelper("three\rlines\rno newline at end", "three\r", "lines\r", "no newline at end"); bufferHelper("mixed\nline\rendings\r\n", "mixed\n", "line\r", "endings\r\n"); } private static final int[] CHUNK_SIZES = { 1, 2, 3, Integer.MAX_VALUE }; private static void bufferHelper(String input, String... expect) throws IOException { List expectProcess = Arrays.asList(expect); List expectRead = Lists.transform(expectProcess, new Function() { @Override public String apply(String value) { return value.replaceAll("[\\r\\n]", ""); } }); for (int chunk : CHUNK_SIZES) { chunk = Math.max(1, Math.min(chunk, input.length())); assertEquals(expectProcess, bufferHelper(input, chunk)); assertEquals(expectRead, readUsingJava(input, chunk)); assertEquals(expectRead, readUsingReader(input, chunk, true)); assertEquals(expectRead, readUsingReader(input, chunk, false)); } } private static List bufferHelper(String input, int chunk) throws IOException { final List lines = Lists.newArrayList(); LineBuffer lineBuf = new LineBuffer() { @Override protected void handleLine(String line, String end) { lines.add(line + end); } }; char[] chars = input.toCharArray(); int off = 0; while (off < chars.length) { int len = Math.min(chars.length, off + chunk) - off; lineBuf.add(chars, off, len); off += len; } lineBuf.finish(); return lines; } private static List readUsingJava(String input, int chunk) throws IOException { BufferedReader r = new BufferedReader(getChunkedReader(input, chunk)); List lines = Lists.newArrayList(); String line; while ((line = r.readLine()) != null) { lines.add(line); } r.close(); return lines; } private static List readUsingReader(String input, int chunk, boolean asReader) throws IOException { Readable readable = asReader ? getChunkedReader(input, chunk) : getChunkedReadable(input, chunk); LineReader r = new LineReader(readable); List lines = Lists.newArrayList(); String line; while ((line = r.readLine()) != null) { lines.add(line); } return lines; } // Returns a Readable that is *not* a Reader. private static Readable getChunkedReadable(String input, int chunk) { final Reader reader = getChunkedReader(input, chunk); return new Readable() { @Override public int read(CharBuffer cbuf) throws IOException { return reader.read(cbuf); } }; } private static Reader getChunkedReader(String input, final int chunk) { return new FilterReader(new StringReader(input)) { @Override public int read(char[] cbuf, int off, int len) throws IOException { return super.read(cbuf, off, Math.min(chunk, len)); } }; } }