sclass BitHead > ByteHead { gettable int align; gettable int currentByte; replae SomethingIO with BitIO. *() {} *(InputStream inputStream) { super(inputStream); } *(OutputStream outputStream) { super(outputStream); } // slow version of write byte[] looping manually void write(byte[] data) { for (b : data) write(b); } void writeByte(int i) { if (align == 0) super.writeByte(i); else { currentByte |= i << align; super.writeByte(currentByte); currentByte = i >> (8-align); } } void writeBit(int i) { writeBit((i & 1) != 0); } void writeBit(bool b) { if (b) currentByte |= 1 << align; if (align == 7) { super.writeByte(currentByte); currentByte = align = 0; } else ++align; } bool byteAligned() { ret align == 0; } void completeByte aka flushBits aka finish(bool padWithOnes default false) { if (byteAligned()) ret; if (padWithOnes) currentByte |= 0xFF << align; super.writeByte(currentByte); currentByte = align = 0; } void writeTrailingBitCount aka trailingBitCount(bool padWithOnes default false) { int bitCount = modRange_incl(align(), 1, 8); completeByte(padWithOnes); writeByte(bitCount); } void exchange(SomethingIO writable) { if (writable != null) writable.readWrite(this); } }