CircularBuffer { public void readChunk(final OutputStream outputStream, final int chunkSize) throws IOException { if (chunkSize > availableReadLength){ throw new IllegalArgumentException("The chunk size must be smaller or equal to the amount of available data in the buffer." + " Available data: " + availableReadLength + ", Requested chunk size: " + chunkSize); } if (chunkSize <= 0 ){ return; } if (startValidDataIndex + chunkSize > buffer.length){ int firstChunkLength = buffer.length - startValidDataIndex; outputStream.write(buffer, startValidDataIndex, firstChunkLength); outputStream.write(buffer, 0, chunkSize - firstChunkLength); }else{ outputStream.write(buffer, startValidDataIndex, chunkSize); } startValidDataIndex = forwards(startValidDataIndex, chunkSize); outputStream.flush(); updateAvailableReadLength(false); } CircularBuffer(final int size); void write(final byte data); void readAll(final OutputStream outputStream); void readChunk(final OutputStream outputStream, final int chunkSize); boolean isFull(); boolean isEmpty(); int getAvailableDataLength(); int getBufferSize(); void reset();  }
@Test public void testReadChunk() throws Exception { ByteArrayOutputStream readBaos = new ByteArrayOutputStream(); byte[] readBytes; final CircularBuffer buffer = new CircularBuffer(10); log.info("Buffer initial status:\n" + circularBufferToString(buffer) + "\n"); buffer.readChunk(readBaos, 0); readBytes = readBaos.toByteArray(); log.info("Buffer after reading a chunk of 0 bytes:\n" + circularBufferToString(buffer)); log.info("Read bytes: " + TestUtils.printBytesHexEncoded(readBytes) + "\n"); assertArrayEquals(new byte[]{}, readBytes); assertEquals(0, buffer.startValidDataIndex); assertEquals(0, buffer.nextAvailablePosition); assertEquals(0, buffer.availableReadLength); readBaos.reset(); writeDataToCircularBuffer(buffer, new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); log.info("Buffer after writing 7 byte:\n" + circularBufferToString(buffer) + "\n"); buffer.readChunk(readBaos, 0); readBytes = readBaos.toByteArray(); log.info("Buffer after reading a chunk of 0 bytes:\n" + circularBufferToString(buffer)); log.info("Read bytes: " + TestUtils.printBytesHexEncoded(readBytes) + "\n"); assertArrayEquals(new byte[]{}, readBytes); assertEquals(0, buffer.startValidDataIndex); assertEquals(7, buffer.nextAvailablePosition); assertEquals(7, buffer.availableReadLength); readBaos.reset(); buffer.readChunk(readBaos, 3); readBytes = readBaos.toByteArray(); log.info("Buffer after reading a chunk of 3 bytes:\n" + circularBufferToString(buffer)); log.info("Read bytes: " + TestUtils.printBytesHexEncoded(readBytes) + "\n"); assertArrayEquals(new byte[]{0x01, 0x02, 0x03}, readBytes); assertEquals(3, buffer.startValidDataIndex); assertEquals(7, buffer.nextAvailablePosition); assertEquals(4, buffer.availableReadLength); readBaos.reset(); buffer.readChunk(readBaos, 4); readBytes = readBaos.toByteArray(); log.info("Buffer after reading a chunk of 4 bytes:\n" + circularBufferToString(buffer)); log.info("Read bytes: " + TestUtils.printBytesHexEncoded(readBytes) + "\n"); assertArrayEquals(new byte[]{0x04, 0x05, 0x06, 0x07}, readBytes); assertEquals(7, buffer.startValidDataIndex); assertEquals(7, buffer.nextAvailablePosition); assertEquals(0, buffer.availableReadLength); }
@Test public void testReadChunk_chunkTooBig() throws Exception { ByteArrayOutputStream readBaos = new ByteArrayOutputStream(); final CircularBuffer buffer = new CircularBuffer(10); writeDataToCircularBuffer(buffer, new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); Exception expected = null; try{ buffer.readChunk(readBaos, 8); }catch (Exception e){ expected = e; } assertNotNull(expected); assertTrue(expected instanceof IllegalArgumentException); }