@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; } }
@Test public void sourceFromInputStreamBounds() throws Exception { Source source = Okio.source(new ByteArrayInputStream(new byte[100])); try { source.read(new Buffer(), -1); fail(); } catch (IllegalArgumentException expected) { } }
@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; }
@Override public void skip(long byteCount) throws IOException { while (byteCount > 0) { if (buffer.size == 0 && source.read(buffer, Segment.SIZE) == -1) { throw new EOFException(); } long toSkip = Math.min(byteCount, buffer.size()); buffer.skip(toSkip); byteCount -= toSkip; } }
@Override public long read(OkBuffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (closed) throw new IllegalStateException("closed"); if (buffer.size == 0) { long read = source.read(buffer, Segment.SIZE); if (read == -1) return -1; } long toRead = Math.min(byteCount, buffer.size); return buffer.read(sink, toRead); }
@Test public void sourceFromInputStream() throws Exception { InputStream in = new ByteArrayInputStream(("a" + repeat('b', Segment.SIZE * 2) + "c").getBytes(UTF_8)); // Source: ab...bc Source source = Okio.source(in); Buffer sink = new Buffer(); // Source: b...bc. Sink: abb. assertEquals(3, source.read(sink, 3)); assertEquals("abb", sink.readUtf8(3)); // Source: b...bc. Sink: b...b. assertEquals(Segment.SIZE, source.read(sink, 20000)); assertEquals(repeat('b', Segment.SIZE), sink.readUtf8(sink.size())); // Source: b...bc. Sink: b...bc. assertEquals(Segment.SIZE - 1, source.read(sink, 20000)); assertEquals(repeat('b', Segment.SIZE - 2) + "c", sink.readUtf8(sink.size())); // Source and sink are empty. assertEquals(-1, source.read(sink, 1)); }
@Override public void require(long byteCount) throws IOException { while (buffer.size < byteCount) { if (source.read(buffer, Segment.SIZE) == -1) throw new EOFException(); } }
@Override public boolean exhausted() throws IOException { return buffer.exhausted() && source.read(buffer, Segment.SIZE) == -1; }