OutputStreamBitChannel implements BitChannel, Closeable { public void write(boolean value) throws IOException { if (value) { buffer = (byte) (0xff & ((buffer << 1) | 0x01)); } else { buffer = (byte) (0xff & (buffer << 1)); } if (++bitPos == 8) { bitPos = 0; out.write(buffer); buffer = 0; } } OutputStreamBitChannel(@Nonnull OutputStream out); void write(boolean value); void write(@Nonnegative int nrbits, byte value); void write(@Nonnegative int nrbits, int value, ByteOrder byteOrder); void write(@Nonnegative int nrbits, long value, ByteOrder byteOrder); void write(@Nonnegative int nrbits, short value, ByteOrder byteOrder); void write(@Nonnull byte[] src, int offset, int length); long write(@Nonnull ByteBuffer buffer); @Nonnegative int getRelativeBitPos(); void close();  }
@Test public void shouldAcceptBooleans() throws IOException { OutputStreamBitChannel channel = new OutputStreamBitChannel(out); channel.write(true); channel.write(true); channel.write(true); channel.write(true); channel.write(false); channel.write(false); channel.write(false); channel.write(false); channel.write(false); verify(out).write((byte) 0xf0); verifyNoMoreInteractions(out); }
@Test public void shouldAcceptFullBytes() throws IOException { OutputStreamBitChannel channel = new OutputStreamBitChannel(out); channel.write(8, (byte) 32); verify(out).write((byte) 32); verifyNoMoreInteractions(out); }
@Test public void shouldAcceptPartialBytes() throws IOException { OutputStreamBitChannel channel = new OutputStreamBitChannel(out); channel.write(4, (byte) 0xff); channel.write(4, (byte) 0x00); verify(out).write((byte) 0xf0); verifyNoMoreInteractions(out); }
@Test public void shouldDealWithNonAlignedBytes() throws IOException { OutputStreamBitChannel channel = new OutputStreamBitChannel(out); channel.write(3, (byte) 0xff); channel.write(7, (byte) 0x00); verify(out).write((byte) Integer.parseInt("11100000", 2)); verifyNoMoreInteractions(out); }
@Test public void shouldDealWithNonAlignedMultipleBytes() throws IOException { OutputStreamBitChannel channel = new OutputStreamBitChannel(out); channel.write(3, (byte) 0xff); channel.write(7, (byte) 0x00); channel.write(8, (byte) 0xff); channel.write(6, (byte) 0x00); verify(out).write((byte) Integer.parseInt("11100000", 2)); verify(out).write((byte) Integer.parseInt("00111111", 2)); verify(out).write((byte) Integer.parseInt("11000000", 2)); verifyNoMoreInteractions(out); }
@Test public void shouldAcceptInts() throws IOException { OutputStreamBitChannel channel = new OutputStreamBitChannel(out); channel.write(12, (int) 0xfff, ByteOrder.BigEndian); channel.write(4, (int) 0x0, ByteOrder.BigEndian); verify(out).write((byte) Integer.parseInt("11111111", 2)); verify(out).write((byte) Integer.parseInt("11110000", 2)); verifyNoMoreInteractions(out); }
@Test public void shouldAcceptIntsAndBytes() throws IOException { OutputStreamBitChannel channel = new OutputStreamBitChannel(out); channel.write(12, (int) 0xfff, ByteOrder.BigEndian); channel.write(5, (byte) 0x0); verify(out).write((byte) Integer.parseInt("11111111", 2)); verify(out).write((byte) Integer.parseInt("11110000", 2)); verifyNoMoreInteractions(out); }
@Test public void shouldAcceptLittleEndian() throws IOException { OutputStreamBitChannel channel = new OutputStreamBitChannel(out); channel.write(12, (int) 0xf00, ByteOrder.LittleEndian); channel.write(4, (int) 0x0, ByteOrder.LittleEndian); verify(out).write((byte) Integer.parseInt("00000000", 2)); verify(out).write((byte) Integer.parseInt("11110000", 2)); verifyNoMoreInteractions(out); }
@Test public void shouldAcceptLongs() throws IOException { OutputStreamBitChannel channel = new OutputStreamBitChannel(out); channel.write(12, Long.MAX_VALUE / 2, ByteOrder.BigEndian); channel.write(5, (byte) 0x0); verify(out).write((byte) Integer.parseInt("11111111", 2)); verify(out).write((byte) Integer.parseInt("11110000", 2)); verifyNoMoreInteractions(out); }