@Override public String readUtf8Line(boolean throwOnEof) throws IOException { long start = 0; long newline; while ((newline = buffer.indexOf((byte) '\n', start)) == -1) { start = buffer.size; if (source.read(buffer, Segment.SIZE) == -1) { if (throwOnEof) throw new EOFException(); return buffer.size != 0 ? readUtf8((int) buffer.size) : null; } } if (newline > 0 && buffer.getByte(newline - 1) == '\r') { // Read everything until '\r\n', then skip the '\r\n'. String result = readUtf8((int) (newline - 1)); skip(2); return result; } else { // Read everything until '\n', then skip the '\n'. String result = readUtf8((int) (newline)); skip(1); return result; } }
@Override public long seek(byte b) throws IOException { long start = 0; long index; while ((index = buffer.indexOf(b, start)) == -1) { start = buffer.size; if (source.read(buffer, Segment.SIZE) == -1) throw new EOFException(); } return index; }
@Test public void indexOfWithOffset() throws Exception { OkBuffer buffer = new OkBuffer(); int halfSegment = Segment.SIZE / 2; buffer.writeUtf8(repeat('a', halfSegment)); buffer.writeUtf8(repeat('b', halfSegment)); buffer.writeUtf8(repeat('c', halfSegment)); buffer.writeUtf8(repeat('d', halfSegment)); assertEquals(0, buffer.indexOf((byte) 'a', 0)); assertEquals(halfSegment - 1, buffer.indexOf((byte) 'a', halfSegment - 1)); assertEquals(halfSegment, buffer.indexOf((byte) 'b', halfSegment - 1)); assertEquals(halfSegment * 2, buffer.indexOf((byte) 'c', halfSegment - 1)); assertEquals(halfSegment * 3, buffer.indexOf((byte) 'd', halfSegment - 1)); assertEquals(halfSegment * 3, buffer.indexOf((byte) 'd', halfSegment * 2)); assertEquals(halfSegment * 3, buffer.indexOf((byte) 'd', halfSegment * 3)); assertEquals(halfSegment * 4 - 1, buffer.indexOf((byte) 'd', halfSegment * 4 - 1)); }
@Test public void indexOf() throws Exception { OkBuffer buffer = new OkBuffer(); // The segment is empty. assertEquals(-1, buffer.indexOf((byte) 'a')); // The segment has one value. buffer.writeUtf8("a"); // a assertEquals(0, buffer.indexOf((byte) 'a')); assertEquals(-1, buffer.indexOf((byte) 'b')); // The segment has lots of data. buffer.writeUtf8(repeat('b', Segment.SIZE - 2)); // ab...b assertEquals(0, buffer.indexOf((byte) 'a')); assertEquals(1, buffer.indexOf((byte) 'b')); assertEquals(-1, buffer.indexOf((byte) 'c')); // The segment doesn't start at 0, it starts at 2. buffer.readUtf8(2); // b...b assertEquals(-1, buffer.indexOf((byte) 'a')); assertEquals(0, buffer.indexOf((byte) 'b')); assertEquals(-1, buffer.indexOf((byte) 'c')); // The segment is full. buffer.writeUtf8("c"); // b...bc assertEquals(-1, buffer.indexOf((byte) 'a')); assertEquals(0, buffer.indexOf((byte) 'b')); assertEquals(Segment.SIZE - 3, buffer.indexOf((byte) 'c')); // The segment doesn't start at 2, it starts at 4. buffer.readUtf8(2); // b...bc assertEquals(-1, buffer.indexOf((byte) 'a')); assertEquals(0, buffer.indexOf((byte) 'b')); assertEquals(Segment.SIZE - 5, buffer.indexOf((byte) 'c')); // Two segments. buffer.writeUtf8("d"); // b...bcd, d is in the 2nd segment. assertEquals(asList(Segment.SIZE - 4, 1), buffer.segmentSizes()); assertEquals(Segment.SIZE - 4, buffer.indexOf((byte) 'd')); assertEquals(-1, buffer.indexOf((byte) 'e')); }