@Override public long read(Buffer sink, long byteCount) throws IOException { if (!channel.isOpen()) throw new IllegalStateException("closed"); try (Buffer.UnsafeCursor ignored = sink.readAndWriteUnsafe(cursor)) { timeout.throwIfReached(); long oldSize = sink.size(); int length = (int) Math.min(8192, byteCount); cursor.expandBuffer(length); int read = channel.read(ByteBuffer.wrap(cursor.data, cursor.start, length)); if (read == -1) { cursor.resizeBuffer(oldSize); return -1; } else { cursor.resizeBuffer(oldSize + read); return read; } } }
@Test public void shrink() throws Exception { Buffer buffer = bufferFactory.newBuffer(); assumeTrue(buffer.size() > 3); long originalSize = buffer.size(); Buffer expected = new Buffer(); deepCopy(buffer).copyTo(expected, 0, originalSize - 3); try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) { assertEquals(originalSize, cursor.resizeBuffer(originalSize - 3)); } assertEquals(expected, buffer); }
@Test public void resizeEnlargeMovesCursorToOldSize() throws Exception { Buffer buffer = bufferFactory.newBuffer(); long originalSize = buffer.size(); Buffer expected = deepCopy(buffer); expected.writeUtf8("a"); try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) { cursor.seek(buffer.size() / 2); assertEquals(originalSize, buffer.size()); cursor.resizeBuffer(originalSize + 1); assertEquals(originalSize, cursor.offset); assertNotNull(cursor.data); assertNotEquals(-1, cursor.start); assertEquals(cursor.start + 1, cursor.end); cursor.data[cursor.start] = 'a'; } assertEquals(expected, buffer); }
@Test public void enlarge() throws Exception { Buffer buffer = bufferFactory.newBuffer(); long originalSize = buffer.size(); Buffer expected = deepCopy(buffer); expected.writeUtf8("abc"); try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) { assertEquals(originalSize, cursor.resizeBuffer(originalSize + 3)); cursor.seek(originalSize); cursor.data[cursor.start] = 'a'; cursor.seek(originalSize + 1); cursor.data[cursor.start] = 'b'; cursor.seek(originalSize + 2); cursor.data[cursor.start] = 'c'; } assertEquals(expected, buffer); }
@Test public void resizeShrinkMovesCursorToEnd() throws Exception { Buffer buffer = bufferFactory.newBuffer(); assumeTrue(buffer.size() > 0); long originalSize = buffer.size(); try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) { cursor.seek(buffer.size() / 2); assertEquals(originalSize, buffer.size()); cursor.resizeBuffer(originalSize - 1); assertEquals(originalSize - 1, cursor.offset); assertNull(cursor.data); assertEquals(-1, cursor.start); assertEquals(-1, cursor.end); } }
@Test public void expand() throws Exception { Buffer buffer = bufferFactory.newBuffer(); long originalSize = buffer.size(); Buffer expected = deepCopy(buffer); expected.writeUtf8("abcde"); try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) { cursor.expandBuffer(5); for (int i = 0; i < 5; i++) { cursor.data[cursor.start + i] = (byte) ('a' + i); } cursor.resizeBuffer(originalSize + 5); } assertEquals(expected, buffer); }
@Test public void resizeToSameSizeSeeksToEnd() throws Exception { Buffer buffer = bufferFactory.newBuffer(); long originalSize = buffer.size(); try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) { cursor.seek(buffer.size() / 2); assertEquals(originalSize, buffer.size()); cursor.resizeBuffer(originalSize); assertEquals(originalSize, buffer.size()); assertEquals(originalSize, cursor.offset); assertNull(cursor.data); assertEquals(-1, cursor.start); assertEquals(-1, cursor.end); } }
@Test public void shrinkAdjustOffset() throws Exception { Buffer buffer = bufferFactory.newBuffer(); assumeTrue(buffer.size() > 4); try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) { cursor.seek(buffer.size() - 1); cursor.resizeBuffer(3); assertEquals(3, cursor.offset); assertEquals(null, cursor.data); assertEquals(-1, cursor.start); assertEquals(-1, cursor.end); } }
@Test public void resizeAcquiredReadOnly() throws Exception { Buffer buffer = bufferFactory.newBuffer(); try (UnsafeCursor cursor = buffer.readUnsafe()) { cursor.resizeBuffer(10); fail(); } catch (IllegalStateException expected) { } }
@Test public void resizeNotAcquired() throws Exception { UnsafeCursor cursor = new UnsafeCursor(); try { cursor.resizeBuffer(10); fail(); } catch (IllegalStateException expected) { } }