Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / java / util / zip / StreamManipulator.java
blob57d15ae283bd503a5d76ae24504afa74df8b1f74
1 /* java.util.zip.StreamManipulator
2 Copyright (C) 2001 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package java.util.zip;
40 /**
41 * This class allows us to retrieve a specified amount of bits from
42 * the input buffer, as well as copy big byte blocks.
44 * It uses an int buffer to store up to 31 bits for direct
45 * manipulation. This guarantees that we can get at least 16 bits,
46 * but we only need at most 15, so this is all safe.
48 * There are some optimizations in this class, for example, you must
49 * never peek more then 8 bits more than needed, and you must first
50 * peek bits before you may drop them. This is not a general purpose
51 * class but optimized for the behaviour of the Inflater.
53 * @author John Leuner, Jochen Hoenicke
56 class StreamManipulator
58 private byte[] window;
59 private int window_start = 0;
60 private int window_end = 0;
62 private int buffer = 0;
63 private int bits_in_buffer = 0;
65 /**
66 * Get the next n bits but don't increase input pointer. n must be
67 * less or equal 16 and if you if this call succeeds, you must drop
68 * at least n-8 bits in the next call.
70 * @return the value of the bits, or -1 if not enough bits available. */
71 public final int peekBits(int n)
73 if (bits_in_buffer < n)
75 if (window_start == window_end)
76 return -1;
77 buffer |= (window[window_start++] & 0xff
78 | (window[window_start++] & 0xff) << 8) << bits_in_buffer;
79 bits_in_buffer += 16;
81 return buffer & ((1 << n) - 1);
84 /* Drops the next n bits from the input. You should have called peekBits
85 * with a bigger or equal n before, to make sure that enough bits are in
86 * the bit buffer.
88 public final void dropBits(int n)
90 buffer >>>= n;
91 bits_in_buffer -= n;
94 /**
95 * Gets the next n bits and increases input pointer. This is equivalent
96 * to peekBits followed by dropBits, except for correct error handling.
97 * @return the value of the bits, or -1 if not enough bits available.
99 public final int getBits(int n)
101 int bits = peekBits(n);
102 if (bits >= 0)
103 dropBits(n);
104 return bits;
107 * Gets the number of bits available in the bit buffer. This must be
108 * only called when a previous peekBits() returned -1.
109 * @return the number of bits available.
111 public final int getAvailableBits()
113 return bits_in_buffer;
117 * Gets the number of bytes available.
118 * @return the number of bytes available.
120 public final int getAvailableBytes()
122 return window_end - window_start + (bits_in_buffer >> 3);
126 * Skips to the next byte boundary.
128 public void skipToByteBoundary()
130 buffer >>= (bits_in_buffer & 7);
131 bits_in_buffer &= ~7;
134 public final boolean needsInput() {
135 return window_start == window_end;
139 /* Copies length bytes from input buffer to output buffer starting
140 * at output[offset]. You have to make sure, that the buffer is
141 * byte aligned. If not enough bytes are available, copies fewer
142 * bytes.
143 * @param length the length to copy, 0 is allowed.
144 * @return the number of bytes copied, 0 if no byte is available.
146 public int copyBytes(byte[] output, int offset, int length)
148 if (length < 0)
149 throw new IllegalArgumentException("length negative");
150 if ((bits_in_buffer & 7) != 0)
151 /* bits_in_buffer may only be 0 or 8 */
152 throw new IllegalStateException("Bit buffer is not aligned!");
154 int count = 0;
155 while (bits_in_buffer > 0 && length > 0)
157 output[offset++] = (byte) buffer;
158 buffer >>>= 8;
159 bits_in_buffer -= 8;
160 length--;
161 count++;
163 if (length == 0)
164 return count;
166 int avail = window_end - window_start;
167 if (length > avail)
168 length = avail;
169 System.arraycopy(window, window_start, output, offset, length);
170 window_start += length;
172 if (((window_start - window_end) & 1) != 0)
174 /* We always want an even number of bytes in input, see peekBits */
175 buffer = (window[window_start++] & 0xff);
176 bits_in_buffer = 8;
178 return count + length;
181 public StreamManipulator()
185 public void reset()
187 window_start = window_end = buffer = bits_in_buffer = 0;
190 public void setInput(byte[] buf, int off, int len)
192 if (window_start < window_end)
193 throw new IllegalStateException
194 ("Old input was not completely processed");
196 int end = off + len;
198 /* We want to throw an ArrayIndexOutOfBoundsException early. The
199 * check is very tricky: it also handles integer wrap around.
201 if (0 > off || off > end || end > buf.length)
202 throw new ArrayIndexOutOfBoundsException();
204 if ((len & 1) != 0)
206 /* We always want an even number of bytes in input, see peekBits */
207 buffer |= (buf[off++] & 0xff) << bits_in_buffer;
208 bits_in_buffer += 8;
211 window = buf;
212 window_start = off;
213 window_end = end;