11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.io; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Function; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Lists; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.BufferedReader; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.FilterReader; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Reader; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.StringReader; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.nio.CharBuffer; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Arrays; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unit tests for {@link LineBuffer} and {@link LineReader}. 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Chris Nokleberg 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class LineBufferTest extends IoTestCase { 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testProcess() throws IOException { 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper(""); 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("\n", "\n"); 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("\r\n", "\r\n"); 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("\n\r", "\n", "\r"); 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("\r", "\r"); 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("\n\n", "\n", "\n"); 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("\r\n\r\n", "\r\n", "\r\n"); 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("\r\r", "\r", "\r"); 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("\ra\r\n\n\r\r", "\r", "a\r\n", "\n", "\r", "\r"); 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("no newlines at all", "no newlines at all"); 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("two lines\nbut no newline at end", 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert "two lines\n", "but no newline at end"); 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("\nempty first line\nno newline at end", 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert "\n", "empty first line\n", "no newline at end"); 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("three\rlines\rno newline at end", 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert "three\r", "lines\r", "no newline at end"); 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bufferHelper("mixed\nline\rendings\r\n", 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert "mixed\n", "line\r", "endings\r\n"); 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final int[] CHUNK_SIZES = { 1, 2, 3, Integer.MAX_VALUE }; 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static void bufferHelper(String input, String... expect) 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws IOException { 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<String> expectProcess = Arrays.asList(expect); 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<String> expectRead = Lists.transform(expectProcess, 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Function<String, String>() { 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public String apply(String value) { 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return value.replaceAll("[\\r\\n]", ""); 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int chunk : CHUNK_SIZES) { 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert chunk = Math.max(1, Math.min(chunk, input.length())); 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(expectProcess, bufferHelper(input, chunk)); 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(expectRead, readUsingJava(input, chunk)); 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(expectRead, readUsingReader(input, chunk, true)); 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(expectRead, readUsingReader(input, chunk, false)); 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static List<String> bufferHelper(String input, int chunk) 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws IOException { 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final List<String> lines = Lists.newArrayList(); 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LineBuffer lineBuf = new LineBuffer() { 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected void handleLine(String line, String end) { 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lines.add(line + end); 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert char[] chars = input.toCharArray(); 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int off = 0; 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (off < chars.length) { 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int len = Math.min(chars.length, off + chunk) - off; 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lineBuf.add(chars, off, len); 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert off += len; 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lineBuf.finish(); 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return lines; 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static List<String> readUsingJava(String input, int chunk) 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws IOException { 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BufferedReader r = new BufferedReader(getChunkedReader(input, chunk)); 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<String> lines = Lists.newArrayList(); 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert String line; 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while ((line = r.readLine()) != null) { 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lines.add(line); 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert r.close(); 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return lines; 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static List<String> readUsingReader(String input, int chunk, 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean asReader) throws IOException { 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Readable readable = asReader 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? getChunkedReader(input, chunk) 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : getChunkedReadable(input, chunk); 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LineReader r = new LineReader(readable); 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<String> lines = Lists.newArrayList(); 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert String line; 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while ((line = r.readLine()) != null) { 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lines.add(line); 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return lines; 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Returns a Readable that is *not* a Reader. 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static Readable getChunkedReadable(String input, int chunk) { 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Reader reader = getChunkedReader(input, chunk); 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Readable() { 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int read(CharBuffer cbuf) throws IOException { 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return reader.read(cbuf); 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static Reader getChunkedReader(String input, final int chunk) { 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new FilterReader(new StringReader(input)) { 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int read(char[] cbuf, int off, int len) 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws IOException { 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.read(cbuf, off, Math.min(chunk, len)); 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 147