| /* java.util.zip.PendingBuffer |
| Copyright (C) 2001 Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| package java.util.zip; |
| |
| /** |
| * 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; |
| } |
| |
| |
| } |
| |