You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tc...@apache.org on 2009/01/08 12:13:52 UTC
svn commit: r732685 - in
/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2:
BZip2CompressorInputStream.java BZip2CompressorOutputStream.java
BZip2Constants.java CRC.java
Author: tcurdt
Date: Thu Jan 8 03:13:50 2009
New Revision: 732685
URL: http://svn.apache.org/viewvc?rev=732685&view=rev
Log:
applied patch from Christian Grobmeier
updated bzip2 streams
https://issues.apache.org/jira/browse/SANDBOX-195
Modified:
commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java
commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java
commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2Constants.java
commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/CRC.java
Modified: commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java
URL: http://svn.apache.org/viewvc/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java?rev=732685&r1=732684&r2=732685&view=diff
==============================================================================
--- commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java (original)
+++ commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java Thu Jan 8 03:13:50 2009
@@ -16,6 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
+
+/*
+ * This package is based on the work done by Keiron Liddle, Aftex Software
+ * <ke...@aftexsw.com> to whom the Ant project is very grateful for his
+ * great code.
+ */
package org.apache.commons.compress.compressors.bzip2;
import java.io.IOException;
@@ -28,90 +34,57 @@
* header chars) to be read as any other stream.
*/
public class BZip2CompressorInputStream extends CompressorInputStream implements BZip2Constants {
+ private static void reportCRCError() throws IOException {
+ // The clean way would be to throw an exception.
+ //throw new IOException("crc error");
- private static void cadvise() {
- System.out.println("CRC Error");
- //throw new CCoruptionError();
+ // Just print a message, like the previous versions of this class did
+ System.err.println("BZip2 CRC error");
}
- /*
- private static void badBGLengths() {
- cadvise();
- }
+ private void makeMaps() {
+ final boolean[] inUse = this.data.inUse;
+ final byte[] seqToUnseq = this.data.seqToUnseq;
- private static void bitStreamEOF() {
- cadvise();
- }
- */
+ int nInUseShadow = 0;
- private static void compressedStreamEOF() {
- cadvise();
- }
-
- private void makeMaps() {
- int i;
- nInUse = 0;
- for (i = 0; i < 256; i++) {
- if (inUse[i]) {
- seqToUnseq[nInUse] = (char) i;
- unseqToSeq[i] = (char) nInUse;
- nInUse++;
- }
+ for (int i = 0; i < 256; i++) {
+ if (inUse[i])
+ seqToUnseq[nInUseShadow++] = (byte) i;
}
+
+ this.nInUse = nInUseShadow;
}
- /*
- index of the last char in the block, so
- the block size == last + 1.
- */
+ /**
+ * Index of the last char in the block, so the block size == last + 1.
+ */
private int last;
- /*
- index in zptr[] of original string after sorting.
- */
+ /**
+ * Index in zptr[] of original string after sorting.
+ */
private int origPtr;
- /*
- always: in the range 0 .. 9.
- The current block size is 100000 * this number.
- */
+ /**
+ * always: in the range 0 .. 9.
+ * The current block size is 100000 * this number.
+ */
private int blockSize100k;
private boolean blockRandomised;
private int bsBuff;
private int bsLive;
- private CRC mCrc = new CRC();
+ private final CRC crc = new CRC();
- private boolean[] inUse = new boolean[256];
private int nInUse;
- private char[] seqToUnseq = new char[256];
- private char[] unseqToSeq = new char[256];
-
- private char[] selector = new char[MAX_SELECTORS];
- private char[] selectorMtf = new char[MAX_SELECTORS];
-
- private int[] tt;
- private char[] ll8;
-
- /*
- freq table collected to save a pass over the data
- during decompression.
- */
- private int[] unzftab = new int[256];
-
- private int[][] limit = new int[N_GROUPS][MAX_ALPHA_SIZE];
- private int[][] base = new int[N_GROUPS][MAX_ALPHA_SIZE];
- private int[][] perm = new int[N_GROUPS][MAX_ALPHA_SIZE];
- private int[] minLens = new int[N_GROUPS];
-
- private InputStream bsStream;
-
- private boolean streamEnd = false;
+ private InputStream in;
private int currentChar = -1;
+ private static final int EOF = 0;
private static final int START_BLOCK_STATE = 1;
private static final int RAND_PART_A_STATE = 2;
private static final int RAND_PART_B_STATE = 3;
@@ -125,330 +98,435 @@
private int storedBlockCRC, storedCombinedCRC;
private int computedBlockCRC, computedCombinedCRC;
- int i2, count, chPrev, ch2;
- int i, tPos;
- int rNToGo = 0;
- int rTPos = 0;
- int j2;
- char z;
-
- public BZip2CompressorInputStream(InputStream zStream) {
- ll8 = null;
- tt = null;
- bsSetStream(zStream);
- initialize();
- initBlock();
- setupBlock();
- }
+ // Variables used by setup* methods exclusively
- public int read() {
- if (streamEnd) {
- return -1;
+ private int su_count;
+ private int su_ch2;
+ private int su_chPrev;
+ private int su_i2;
+ private int su_j2;
+ private int su_rNToGo;
+ private int su_rTPos;
+ private int su_tPos;
+ private char su_z;
+
+ /**
+ * All memory intensive stuff.
+ * This field is initialized by initBlock().
+ */
+ private BZip2CompressorInputStream.Data data;
+
+ /**
+ * Constructs a new CBZip2InputStream which decompresses bytes read from
+ * the specified stream.
+ *
+ * <p>Although BZip2 headers are marked with the magic
+ * <tt>"Bz"</tt> this constructor expects the next byte in the
+ * stream to be the first one after the magic. Thus callers have
+ * to skip the first two bytes. Otherwise this constructor will
+ * throw an exception. </p>
+ *
+ * @throws IOException
+ * if the stream content is malformed or an I/O error occurs.
+ * @throws NullPointerException
+ * if <tt>in == null</tt>
+ */
+ public BZip2CompressorInputStream(final InputStream in) throws IOException {
+ super();
+
+ this.in = in;
+ init();
+ }
+
+ public int read() throws IOException {
+ if (this.in != null) {
+ return read0();
} else {
- int retChar = currentChar;
- switch(currentState) {
- case START_BLOCK_STATE:
- break;
- case RAND_PART_A_STATE:
- break;
- case RAND_PART_B_STATE:
- setupRandPartB();
- break;
- case RAND_PART_C_STATE:
- setupRandPartC();
- break;
- case NO_RAND_PART_A_STATE:
- break;
- case NO_RAND_PART_B_STATE:
- setupNoRandPartB();
- break;
- case NO_RAND_PART_C_STATE:
- setupNoRandPartC();
- break;
- default:
- break;
- }
- return retChar;
+ throw new IOException("stream closed");
}
}
- private void initialize() {
- char magic3, magic4;
- magic3 = bsGetUChar();
- magic4 = bsGetUChar();
- if (magic3 != 'h' || magic4 < '1' || magic4 > '9') {
- bsFinishedWithStream();
- streamEnd = true;
- return;
+ public int read(final byte[] dest, final int offs, final int len)
+ throws IOException {
+ if (offs < 0) {
+ throw new IndexOutOfBoundsException("offs(" + offs + ") < 0.");
+ }
+ if (len < 0) {
+ throw new IndexOutOfBoundsException("len(" + len + ") < 0.");
+ }
+ if (offs + len > dest.length) {
+ throw new IndexOutOfBoundsException("offs(" + offs + ") + len("
+ + len + ") > dest.length("
+ + dest.length + ").");
+ }
+ if (this.in == null) {
+ throw new IOException("stream closed");
}
- setDecompressStructureSizes(magic4 - '0');
- computedCombinedCRC = 0;
+ final int hi = offs + len;
+ int destOffs = offs;
+ for (int b; (destOffs < hi) && ((b = read0()) >= 0);) {
+ dest[destOffs++] = (byte) b;
+ }
+
+ return (destOffs == offs) ? -1 : (destOffs - offs);
}
- private void initBlock() {
- char magic1, magic2, magic3, magic4;
- char magic5, magic6;
- magic1 = bsGetUChar();
- magic2 = bsGetUChar();
- magic3 = bsGetUChar();
- magic4 = bsGetUChar();
- magic5 = bsGetUChar();
- magic6 = bsGetUChar();
- if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45
- && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90) {
- complete();
- return;
- }
+ private int read0() throws IOException {
+ final int retChar = this.currentChar;
- if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59
- || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59) {
- badBlockHeader();
- streamEnd = true;
- return;
- }
+ switch (this.currentState) {
+ case EOF:
+ return -1;
- storedBlockCRC = bsGetInt32();
+ case START_BLOCK_STATE:
+ throw new IllegalStateException();
- if (bsR(1) == 1) {
- blockRandomised = true;
- } else {
- blockRandomised = false;
- }
+ case RAND_PART_A_STATE:
+ throw new IllegalStateException();
- // currBlockNo++;
- getAndMoveToFrontDecode();
+ case RAND_PART_B_STATE:
+ setupRandPartB();
+ break;
- mCrc.initialiseCRC();
- currentState = START_BLOCK_STATE;
- }
+ case RAND_PART_C_STATE:
+ setupRandPartC();
+ break;
+
+ case NO_RAND_PART_A_STATE:
+ throw new IllegalStateException();
+
+ case NO_RAND_PART_B_STATE:
+ setupNoRandPartB();
+ break;
+
+ case NO_RAND_PART_C_STATE:
+ setupNoRandPartC();
+ break;
- private void endBlock() {
- computedBlockCRC = mCrc.getFinalCRC();
- /* A bad CRC is considered a fatal error. */
- if (storedBlockCRC != computedBlockCRC) {
- crcError();
+ default:
+ throw new IllegalStateException();
}
- computedCombinedCRC = (computedCombinedCRC << 1)
- | (computedCombinedCRC >>> 31);
- computedCombinedCRC ^= computedBlockCRC;
+ return retChar;
}
- private void complete() {
- storedCombinedCRC = bsGetInt32();
- if (storedCombinedCRC != computedCombinedCRC) {
- crcError();
+ private void init() throws IOException {
+ if (null == in) {
+ throw new IOException("No InputStream");
}
+ if (in.available() == 0) {
+ throw new IOException("Empty InputStream");
+ }
+ int magic2 = this.in.read();
+ if (magic2 != 'h') {
+ throw new IOException("Stream is not BZip2 formatted: expected 'h'"
+ + " as first byte but got '" + (char) magic2
+ + "'");
+ }
+
+ int blockSize = this.in.read();
+ if ((blockSize < '1') || (blockSize > '9')) {
+ throw new IOException("Stream is not BZip2 formatted: illegal "
+ + "blocksize " + (char) blockSize);
+ }
+
+ this.blockSize100k = blockSize - '0';
- bsFinishedWithStream();
- streamEnd = true;
+ initBlock();
+ setupBlock();
}
- private static void blockOverrun() {
- cadvise();
+ private void initBlock() throws IOException {
+ char magic0 = bsGetUByte();
+ char magic1 = bsGetUByte();
+ char magic2 = bsGetUByte();
+ char magic3 = bsGetUByte();
+ char magic4 = bsGetUByte();
+ char magic5 = bsGetUByte();
+
+ if (magic0 == 0x17 &&
+ magic1 == 0x72 &&
+ magic2 == 0x45 &&
+ magic3 == 0x38 &&
+ magic4 == 0x50 &&
+ magic5 == 0x90) {
+ complete(); // end of file
+ } else if (magic0 != 0x31 || // '1'
+ magic1 != 0x41 || // ')'
+ magic2 != 0x59 || // 'Y'
+ magic3 != 0x26 || // '&'
+ magic4 != 0x53 || // 'S'
+ magic5 != 0x59 // 'Y'
+ ) {
+ this.currentState = EOF;
+ throw new IOException("bad block header");
+ } else {
+ this.storedBlockCRC = bsGetInt();
+ this.blockRandomised = bsR(1) == 1;
+
+ /**
+ * Allocate data here instead in constructor, so we do not
+ * allocate it if the input file is empty.
+ */
+ if (this.data == null) {
+ this.data = new Data(this.blockSize100k);
+ }
+
+ // currBlockNo++;
+ getAndMoveToFrontDecode();
+
+ this.crc.initialiseCRC();
+ this.currentState = START_BLOCK_STATE;
+ }
}
- private static void badBlockHeader() {
- cadvise();
+ private void endBlock() throws IOException {
+ this.computedBlockCRC = this.crc.getFinalCRC();
+
+ // A bad CRC is considered a fatal error.
+ if (this.storedBlockCRC != this.computedBlockCRC) {
+ // make next blocks readable without error
+ // (repair feature, not yet documented, not tested)
+ this.computedCombinedCRC
+ = (this.storedCombinedCRC << 1)
+ | (this.storedCombinedCRC >>> 31);
+ this.computedCombinedCRC ^= this.storedBlockCRC;
+
+ reportCRCError();
+ }
+
+ this.computedCombinedCRC
+ = (this.computedCombinedCRC << 1)
+ | (this.computedCombinedCRC >>> 31);
+ this.computedCombinedCRC ^= this.computedBlockCRC;
}
- private static void crcError() {
- cadvise();
+ private void complete() throws IOException {
+ this.storedCombinedCRC = bsGetInt();
+ this.currentState = EOF;
+ this.data = null;
+
+ if (this.storedCombinedCRC != this.computedCombinedCRC) {
+ reportCRCError();
+ }
}
- private void bsFinishedWithStream() {
- try {
- if (this.bsStream != null) {
- if (this.bsStream != System.in) {
- this.bsStream.close();
- this.bsStream = null;
+ public void close() throws IOException {
+ InputStream inShadow = this.in;
+ if (inShadow != null) {
+ try {
+ if (inShadow != System.in) {
+ inShadow.close();
}
+ } finally {
+ this.data = null;
+ this.in = null;
}
- } catch (IOException ioe) {
- //ignore
}
}
- private void bsSetStream(InputStream f) {
- bsStream = f;
- bsLive = 0;
- bsBuff = 0;
- }
+ private int bsR(final int n) throws IOException {
+ int bsLiveShadow = this.bsLive;
+ int bsBuffShadow = this.bsBuff;
- private int bsR(int n) {
- int v;
- while (bsLive < n) {
- int zzi;
- char thech = 0;
- try {
- thech = (char) bsStream.read();
- } catch (IOException e) {
- compressedStreamEOF();
- }
- if (thech == -1) {
- compressedStreamEOF();
- }
- zzi = thech;
- bsBuff = (bsBuff << 8) | (zzi & 0xff);
- bsLive += 8;
+ if (bsLiveShadow < n) {
+ final InputStream inShadow = this.in;
+ do {
+ int thech = inShadow.read();
+
+ if (thech < 0) {
+ throw new IOException("unexpected end of stream");
+ }
+
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ } while (bsLiveShadow < n);
+
+ this.bsBuff = bsBuffShadow;
}
- v = (bsBuff >> (bsLive - n)) & ((1 << n) - 1);
- bsLive -= n;
- return v;
+ this.bsLive = bsLiveShadow - n;
+ return (bsBuffShadow >> (bsLiveShadow - n)) & ((1 << n) - 1);
}
- private char bsGetUChar() {
- return (char) bsR(8);
- }
+ private boolean bsGetBit() throws IOException {
+ int bsLiveShadow = this.bsLive;
+ int bsBuffShadow = this.bsBuff;
- private int bsGetint() {
- int u = 0;
- u = (u << 8) | bsR(8);
- u = (u << 8) | bsR(8);
- u = (u << 8) | bsR(8);
- u = (u << 8) | bsR(8);
- return u;
- }
+ if (bsLiveShadow < 1) {
+ int thech = this.in.read();
- private int bsGetIntVS(int numBits) {
- return (int) bsR(numBits);
+ if (thech < 0) {
+ throw new IOException("unexpected end of stream");
+ }
+
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ this.bsBuff = bsBuffShadow;
+ }
+
+ this.bsLive = bsLiveShadow - 1;
+ return ((bsBuffShadow >> (bsLiveShadow - 1)) & 1) != 0;
}
- private int bsGetInt32() {
- return (int) bsGetint();
+ private char bsGetUByte() throws IOException {
+ return (char) bsR(8);
}
- private void hbCreateDecodeTables(int[] limit, int[] base,
- int[] perm, char[] length,
- int minLen, int maxLen, int alphaSize) {
- int pp, i, j, vec;
+ private int bsGetInt() throws IOException {
+ return (((((bsR(8) << 8) | bsR(8)) << 8) | bsR(8)) << 8) | bsR(8);
+ }
- pp = 0;
- for (i = minLen; i <= maxLen; i++) {
- for (j = 0; j < alphaSize; j++) {
+ /**
+ * Called by createHuffmanDecodingTables() exclusively.
+ */
+ private static void hbCreateDecodeTables(final int[] limit,
+ final int[] base,
+ final int[] perm,
+ final char[] length,
+ final int minLen,
+ final int maxLen,
+ final int alphaSize) {
+ for (int i = minLen, pp = 0; i <= maxLen; i++) {
+ for (int j = 0; j < alphaSize; j++) {
if (length[j] == i) {
- perm[pp] = j;
- pp++;
+ perm[pp++] = j;
}
}
}
- for (i = 0; i < MAX_CODE_LEN; i++) {
+ for (int i = MAX_CODE_LEN; --i > 0;) {
base[i] = 0;
- }
- for (i = 0; i < alphaSize; i++) {
- base[length[i] + 1]++;
+ limit[i] = 0;
}
- for (i = 1; i < MAX_CODE_LEN; i++) {
- base[i] += base[i - 1];
+ for (int i = 0; i < alphaSize; i++) {
+ base[length[i] + 1]++;
}
- for (i = 0; i < MAX_CODE_LEN; i++) {
- limit[i] = 0;
+ for (int i = 1, b = base[0]; i < MAX_CODE_LEN; i++) {
+ b += base[i];
+ base[i] = b;
}
- vec = 0;
- for (i = minLen; i <= maxLen; i++) {
- vec += (base[i + 1] - base[i]);
+ for (int i = minLen, vec = 0, b = base[i]; i <= maxLen; i++) {
+ final int nb = base[i + 1];
+ vec += nb - b;
+ b = nb;
limit[i] = vec - 1;
vec <<= 1;
}
- for (i = minLen + 1; i <= maxLen; i++) {
+
+ for (int i = minLen + 1; i <= maxLen; i++) {
base[i] = ((limit[i - 1] + 1) << 1) - base[i];
}
}
- private void recvDecodingTables() {
- char len[][] = new char[N_GROUPS][MAX_ALPHA_SIZE];
- int i, j, t, nGroups, nSelectors, alphaSize;
- int minLen, maxLen;
- boolean[] inUse16 = new boolean[16];
+ private void recvDecodingTables() throws IOException {
+ final Data dataShadow = this.data;
+ final boolean[] inUse = dataShadow.inUse;
+ final byte[] pos = dataShadow.recvDecodingTables_pos;
+ final byte[] selector = dataShadow.selector;
+ final byte[] selectorMtf = dataShadow.selectorMtf;
+
+ int inUse16 = 0;
/* Receive the mapping table */
- for (i = 0; i < 16; i++) {
- if (bsR(1) == 1) {
- inUse16[i] = true;
- } else {
- inUse16[i] = false;
+ for (int i = 0; i < 16; i++) {
+ if (bsGetBit()) {
+ inUse16 |= 1 << i;
}
}
- for (i = 0; i < 256; i++) {
+ for (int i = 256; --i >= 0;) {
inUse[i] = false;
}
- for (i = 0; i < 16; i++) {
- if (inUse16[i]) {
- for (j = 0; j < 16; j++) {
- if (bsR(1) == 1) {
- inUse[i * 16 + j] = true;
+ for (int i = 0; i < 16; i++) {
+ if ((inUse16 & (1 << i)) != 0) {
+ final int i16 = i << 4;
+ for (int j = 0; j < 16; j++) {
+ if (bsGetBit()) {
+ inUse[i16 + j] = true;
}
}
}
}
makeMaps();
- alphaSize = nInUse + 2;
+ final int alphaSize = this.nInUse + 2;
/* Now the selectors */
- nGroups = bsR(3);
- nSelectors = bsR(15);
- for (i = 0; i < nSelectors; i++) {
- j = 0;
- while (bsR(1) == 1) {
+ final int nGroups = bsR(3);
+ final int nSelectors = bsR(15);
+
+ for (int i = 0; i < nSelectors; i++) {
+ int j = 0;
+ while (bsGetBit()) {
j++;
}
- selectorMtf[i] = (char) j;
+ selectorMtf[i] = (byte) j;
}
/* Undo the MTF values for the selectors. */
- {
- char[] pos = new char[N_GROUPS];
- char tmp, v;
- for (v = 0; v < nGroups; v++) {
- pos[v] = v;
- }
-
- for (i = 0; i < nSelectors; i++) {
- v = selectorMtf[i];
- tmp = pos[v];
- while (v > 0) {
- pos[v] = pos[v - 1];
- v--;
- }
- pos[0] = tmp;
- selector[i] = tmp;
+ for (int v = nGroups; --v >= 0;) {
+ pos[v] = (byte) v;
+ }
+
+ for (int i = 0; i < nSelectors; i++) {
+ int v = selectorMtf[i] & 0xff;
+ final byte tmp = pos[v];
+ while (v > 0) {
+ // nearly all times v is zero, 4 in most other cases
+ pos[v] = pos[v - 1];
+ v--;
}
+ pos[0] = tmp;
+ selector[i] = tmp;
}
+ final char[][] len = dataShadow.temp_charArray2d;
+
/* Now the coding tables */
- for (t = 0; t < nGroups; t++) {
+ for (int t = 0; t < nGroups; t++) {
int curr = bsR(5);
- for (i = 0; i < alphaSize; i++) {
- while (bsR(1) == 1) {
- if (bsR(1) == 0) {
- curr++;
- } else {
- curr--;
- }
- }
- len[t][i] = (char) curr;
+ final char[] len_t = len[t];
+ for (int i = 0; i < alphaSize; i++) {
+ while (bsGetBit()) {
+ curr += bsGetBit() ? -1 : 1;
+ }
+ len_t[i] = (char) curr;
}
}
- /* Create the Huffman decoding tables */
- for (t = 0; t < nGroups; t++) {
- minLen = 32;
- maxLen = 0;
- for (i = 0; i < alphaSize; i++) {
- if (len[t][i] > maxLen) {
- maxLen = len[t][i];
+ // finally create the Huffman tables
+ createHuffmanDecodingTables(alphaSize, nGroups);
+ }
+
+ /**
+ * Called by recvDecodingTables() exclusively.
+ */
+ private void createHuffmanDecodingTables(final int alphaSize,
+ final int nGroups) {
+ final Data dataShadow = this.data;
+ final char[][] len = dataShadow.temp_charArray2d;
+ final int[] minLens = dataShadow.minLens;
+ final int[][] limit = dataShadow.limit;
+ final int[][] base = dataShadow.base;
+ final int[][] perm = dataShadow.perm;
+
+ for (int t = 0; t < nGroups; t++) {
+ int minLen = 32;
+ int maxLen = 0;
+ final char[] len_t = len[t];
+ for (int i = alphaSize; --i >= 0;) {
+ final char lent = len_t[i];
+ if (lent > maxLen) {
+ maxLen = lent;
}
- if (len[t][i] < minLen) {
- minLen = len[t][i];
+ if (lent < minLen) {
+ minLen = lent;
}
}
hbCreateDecodeTables(limit[t], base[t], perm[t], len[t], minLen,
@@ -457,18 +535,22 @@
}
}
- private void getAndMoveToFrontDecode() {
- char[] yy = new char[256];
- int i, j, nextSym, limitLast;
- int EOB, groupNo, groupPos;
-
- limitLast = baseBlockSize * blockSize100k;
- origPtr = bsGetIntVS(24);
-
+ private void getAndMoveToFrontDecode() throws IOException {
+ this.origPtr = bsR(24);
recvDecodingTables();
- EOB = nInUse + 1;
- groupNo = -1;
- groupPos = 0;
+
+ final InputStream inShadow = this.in;
+ final Data dataShadow = this.data;
+ final byte[] ll8 = dataShadow.ll8;
+ final int[] unzftab = dataShadow.unzftab;
+ final byte[] selector = dataShadow.selector;
+ final byte[] seqToUnseq = dataShadow.seqToUnseq;
+ final char[] yy = dataShadow.getAndMoveToFrontDecode_yy;
+ final int[] minLens = dataShadow.minLens;
+ final int[][] limit = dataShadow.limit;
+ final int[][] base = dataShadow.base;
+ final int[][] perm = dataShadow.perm;
+ final int limitLast = this.blockSize100k * 100000;
/*
Setting up the unzftab entries here is not strictly
@@ -476,246 +558,259 @@
in a separate pass, and so saves a block's worth of
cache misses.
*/
- for (i = 0; i <= 255; i++) {
+ for (int i = 256; --i >= 0;) {
+ yy[i] = (char) i;
unzftab[i] = 0;
}
- for (i = 0; i <= 255; i++) {
- yy[i] = (char) i;
- }
+ int groupNo = 0;
+ int groupPos = G_SIZE - 1;
+ final int eob = this.nInUse + 1;
+ int nextSym = getAndMoveToFrontDecode0(0);
+ int bsBuffShadow = this.bsBuff;
+ int bsLiveShadow = this.bsLive;
+ int lastShadow = -1;
+ int zt = selector[groupNo] & 0xff;
+ int[] base_zt = base[zt];
+ int[] limit_zt = limit[zt];
+ int[] perm_zt = perm[zt];
+ int minLens_zt = minLens[zt];
- last = -1;
+ while (nextSym != eob) {
+ if ((nextSym == RUNA) || (nextSym == RUNB)) {
+ int s = -1;
- {
- int zt, zn, zvec, zj;
- if (groupPos == 0) {
- groupNo++;
- groupPos = G_SIZE;
- }
- groupPos--;
- zt = selector[groupNo];
- zn = minLens[zt];
- zvec = bsR(zn);
- while (zvec > limit[zt][zn]) {
- zn++;
- {
- {
- while (bsLive < 1) {
- int zzi;
- char thech = 0;
- try {
- thech = (char) bsStream.read();
- } catch (IOException e) {
- compressedStreamEOF();
- }
- if (thech == -1) {
- compressedStreamEOF();
- }
- zzi = thech;
- bsBuff = (bsBuff << 8) | (zzi & 0xff);
- bsLive += 8;
- }
+ for (int n = 1; true; n <<= 1) {
+ if (nextSym == RUNA) {
+ s += n;
+ } else if (nextSym == RUNB) {
+ s += n << 1;
+ } else {
+ break;
}
- zj = (bsBuff >> (bsLive - 1)) & 1;
- bsLive--;
- }
- zvec = (zvec << 1) | zj;
- }
- nextSym = perm[zt][zvec - base[zt][zn]];
- }
- while (true) {
+ if (groupPos == 0) {
+ groupPos = G_SIZE - 1;
+ zt = selector[++groupNo] & 0xff;
+ base_zt = base[zt];
+ limit_zt = limit[zt];
+ perm_zt = perm[zt];
+ minLens_zt = minLens[zt];
+ } else {
+ groupPos--;
+ }
- if (nextSym == EOB) {
- break;
- }
+ int zn = minLens_zt;
- if (nextSym == RUNA || nextSym == RUNB) {
- char ch;
- int s = -1;
- int N = 1;
- do {
- if (nextSym == RUNA) {
- s = s + (0 + 1) * N;
- } else if (nextSym == RUNB) {
- s = s + (1 + 1) * N;
- }
- N = N * 2;
- {
- int zt, zn, zvec, zj;
- if (groupPos == 0) {
- groupNo++;
- groupPos = G_SIZE;
+ // Inlined:
+ // int zvec = bsR(zn);
+ while (bsLiveShadow < zn) {
+ final int thech = inShadow.read();
+ if (thech >= 0) {
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ continue;
+ } else {
+ throw new IOException("unexpected end of stream");
}
- groupPos--;
- zt = selector[groupNo];
- zn = minLens[zt];
- zvec = bsR(zn);
- while (zvec > limit[zt][zn]) {
- zn++;
- {
- {
- while (bsLive < 1) {
- int zzi;
- char thech = 0;
- try {
- thech = (char) bsStream.read();
- } catch (IOException e) {
- compressedStreamEOF();
- }
- if (thech == -1) {
- compressedStreamEOF();
- }
- zzi = thech;
- bsBuff = (bsBuff << 8) | (zzi & 0xff);
- bsLive += 8;
- }
- }
- zj = (bsBuff >> (bsLive - 1)) & 1;
- bsLive--;
+ }
+ int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1);
+ bsLiveShadow -= zn;
+
+ while (zvec > limit_zt[zn]) {
+ zn++;
+ while (bsLiveShadow < 1) {
+ final int thech = inShadow.read();
+ if (thech >= 0) {
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ continue;
+ } else {
+ throw new IOException("unexpected end of stream");
}
- zvec = (zvec << 1) | zj;
}
- nextSym = perm[zt][zvec - base[zt][zn]];
+ bsLiveShadow--;
+ zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1);
}
- } while (nextSym == RUNA || nextSym == RUNB);
+ nextSym = perm_zt[zvec - base_zt[zn]];
+ }
- s++;
- ch = seqToUnseq[yy[0]];
- unzftab[ch] += s;
+ final byte ch = seqToUnseq[yy[0]];
+ unzftab[ch & 0xff] += s + 1;
- while (s > 0) {
- last++;
- ll8[last] = ch;
- s--;
+ while (s-- >= 0) {
+ ll8[++lastShadow] = ch;
}
- if (last >= limitLast) {
- blockOverrun();
+ if (lastShadow >= limitLast) {
+ throw new IOException("block overrun");
}
- continue;
} else {
- char tmp;
- last++;
- if (last >= limitLast) {
- blockOverrun();
+ if (++lastShadow >= limitLast) {
+ throw new IOException("block overrun");
}
- tmp = yy[nextSym - 1];
- unzftab[seqToUnseq[tmp]]++;
- ll8[last] = seqToUnseq[tmp];
+ final char tmp = yy[nextSym - 1];
+ unzftab[seqToUnseq[tmp] & 0xff]++;
+ ll8[lastShadow] = seqToUnseq[tmp];
/*
This loop is hammered during decompression,
- hence the unrolling.
-
- for (j = nextSym-1; j > 0; j--) yy[j] = yy[j-1];
+ hence avoid native method call overhead of
+ System.arraycopy for very small ranges to copy.
*/
-
- j = nextSym - 1;
- for (; j > 3; j -= 4) {
- yy[j] = yy[j - 1];
- yy[j - 1] = yy[j - 2];
- yy[j - 2] = yy[j - 3];
- yy[j - 3] = yy[j - 4];
- }
- for (; j > 0; j--) {
- yy[j] = yy[j - 1];
+ if (nextSym <= 16) {
+ for (int j = nextSym - 1; j > 0;) {
+ yy[j] = yy[--j];
+ }
+ } else {
+ System.arraycopy(yy, 0, yy, 1, nextSym - 1);
}
yy[0] = tmp;
- {
- int zt, zn, zvec, zj;
- if (groupPos == 0) {
- groupNo++;
- groupPos = G_SIZE;
- }
+
+ if (groupPos == 0) {
+ groupPos = G_SIZE - 1;
+ zt = selector[++groupNo] & 0xff;
+ base_zt = base[zt];
+ limit_zt = limit[zt];
+ perm_zt = perm[zt];
+ minLens_zt = minLens[zt];
+ } else {
groupPos--;
- zt = selector[groupNo];
- zn = minLens[zt];
- zvec = bsR(zn);
- while (zvec > limit[zt][zn]) {
- zn++;
- {
- {
- while (bsLive < 1) {
- int zzi;
- char thech = 0;
- try {
- thech = (char) bsStream.read();
- } catch (IOException e) {
- compressedStreamEOF();
- }
- zzi = thech;
- bsBuff = (bsBuff << 8) | (zzi & 0xff);
- bsLive += 8;
- }
- }
- zj = (bsBuff >> (bsLive - 1)) & 1;
- bsLive--;
+ }
+
+ int zn = minLens_zt;
+
+ // Inlined:
+ // int zvec = bsR(zn);
+ while (bsLiveShadow < zn) {
+ final int thech = inShadow.read();
+ if (thech >= 0) {
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ continue;
+ } else {
+ throw new IOException("unexpected end of stream");
+ }
+ }
+ int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1);
+ bsLiveShadow -= zn;
+
+ while (zvec > limit_zt[zn]) {
+ zn++;
+ while (bsLiveShadow < 1) {
+ final int thech = inShadow.read();
+ if (thech >= 0) {
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ continue;
+ } else {
+ throw new IOException("unexpected end of stream");
}
- zvec = (zvec << 1) | zj;
}
- nextSym = perm[zt][zvec - base[zt][zn]];
+ bsLiveShadow--;
+ zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1);
}
- continue;
+ nextSym = perm_zt[zvec - base_zt[zn]];
}
}
+
+ this.last = lastShadow;
+ this.bsLive = bsLiveShadow;
+ this.bsBuff = bsBuffShadow;
}
- private void setupBlock() {
- int[] cftab = new int[257];
- char ch;
+ private int getAndMoveToFrontDecode0(final int groupNo)
+ throws IOException {
+ final InputStream inShadow = this.in;
+ final Data dataShadow = this.data;
+ final int zt = dataShadow.selector[groupNo] & 0xff;
+ final int[] limit_zt = dataShadow.limit[zt];
+ int zn = dataShadow.minLens[zt];
+ int zvec = bsR(zn);
+ int bsLiveShadow = this.bsLive;
+ int bsBuffShadow = this.bsBuff;
- cftab[0] = 0;
- for (i = 1; i <= 256; i++) {
- cftab[i] = unzftab[i - 1];
+ while (zvec > limit_zt[zn]) {
+ zn++;
+ while (bsLiveShadow < 1) {
+ final int thech = inShadow.read();
+
+ if (thech >= 0) {
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ continue;
+ } else {
+ throw new IOException("unexpected end of stream");
+ }
+ }
+ bsLiveShadow--;
+ zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1);
}
- for (i = 1; i <= 256; i++) {
- cftab[i] += cftab[i - 1];
+
+ this.bsLive = bsLiveShadow;
+ this.bsBuff = bsBuffShadow;
+
+ return dataShadow.perm[zt][zvec - dataShadow.base[zt][zn]];
+ }
+
+ private void setupBlock() throws IOException {
+ if (this.data == null) {
+ return;
}
- for (i = 0; i <= last; i++) {
- ch = (char) ll8[i];
- tt[cftab[ch]] = i;
- cftab[ch]++;
+ final int[] cftab = this.data.cftab;
+ final int[] tt = this.data.initTT(this.last + 1);
+ final byte[] ll8 = this.data.ll8;
+ cftab[0] = 0;
+ System.arraycopy(this.data.unzftab, 0, cftab, 1, 256);
+
+ for (int i = 1, c = cftab[0]; i <= 256; i++) {
+ c += cftab[i];
+ cftab[i] = c;
}
- cftab = null;
- tPos = tt[origPtr];
+ for (int i = 0, lastShadow = this.last; i <= lastShadow; i++) {
+ tt[cftab[ll8[i] & 0xff]++] = i;
+ }
- count = 0;
- i2 = 0;
- ch2 = 256; /* not a char and not EOF */
+ if ((this.origPtr < 0) || (this.origPtr >= tt.length)) {
+ throw new IOException("stream corrupted");
+ }
- if (blockRandomised) {
- rNToGo = 0;
- rTPos = 0;
+ this.su_tPos = tt[this.origPtr];
+ this.su_count = 0;
+ this.su_i2 = 0;
+ this.su_ch2 = 256; /* not a char and not EOF */
+
+ if (this.blockRandomised) {
+ this.su_rNToGo = 0;
+ this.su_rTPos = 0;
setupRandPartA();
} else {
setupNoRandPartA();
}
}
- private void setupRandPartA() {
- if (i2 <= last) {
- chPrev = ch2;
- ch2 = ll8[tPos];
- tPos = tt[tPos];
- if (rNToGo == 0) {
- rNToGo = rNums[rTPos];
- rTPos++;
- if (rTPos == 512) {
- rTPos = 0;
- }
- }
- rNToGo--;
- ch2 ^= (int) ((rNToGo == 1) ? 1 : 0);
- i2++;
-
- currentChar = ch2;
- currentState = RAND_PART_B_STATE;
- mCrc.updateCRC(ch2);
+ private void setupRandPartA() throws IOException {
+ if (this.su_i2 <= this.last) {
+ this.su_chPrev = this.su_ch2;
+ int su_ch2Shadow = this.data.ll8[this.su_tPos] & 0xff;
+ this.su_tPos = this.data.tt[this.su_tPos];
+ if (this.su_rNToGo == 0) {
+ this.su_rNToGo = BZip2Constants.rNums[this.su_rTPos] - 1;
+ if (++this.su_rTPos == 512) {
+ this.su_rTPos = 0;
+ }
+ } else {
+ this.su_rNToGo--;
+ }
+ this.su_ch2 = su_ch2Shadow ^= (this.su_rNToGo == 1) ? 1 : 0;
+ this.su_i2++;
+ this.currentChar = su_ch2Shadow;
+ this.currentState = RAND_PART_B_STATE;
+ this.crc.updateCRC(su_ch2Shadow);
} else {
endBlock();
initBlock();
@@ -723,113 +818,155 @@
}
}
- private void setupNoRandPartA() {
- if (i2 <= last) {
- chPrev = ch2;
- ch2 = ll8[tPos];
- tPos = tt[tPos];
- i2++;
-
- currentChar = ch2;
- currentState = NO_RAND_PART_B_STATE;
- mCrc.updateCRC(ch2);
+ private void setupNoRandPartA() throws IOException {
+ if (this.su_i2 <= this.last) {
+ this.su_chPrev = this.su_ch2;
+ int su_ch2Shadow = this.data.ll8[this.su_tPos] & 0xff;
+ this.su_ch2 = su_ch2Shadow;
+ this.su_tPos = this.data.tt[this.su_tPos];
+ this.su_i2++;
+ this.currentChar = su_ch2Shadow;
+ this.currentState = NO_RAND_PART_B_STATE;
+ this.crc.updateCRC(su_ch2Shadow);
} else {
+ this.currentState = NO_RAND_PART_A_STATE;
endBlock();
initBlock();
setupBlock();
}
}
- private void setupRandPartB() {
- if (ch2 != chPrev) {
- currentState = RAND_PART_A_STATE;
- count = 1;
+ private void setupRandPartB() throws IOException {
+ if (this.su_ch2 != this.su_chPrev) {
+ this.currentState = RAND_PART_A_STATE;
+ this.su_count = 1;
setupRandPartA();
- } else {
- count++;
- if (count >= 4) {
- z = ll8[tPos];
- tPos = tt[tPos];
- if (rNToGo == 0) {
- rNToGo = rNums[rTPos];
- rTPos++;
- if (rTPos == 512) {
- rTPos = 0;
- }
+ } else if (++this.su_count >= 4) {
+ this.su_z = (char) (this.data.ll8[this.su_tPos] & 0xff);
+ this.su_tPos = this.data.tt[this.su_tPos];
+ if (this.su_rNToGo == 0) {
+ this.su_rNToGo = BZip2Constants.rNums[this.su_rTPos] - 1;
+ if (++this.su_rTPos == 512) {
+ this.su_rTPos = 0;
}
- rNToGo--;
- z ^= ((rNToGo == 1) ? 1 : 0);
- j2 = 0;
- currentState = RAND_PART_C_STATE;
- setupRandPartC();
} else {
- currentState = RAND_PART_A_STATE;
- setupRandPartA();
+ this.su_rNToGo--;
+ }
+ this.su_j2 = 0;
+ this.currentState = RAND_PART_C_STATE;
+ if (this.su_rNToGo == 1) {
+ this.su_z ^= 1;
}
+ setupRandPartC();
+ } else {
+ this.currentState = RAND_PART_A_STATE;
+ setupRandPartA();
}
}
- private void setupRandPartC() {
- if (j2 < (int) z) {
- currentChar = ch2;
- mCrc.updateCRC(ch2);
- j2++;
+ private void setupRandPartC() throws IOException {
+ if (this.su_j2 < this.su_z) {
+ this.currentChar = this.su_ch2;
+ this.crc.updateCRC(this.su_ch2);
+ this.su_j2++;
} else {
- currentState = RAND_PART_A_STATE;
- i2++;
- count = 0;
+ this.currentState = RAND_PART_A_STATE;
+ this.su_i2++;
+ this.su_count = 0;
setupRandPartA();
}
}
- private void setupNoRandPartB() {
- if (ch2 != chPrev) {
- currentState = NO_RAND_PART_A_STATE;
- count = 1;
+ private void setupNoRandPartB() throws IOException {
+ if (this.su_ch2 != this.su_chPrev) {
+ this.su_count = 1;
setupNoRandPartA();
+ } else if (++this.su_count >= 4) {
+ this.su_z = (char) (this.data.ll8[this.su_tPos] & 0xff);
+ this.su_tPos = this.data.tt[this.su_tPos];
+ this.su_j2 = 0;
+ setupNoRandPartC();
} else {
- count++;
- if (count >= 4) {
- z = ll8[tPos];
- tPos = tt[tPos];
- currentState = NO_RAND_PART_C_STATE;
- j2 = 0;
- setupNoRandPartC();
- } else {
- currentState = NO_RAND_PART_A_STATE;
- setupNoRandPartA();
- }
+ setupNoRandPartA();
}
}
- private void setupNoRandPartC() {
- if (j2 < (int) z) {
- currentChar = ch2;
- mCrc.updateCRC(ch2);
- j2++;
+ private void setupNoRandPartC() throws IOException {
+ if (this.su_j2 < this.su_z) {
+ int su_ch2Shadow = this.su_ch2;
+ this.currentChar = su_ch2Shadow;
+ this.crc.updateCRC(su_ch2Shadow);
+ this.su_j2++;
+ this.currentState = NO_RAND_PART_C_STATE;
} else {
- currentState = NO_RAND_PART_A_STATE;
- i2++;
- count = 0;
+ this.su_i2++;
+ this.su_count = 0;
setupNoRandPartA();
}
}
- private void setDecompressStructureSizes(int newSize100k) {
- if (!(0 <= newSize100k && newSize100k <= 9 && 0 <= blockSize100k
- && blockSize100k <= 9)) {
- // throw new IOException("Invalid block size");
- }
+ private static final class Data extends Object {
- blockSize100k = newSize100k;
+ // (with blockSize 900k)
+ final boolean[] inUse = new boolean[256]; // 256 byte
- if (newSize100k == 0) {
- return;
+ final byte[] seqToUnseq = new byte[256]; // 256 byte
+ final byte[] selector = new byte[MAX_SELECTORS]; // 18002 byte
+ final byte[] selectorMtf = new byte[MAX_SELECTORS]; // 18002 byte
+
+ /**
+ * Freq table collected to save a pass over the data during
+ * decompression.
+ */
+ final int[] unzftab = new int[256]; // 1024 byte
+
+ final int[][] limit = new int[N_GROUPS][MAX_ALPHA_SIZE]; // 6192 byte
+ final int[][] base = new int[N_GROUPS][MAX_ALPHA_SIZE]; // 6192 byte
+ final int[][] perm = new int[N_GROUPS][MAX_ALPHA_SIZE]; // 6192 byte
+ final int[] minLens = new int[N_GROUPS]; // 24 byte
+
+ final int[] cftab = new int[257]; // 1028 byte
+ final char[] getAndMoveToFrontDecode_yy = new char[256]; // 512 byte
+ final char[][] temp_charArray2d = new char[N_GROUPS][MAX_ALPHA_SIZE]; // 3096 byte
+ final byte[] recvDecodingTables_pos = new byte[N_GROUPS]; // 6 byte
+ //---------------
+ // 60798 byte
+
+ int[] tt; // 3600000 byte
+ byte[] ll8; // 900000 byte
+ //---------------
+ // 4560782 byte
+ //===============
+
+ Data(int blockSize100k) {
+ super();
+
+ this.ll8 = new byte[blockSize100k * BZip2Constants.baseBlockSize];
+ }
+
+ /**
+ * Initializes the {@link #tt} array.
+ *
+ * This method is called when the required length of the array
+ * is known. I don't initialize it at construction time to
+ * avoid unneccessary memory allocation when compressing small
+ * files.
+ */
+ final int[] initTT(int length) {
+ int[] ttShadow = this.tt;
+
+ // tt.length should always be >= length, but theoretically
+ // it can happen, if the compressor mixed small and large
+ // blocks. Normally only the last block will be smaller
+ // than others.
+ if ((ttShadow == null) || (ttShadow.length < length)) {
+ this.tt = ttShadow = new int[length];
+ }
+
+ return ttShadow;
}
- int n = baseBlockSize * newSize100k;
- ll8 = new char[n];
- tt = new int[n];
}
+
}
Modified: commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java
URL: http://svn.apache.org/viewvc/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java?rev=732685&r1=732684&r2=732685&view=diff
==============================================================================
--- commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java (original)
+++ commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java Thu Jan 8 03:13:50 2009
@@ -160,10 +160,10 @@
weight[nNodes] = ((weight[n1] & 0xffffff00)
+ (weight[n2] & 0xffffff00))
- | (1 + (((weight[n1] & 0x000000ff) >
- (weight[n2] & 0x000000ff)) ?
- (weight[n1] & 0x000000ff) :
- (weight[n2] & 0x000000ff)));
+ | (1 + (((weight[n1] & 0x000000ff)
+ > (weight[n2] & 0x000000ff))
+ ? (weight[n1] & 0x000000ff)
+ : (weight[n2] & 0x000000ff)));
parent[nNodes] = -1;
nHeap++;
@@ -428,6 +428,12 @@
combinedCRC = (combinedCRC << 1) | (combinedCRC >>> 31);
combinedCRC ^= blockCRC;
+ // If the stream was empty we must skip the rest of this method.
+ // See bug#32200.
+ if (last == -1) {
+ return;
+ }
+
/* sort the block and establish posn of original string */
doReversibleTransformation();
@@ -497,7 +503,7 @@
code[i] = vec;
vec++;
}
- };
+ }
vec <<= 1;
}
}
@@ -559,8 +565,7 @@
int v, t, i, j, gs, ge, totc, bt, bc, iter;
int nSelectors = 0, alphaSize, minLen, maxLen, selCtr;
- int nGroups;
- //int nBytes;
+ int nGroups, nBytes;
alphaSize = nInUse + 2;
for (t = 0; t < N_GROUPS; t++) {
@@ -698,7 +703,7 @@
bc = cost[t];
bt = t;
}
- };
+ }
totc += bc;
fave[bt]++;
selector[nSelectors] = (char) bt;
@@ -791,7 +796,7 @@
}
}
- //nBytes = bytesOut;
+ nBytes = bytesOut;
for (i = 0; i < 16; i++) {
if (inUse16[i]) {
bsW(1, 1);
@@ -815,7 +820,7 @@
}
/* Now the selectors. */
- //nBytes = bytesOut;
+ nBytes = bytesOut;
bsW (3, nGroups);
bsW (15, nSelectors);
for (i = 0; i < nSelectors; i++) {
@@ -826,7 +831,7 @@
}
/* Now the coding tables. */
- //nBytes = bytesOut;
+ nBytes = bytesOut;
for (t = 0; t < nGroups; t++) {
int curr = len[t][0];
@@ -845,7 +850,7 @@
}
/* And finally, the block data proper */
- //nBytes = bytesOut;
+ nBytes = bytesOut;
selCtr = 0;
gs = 0;
while (true) {
@@ -988,13 +993,9 @@
int dd;
}
- private void qSort3(int loSt, int hiSt, int dSt) {
+ private void qSort3(int loSt, int hiSt, int dSt, StackElem[] stack) {
int unLo, unHi, ltLo, gtHi, med, n, m;
int sp, lo, hi, d;
- StackElem[] stack = new StackElem[QSORT_STACK_SIZE];
- for (int count = 0; count < QSORT_STACK_SIZE; count++) {
- stack[count] = new StackElem();
- }
sp = 0;
@@ -1042,7 +1043,7 @@
ltLo++;
unLo++;
continue;
- };
+ }
if (n > 0) {
break;
}
@@ -1061,7 +1062,7 @@
gtHi--;
unHi--;
continue;
- };
+ }
if (n < 0) {
break;
}
@@ -1126,6 +1127,7 @@
*/
// if (verbosity >= 4) fprintf ( stderr, " sort initialise ...\n" );
+
for (i = 0; i < NUM_OVERSHOOT_BYTES; i++) {
block[last + i + 2] = block[(i % (last + 1)) + 1];
}
@@ -1203,8 +1205,8 @@
vv = runningOrder[i];
j = i;
while ((ftab[((runningOrder[j - h]) + 1) << 8]
- - ftab[(runningOrder[j - h]) << 8]) >
- (ftab[((vv) + 1) << 8] - ftab[(vv) << 8])) {
+ - ftab[(runningOrder[j - h]) << 8])
+ > (ftab[((vv) + 1) << 8] - ftab[(vv) << 8])) {
runningOrder[j] = runningOrder[j - h];
j = j - h;
if (j <= (h - 1)) {
@@ -1216,6 +1218,11 @@
} while (h != 1);
}
+ StackElem[] stack = new StackElem[QSORT_STACK_SIZE];
+ for (int count = 0; count < QSORT_STACK_SIZE; count++) {
+ stack[count] = new StackElem();
+ }
+
/*
The main sorting loop.
*/
@@ -1239,7 +1246,7 @@
int lo = ftab[sb] & CLEARMASK;
int hi = (ftab[sb + 1] & CLEARMASK) - 1;
if (hi > lo) {
- qSort3(lo, hi, 2);
+ qSort3(lo, hi, 2, stack);
numQSorted += (hi - lo + 1);
if (workDone > workLimit && firstAttempt) {
return;
@@ -1355,7 +1362,7 @@
origPtr = i;
break;
}
- };
+ }
if (origPtr == -1) {
panic();
@@ -1473,11 +1480,11 @@
if (i1 > last) {
i1 -= last;
i1--;
- };
+ }
if (i2 > last) {
i2 -= last;
i2--;
- };
+ }
k -= 4;
workDone++;
@@ -1492,9 +1499,9 @@
because the number of elems to sort is
usually small, typically <= 20.
*/
- private int[] incs = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+ private int[] incs = {1, 4, 13, 40, 121, 364, 1093, 3280,
9841, 29524, 88573, 265720,
- 797161, 2391484 };
+ 797161, 2391484};
private void allocateCompressStructures () {
int n = baseBlockSize * blockSize100k;
@@ -1560,7 +1567,7 @@
tmp2 = tmp;
tmp = yy[j];
yy[j] = tmp2;
- };
+ }
yy[0] = tmp;
if (j == 0) {
@@ -1580,12 +1587,12 @@
wr++;
mtfFreq[RUNB]++;
break;
- };
+ }
if (zPend < 2) {
break;
}
zPend = (zPend - 2) / 2;
- };
+ }
zPend = 0;
}
szptr[wr] = (short) (j + 1);
Modified: commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2Constants.java
URL: http://svn.apache.org/viewvc/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2Constants.java?rev=732685&r1=732684&r2=732685&view=diff
==============================================================================
--- commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2Constants.java (original)
+++ commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2Constants.java Thu Jan 8 03:13:50 2009
@@ -36,6 +36,13 @@
int MAX_SELECTORS = (2 + (900000 / G_SIZE));
int NUM_OVERSHOOT_BYTES = 20;
+ /**
+ * This array really shouldn't be here.
+ * Again, for historical purposes it is.
+ *
+ * <p>FIXME: This array should be in a private or package private
+ * location, since it could be modified by malicious code.</p>
+ */
int[] rNums = {
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
Modified: commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/CRC.java
URL: http://svn.apache.org/viewvc/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/CRC.java?rev=732685&r1=732684&r2=732685&view=diff
==============================================================================
--- commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/CRC.java (original)
+++ commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/compressors/bzip2/CRC.java Thu Jan 8 03:13:50 2009
@@ -23,78 +23,111 @@
* data.
*/
class CRC {
- private static int[] CRC32_TABLE = new int[] { 0x00000000, 0x04c11db7,
- 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2,
- 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
- 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70,
- 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b,
- 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 0x639b0da6,
- 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
- 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c,
- 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
- 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea,
- 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
- 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 0xf23a8028,
- 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43,
- 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 0x3d044b19,
- 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
- 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13,
- 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0,
- 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5,
- 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
- 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0xaca5c697,
- 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
- 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041,
- 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
- 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b,
- 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 0xc27dede8,
- 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded,
- 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
- 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56,
- 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d,
- 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 0x2c9f00f0,
- 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
- 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa,
- 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
- 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc,
- 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
- 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e,
- 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615,
- 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 0x92b45ba8,
- 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
- 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645,
- 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096,
- 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093,
- 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
- 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 0x3793a651,
- 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
- 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17,
- 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
- 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d,
- 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 0x8d79e0be,
- 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb,
- 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
- 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 };
-
- private int m_globalCrc;
-
- protected CRC() {
- initialiseCRC();
- }
-
- int getFinalCRC() {
- return ~m_globalCrc;
- }
-
- void initialiseCRC() {
- m_globalCrc = 0xffffffff;
- }
-
- void updateCRC(final int inCh) {
- int temp = (m_globalCrc >> 24) ^ inCh;
- if (temp < 0) {
- temp = 256 + temp;
- }
- m_globalCrc = (m_globalCrc << 8) ^ CRC32_TABLE[temp];
- }
+ static final int crc32Table[] = {
+ 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
+ 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
+ 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
+ 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
+ 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+ 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
+ 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
+ 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+ 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
+ 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
+ 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+ 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
+ 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
+ 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
+ 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
+ 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+ 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+ 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
+ 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
+ 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
+ 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
+ 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
+ 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
+ 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
+ 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
+ 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+ 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+ 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
+ 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
+ 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
+ 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
+ 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+ 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
+ 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
+ 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+ 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
+ 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
+ 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+ 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
+ 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
+ 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
+ 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
+ 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+ 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+ 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
+ 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
+ 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
+ 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
+ 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
+ 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
+ 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
+ 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
+ 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+ 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
+ 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
+ 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
+ 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
+ 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+ };
+
+ CRC() {
+ initialiseCRC();
+ }
+
+ void initialiseCRC() {
+ globalCrc = 0xffffffff;
+ }
+
+ int getFinalCRC() {
+ return ~globalCrc;
+ }
+
+ int getGlobalCRC() {
+ return globalCrc;
+ }
+
+ void setGlobalCRC(int newCrc) {
+ globalCrc = newCrc;
+ }
+
+ void updateCRC(int inCh) {
+ int temp = (globalCrc >> 24) ^ inCh;
+ if (temp < 0) {
+ temp = 256 + temp;
+ }
+ globalCrc = (globalCrc << 8) ^ CRC.crc32Table[temp];
+ }
+
+ void updateCRC(int inCh, int repeat) {
+ int globalCrcShadow = this.globalCrc;
+ while (repeat-- > 0) {
+ int temp = (globalCrcShadow >> 24) ^ inCh;
+ globalCrcShadow = (globalCrcShadow << 8) ^ crc32Table[(temp >= 0)
+ ? temp
+ : (temp + 256)];
+ }
+ this.globalCrc = globalCrcShadow;
+ }
+
+ int globalCrc;
}
\ No newline at end of file