package uk.co.mmscomputing.io; import java.io.*; public class BitOutputStream extends FilterOutputStream{ private int buf=0; private int off=0; protected int count=0; public BitOutputStream(){ this(new ByteArrayOutputStream()); } public BitOutputStream(OutputStream out){ super(out); buf=0;off=0;count=0; } protected void cbLength(int len)throws IOException{ // callback for subclasses } public void write(int bit)throws IOException{ bit&=0x00000001; write(bit,1); } public void write(int code, int bitCount)throws IOException{ bitCount+=off; code<<=off; // shift to right place buf|=code; while(bitCount>=8) { super.write(buf&0x000000FF); buf>>=8; bitCount-=8; cbLength(++count); } off=bitCount&0x00000007; // update offset } public void pad()throws IOException{ if(off>0){ write(0,8); // padding, flush } buf=0;off=0;count=0; } public void flush()throws IOException{ pad(); super.flush(); } public void close()throws IOException{ this.flush(); super.close(); } public byte[] toByteArray()throws IOException{ if(out instanceof ByteArrayOutputStream){ super.flush(); return ((ByteArrayOutputStream)out).toByteArray(); }else{ throw new IOException("mmsc - BitOutputStream cannot convert underlying output stream to array of bytes !"); } } public void reset()throws IOException{ count=0; if(out instanceof ByteArrayOutputStream){ ((ByteArrayOutputStream)out).reset(); }else{ throw new IOException("mmsc - BitOutputStream cannot reset underlying output stream !"); } } }