// package net.sf.zipme; /** * This class is general purpose class for writing data to a buffer. * It allows you to write bits as well as bytes * Based on DeflaterPending.java * @author Jochen Hoenicke * @date Jan 5, 2000 */ class PendingBuffer { protected byte[] buf; int start; int end; int bits; int bitCount; public PendingBuffer(){ this(4096); } public PendingBuffer( int bufsize){ buf=new byte[bufsize]; } public final void reset(){ start=end=bitCount=0; } public final void writeByte( int b){ if (DeflaterConstants.DEBUGGING && start != 0) throw new IllegalStateException(); buf[end++]=(byte)b; } public final void writeShort( int s){ if (DeflaterConstants.DEBUGGING && start != 0) throw new IllegalStateException(); buf[end++]=(byte)s; buf[end++]=(byte)(s >> 8); } public final void writeInt( int s){ if (DeflaterConstants.DEBUGGING && start != 0) throw new IllegalStateException(); buf[end++]=(byte)s; buf[end++]=(byte)(s >> 8); buf[end++]=(byte)(s >> 16); buf[end++]=(byte)(s >> 24); } public final void writeBlock( byte[] block, int offset, int len){ if (DeflaterConstants.DEBUGGING && start != 0) throw new IllegalStateException(); System.arraycopy(block,offset,buf,end,len); end+=len; } public final int getBitCount(){ return bitCount; } public final void alignToByte(){ if (DeflaterConstants.DEBUGGING && start != 0) throw new IllegalStateException(); if (bitCount > 0) { buf[end++]=(byte)bits; if (bitCount > 8) buf[end++]=(byte)(bits >>> 8); } bits=0; bitCount=0; } public final void writeBits( int b, int count){ if (DeflaterConstants.DEBUGGING && start != 0) throw new IllegalStateException(); if (DeflaterConstants.DEBUGGING) System.err.println("writeBits(" + Integer.toHexString(b) + ","+ count+ ")"); bits|=b << bitCount; bitCount+=count; if (bitCount >= 16) { buf[end++]=(byte)bits; buf[end++]=(byte)(bits >>> 8); bits>>>=16; bitCount-=16; } } public final void writeShortMSB( int s){ if (DeflaterConstants.DEBUGGING && start != 0) throw new IllegalStateException(); buf[end++]=(byte)(s >> 8); buf[end++]=(byte)s; } public final boolean isFlushed(){ return end == 0; } /** * Flushes the pending buffer into the given output array. If the * output array is to small, only a partial flush is done. * @param output the output array; * @param offset the offset into output array; * @param length the maximum number of bytes to store; * @exception IndexOutOfBoundsException if offset or length are * invalid. */ public final int flush( byte[] output, int offset, int length){ if (bitCount >= 8) { buf[end++]=(byte)bits; bits>>>=8; bitCount-=8; } if (length > end - start) { length=end - start; System.arraycopy(buf,start,output,offset,length); start=0; end=0; } else { System.arraycopy(buf,start,output,offset,length); start+=length; } return length; } /** * Flushes the pending buffer and returns that data in a new array * @return the output stream */ public final byte[] toByteArray(){ byte[] ret=new byte[end - start]; System.arraycopy(buf,start,ret,0,ret.length); start=0; end=0; return ret; } }