LineReader { public byte[] readLine() throws IOException { if (readBuffer == null) return null; while (true) { while (readOffset >= readLength) { readLength = input.read(readBuffer); readOffset = 0; if (readLength == -1) { byte[] result; if (lineLength == -1) result = null; else if (lineLength == 0) result = BLANK_EOF; else result = takeCurrentLine(); readBuffer = null; lineBuffer = null; return result; } } while (readOffset < readLength) { byte b = readBuffer[readOffset]; readOffset++; if (lineLength != -1) { switch (b) { case '\r': prevWasCr = true; return takeCurrentLine(); case '\n': if (prevWasCr) { prevWasCr = false; break; } else return takeCurrentLine(); default: prevWasCr = false; if (lineLength == maxLineLength) { lineLength = -1; continue; } else { if (lineLength == lineBuffer.length) lineBuffer = Arrays.copyOf(lineBuffer, Math.min(lineBuffer.length * 2, maxLineLength)); lineBuffer[lineLength] = b; lineLength++; break; } } } else { switch (b) { case '\r': lineLength = 0; prevWasCr = true; break; case '\n': lineLength = 0; prevWasCr = false; break; default: prevWasCr = false; break; } } } } } LineReader(InputStream in);  LineReader(InputStream in, int maxLen); byte[] readLine(); static final byte[] BLANK_EOF; }
@Test public void testLongLines() { try { LineReader reader = new LineReader(new ByteArrayInputStream( Utils.toUtf8("a\r12345\r\nxyzabc\n \n7890123\nABCDEF")), 5); Assert.assertArrayEquals(Utils.toUtf8("a"), reader.readLine()); Assert.assertArrayEquals(Utils.toUtf8("12345"), reader.readLine()); Assert.assertArrayEquals(Utils.toUtf8(" "), reader.readLine()); Assert.assertNull(reader.readLine()); } catch (IOException e) {} }