source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/bzip2/CBZip2InputStream.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 23.6 KB
Line 
1/*
2 * Copyright 2001-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18/*
19 * This package is based on the work done by Keiron Liddle, Aftex Software
20 * <[email protected]> to whom the Ant project is very grateful for his
21 * great code.
22 */
23package org.apache.tools.bzip2;
24
25import java.io.InputStream;
26import java.io.IOException;
27
28/**
29 * An input stream that decompresses from the BZip2 format (without the file
30 * header chars) to be read as any other stream.
31 *
32 */
33public class CBZip2InputStream extends InputStream implements BZip2Constants {
34 private static void cadvise() {
35 System.out.println("CRC Error");
36 //throw new CCoruptionError();
37 }
38
39 private static void badBGLengths() {
40 cadvise();
41 }
42
43 private static void bitStreamEOF() {
44 cadvise();
45 }
46
47 private static void compressedStreamEOF() {
48 cadvise();
49 }
50
51 private void makeMaps() {
52 int i;
53 nInUse = 0;
54 for (i = 0; i < 256; i++) {
55 if (inUse[i]) {
56 seqToUnseq[nInUse] = (char) i;
57 unseqToSeq[i] = (char) nInUse;
58 nInUse++;
59 }
60 }
61 }
62
63 /*
64 index of the last char in the block, so
65 the block size == last + 1.
66 */
67 private int last;
68
69 /*
70 index in zptr[] of original string after sorting.
71 */
72 private int origPtr;
73
74 /*
75 always: in the range 0 .. 9.
76 The current block size is 100000 * this number.
77 */
78 private int blockSize100k;
79
80 private boolean blockRandomised;
81
82 private int bsBuff;
83 private int bsLive;
84 private CRC mCrc = new CRC();
85
86 private boolean[] inUse = new boolean[256];
87 private int nInUse;
88
89 private char[] seqToUnseq = new char[256];
90 private char[] unseqToSeq = new char[256];
91
92 private char[] selector = new char[MAX_SELECTORS];
93 private char[] selectorMtf = new char[MAX_SELECTORS];
94
95 private int[] tt;
96 private char[] ll8;
97
98 /*
99 freq table collected to save a pass over the data
100 during decompression.
101 */
102 private int[] unzftab = new int[256];
103
104 private int[][] limit = new int[N_GROUPS][MAX_ALPHA_SIZE];
105 private int[][] base = new int[N_GROUPS][MAX_ALPHA_SIZE];
106 private int[][] perm = new int[N_GROUPS][MAX_ALPHA_SIZE];
107 private int[] minLens = new int[N_GROUPS];
108
109 private InputStream bsStream;
110
111 private boolean streamEnd = false;
112
113 private int currentChar = -1;
114
115 private static final int START_BLOCK_STATE = 1;
116 private static final int RAND_PART_A_STATE = 2;
117 private static final int RAND_PART_B_STATE = 3;
118 private static final int RAND_PART_C_STATE = 4;
119 private static final int NO_RAND_PART_A_STATE = 5;
120 private static final int NO_RAND_PART_B_STATE = 6;
121 private static final int NO_RAND_PART_C_STATE = 7;
122
123 private int currentState = START_BLOCK_STATE;
124
125 private int storedBlockCRC, storedCombinedCRC;
126 private int computedBlockCRC, computedCombinedCRC;
127
128 int i2, count, chPrev, ch2;
129 int i, tPos;
130 int rNToGo = 0;
131 int rTPos = 0;
132 int j2;
133 char z;
134
135 public CBZip2InputStream(InputStream zStream) {
136 ll8 = null;
137 tt = null;
138 bsSetStream(zStream);
139 initialize();
140 initBlock();
141 setupBlock();
142 }
143
144 public int read() {
145 if (streamEnd) {
146 return -1;
147 } else {
148 int retChar = currentChar;
149 switch(currentState) {
150 case START_BLOCK_STATE:
151 break;
152 case RAND_PART_A_STATE:
153 break;
154 case RAND_PART_B_STATE:
155 setupRandPartB();
156 break;
157 case RAND_PART_C_STATE:
158 setupRandPartC();
159 break;
160 case NO_RAND_PART_A_STATE:
161 break;
162 case NO_RAND_PART_B_STATE:
163 setupNoRandPartB();
164 break;
165 case NO_RAND_PART_C_STATE:
166 setupNoRandPartC();
167 break;
168 default:
169 break;
170 }
171 return retChar;
172 }
173 }
174
175 private void initialize() {
176 char magic3, magic4;
177 magic3 = bsGetUChar();
178 magic4 = bsGetUChar();
179 if (magic3 != 'h' || magic4 < '1' || magic4 > '9') {
180 bsFinishedWithStream();
181 streamEnd = true;
182 return;
183 }
184
185 setDecompressStructureSizes(magic4 - '0');
186 computedCombinedCRC = 0;
187 }
188
189 private void initBlock() {
190 char magic1, magic2, magic3, magic4;
191 char magic5, magic6;
192 magic1 = bsGetUChar();
193 magic2 = bsGetUChar();
194 magic3 = bsGetUChar();
195 magic4 = bsGetUChar();
196 magic5 = bsGetUChar();
197 magic6 = bsGetUChar();
198 if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45
199 && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90) {
200 complete();
201 return;
202 }
203
204 if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59
205 || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59) {
206 badBlockHeader();
207 streamEnd = true;
208 return;
209 }
210
211 storedBlockCRC = bsGetInt32();
212
213 if (bsR(1) == 1) {
214 blockRandomised = true;
215 } else {
216 blockRandomised = false;
217 }
218
219 // currBlockNo++;
220 getAndMoveToFrontDecode();
221
222 mCrc.initialiseCRC();
223 currentState = START_BLOCK_STATE;
224 }
225
226 private void endBlock() {
227 computedBlockCRC = mCrc.getFinalCRC();
228 /* A bad CRC is considered a fatal error. */
229 if (storedBlockCRC != computedBlockCRC) {
230 crcError();
231 }
232
233 computedCombinedCRC = (computedCombinedCRC << 1)
234 | (computedCombinedCRC >>> 31);
235 computedCombinedCRC ^= computedBlockCRC;
236 }
237
238 private void complete() {
239 storedCombinedCRC = bsGetInt32();
240 if (storedCombinedCRC != computedCombinedCRC) {
241 crcError();
242 }
243
244 bsFinishedWithStream();
245 streamEnd = true;
246 }
247
248 private static void blockOverrun() {
249 cadvise();
250 }
251
252 private static void badBlockHeader() {
253 cadvise();
254 }
255
256 private static void crcError() {
257 cadvise();
258 }
259
260 private void bsFinishedWithStream() {
261 try {
262 if (this.bsStream != null) {
263 if (this.bsStream != System.in) {
264 this.bsStream.close();
265 this.bsStream = null;
266 }
267 }
268 } catch (IOException ioe) {
269 //ignore
270 }
271 }
272
273 private void bsSetStream(InputStream f) {
274 bsStream = f;
275 bsLive = 0;
276 bsBuff = 0;
277 }
278
279 private int bsR(int n) {
280 int v;
281 while (bsLive < n) {
282 int zzi;
283 char thech = 0;
284 try {
285 thech = (char) bsStream.read();
286 } catch (IOException e) {
287 compressedStreamEOF();
288 }
289 if (thech == -1) {
290 compressedStreamEOF();
291 }
292 zzi = thech;
293 bsBuff = (bsBuff << 8) | (zzi & 0xff);
294 bsLive += 8;
295 }
296
297 v = (bsBuff >> (bsLive - n)) & ((1 << n) - 1);
298 bsLive -= n;
299 return v;
300 }
301
302 private char bsGetUChar() {
303 return (char) bsR(8);
304 }
305
306 private int bsGetint() {
307 int u = 0;
308 u = (u << 8) | bsR(8);
309 u = (u << 8) | bsR(8);
310 u = (u << 8) | bsR(8);
311 u = (u << 8) | bsR(8);
312 return u;
313 }
314
315 private int bsGetIntVS(int numBits) {
316 return (int) bsR(numBits);
317 }
318
319 private int bsGetInt32() {
320 return (int) bsGetint();
321 }
322
323 private void hbCreateDecodeTables(int[] limit, int[] base,
324 int[] perm, char[] length,
325 int minLen, int maxLen, int alphaSize) {
326 int pp, i, j, vec;
327
328 pp = 0;
329 for (i = minLen; i <= maxLen; i++) {
330 for (j = 0; j < alphaSize; j++) {
331 if (length[j] == i) {
332 perm[pp] = j;
333 pp++;
334 }
335 }
336 }
337
338 for (i = 0; i < MAX_CODE_LEN; i++) {
339 base[i] = 0;
340 }
341 for (i = 0; i < alphaSize; i++) {
342 base[length[i] + 1]++;
343 }
344
345 for (i = 1; i < MAX_CODE_LEN; i++) {
346 base[i] += base[i - 1];
347 }
348
349 for (i = 0; i < MAX_CODE_LEN; i++) {
350 limit[i] = 0;
351 }
352 vec = 0;
353
354 for (i = minLen; i <= maxLen; i++) {
355 vec += (base[i + 1] - base[i]);
356 limit[i] = vec - 1;
357 vec <<= 1;
358 }
359 for (i = minLen + 1; i <= maxLen; i++) {
360 base[i] = ((limit[i - 1] + 1) << 1) - base[i];
361 }
362 }
363
364 private void recvDecodingTables() {
365 char len[][] = new char[N_GROUPS][MAX_ALPHA_SIZE];
366 int i, j, t, nGroups, nSelectors, alphaSize;
367 int minLen, maxLen;
368 boolean[] inUse16 = new boolean[16];
369
370 /* Receive the mapping table */
371 for (i = 0; i < 16; i++) {
372 if (bsR(1) == 1) {
373 inUse16[i] = true;
374 } else {
375 inUse16[i] = false;
376 }
377 }
378
379 for (i = 0; i < 256; i++) {
380 inUse[i] = false;
381 }
382
383 for (i = 0; i < 16; i++) {
384 if (inUse16[i]) {
385 for (j = 0; j < 16; j++) {
386 if (bsR(1) == 1) {
387 inUse[i * 16 + j] = true;
388 }
389 }
390 }
391 }
392
393 makeMaps();
394 alphaSize = nInUse + 2;
395
396 /* Now the selectors */
397 nGroups = bsR(3);
398 nSelectors = bsR(15);
399 for (i = 0; i < nSelectors; i++) {
400 j = 0;
401 while (bsR(1) == 1) {
402 j++;
403 }
404 selectorMtf[i] = (char) j;
405 }
406
407 /* Undo the MTF values for the selectors. */
408 {
409 char[] pos = new char[N_GROUPS];
410 char tmp, v;
411 for (v = 0; v < nGroups; v++) {
412 pos[v] = v;
413 }
414
415 for (i = 0; i < nSelectors; i++) {
416 v = selectorMtf[i];
417 tmp = pos[v];
418 while (v > 0) {
419 pos[v] = pos[v - 1];
420 v--;
421 }
422 pos[0] = tmp;
423 selector[i] = tmp;
424 }
425 }
426
427 /* Now the coding tables */
428 for (t = 0; t < nGroups; t++) {
429 int curr = bsR(5);
430 for (i = 0; i < alphaSize; i++) {
431 while (bsR(1) == 1) {
432 if (bsR(1) == 0) {
433 curr++;
434 } else {
435 curr--;
436 }
437 }
438 len[t][i] = (char) curr;
439 }
440 }
441
442 /* Create the Huffman decoding tables */
443 for (t = 0; t < nGroups; t++) {
444 minLen = 32;
445 maxLen = 0;
446 for (i = 0; i < alphaSize; i++) {
447 if (len[t][i] > maxLen) {
448 maxLen = len[t][i];
449 }
450 if (len[t][i] < minLen) {
451 minLen = len[t][i];
452 }
453 }
454 hbCreateDecodeTables(limit[t], base[t], perm[t], len[t], minLen,
455 maxLen, alphaSize);
456 minLens[t] = minLen;
457 }
458 }
459
460 private void getAndMoveToFrontDecode() {
461 char[] yy = new char[256];
462 int i, j, nextSym, limitLast;
463 int EOB, groupNo, groupPos;
464
465 limitLast = baseBlockSize * blockSize100k;
466 origPtr = bsGetIntVS(24);
467
468 recvDecodingTables();
469 EOB = nInUse + 1;
470 groupNo = -1;
471 groupPos = 0;
472
473 /*
474 Setting up the unzftab entries here is not strictly
475 necessary, but it does save having to do it later
476 in a separate pass, and so saves a block's worth of
477 cache misses.
478 */
479 for (i = 0; i <= 255; i++) {
480 unzftab[i] = 0;
481 }
482
483 for (i = 0; i <= 255; i++) {
484 yy[i] = (char) i;
485 }
486
487 last = -1;
488
489 {
490 int zt, zn, zvec, zj;
491 if (groupPos == 0) {
492 groupNo++;
493 groupPos = G_SIZE;
494 }
495 groupPos--;
496 zt = selector[groupNo];
497 zn = minLens[zt];
498 zvec = bsR(zn);
499 while (zvec > limit[zt][zn]) {
500 zn++;
501 {
502 {
503 while (bsLive < 1) {
504 int zzi;
505 char thech = 0;
506 try {
507 thech = (char) bsStream.read();
508 } catch (IOException e) {
509 compressedStreamEOF();
510 }
511 if (thech == -1) {
512 compressedStreamEOF();
513 }
514 zzi = thech;
515 bsBuff = (bsBuff << 8) | (zzi & 0xff);
516 bsLive += 8;
517 }
518 }
519 zj = (bsBuff >> (bsLive - 1)) & 1;
520 bsLive--;
521 }
522 zvec = (zvec << 1) | zj;
523 }
524 nextSym = perm[zt][zvec - base[zt][zn]];
525 }
526
527 while (true) {
528
529 if (nextSym == EOB) {
530 break;
531 }
532
533 if (nextSym == RUNA || nextSym == RUNB) {
534 char ch;
535 int s = -1;
536 int N = 1;
537 do {
538 if (nextSym == RUNA) {
539 s = s + (0 + 1) * N;
540 } else if (nextSym == RUNB) {
541 s = s + (1 + 1) * N;
542 }
543 N = N * 2;
544 {
545 int zt, zn, zvec, zj;
546 if (groupPos == 0) {
547 groupNo++;
548 groupPos = G_SIZE;
549 }
550 groupPos--;
551 zt = selector[groupNo];
552 zn = minLens[zt];
553 zvec = bsR(zn);
554 while (zvec > limit[zt][zn]) {
555 zn++;
556 {
557 {
558 while (bsLive < 1) {
559 int zzi;
560 char thech = 0;
561 try {
562 thech = (char) bsStream.read();
563 } catch (IOException e) {
564 compressedStreamEOF();
565 }
566 if (thech == -1) {
567 compressedStreamEOF();
568 }
569 zzi = thech;
570 bsBuff = (bsBuff << 8) | (zzi & 0xff);
571 bsLive += 8;
572 }
573 }
574 zj = (bsBuff >> (bsLive - 1)) & 1;
575 bsLive--;
576 }
577 zvec = (zvec << 1) | zj;
578 }
579 nextSym = perm[zt][zvec - base[zt][zn]];
580 }
581 } while (nextSym == RUNA || nextSym == RUNB);
582
583 s++;
584 ch = seqToUnseq[yy[0]];
585 unzftab[ch] += s;
586
587 while (s > 0) {
588 last++;
589 ll8[last] = ch;
590 s--;
591 }
592
593 if (last >= limitLast) {
594 blockOverrun();
595 }
596 continue;
597 } else {
598 char tmp;
599 last++;
600 if (last >= limitLast) {
601 blockOverrun();
602 }
603
604 tmp = yy[nextSym - 1];
605 unzftab[seqToUnseq[tmp]]++;
606 ll8[last] = seqToUnseq[tmp];
607
608 /*
609 This loop is hammered during decompression,
610 hence the unrolling.
611
612 for (j = nextSym-1; j > 0; j--) yy[j] = yy[j-1];
613 */
614
615 j = nextSym - 1;
616 for (; j > 3; j -= 4) {
617 yy[j] = yy[j - 1];
618 yy[j - 1] = yy[j - 2];
619 yy[j - 2] = yy[j - 3];
620 yy[j - 3] = yy[j - 4];
621 }
622 for (; j > 0; j--) {
623 yy[j] = yy[j - 1];
624 }
625
626 yy[0] = tmp;
627 {
628 int zt, zn, zvec, zj;
629 if (groupPos == 0) {
630 groupNo++;
631 groupPos = G_SIZE;
632 }
633 groupPos--;
634 zt = selector[groupNo];
635 zn = minLens[zt];
636 zvec = bsR(zn);
637 while (zvec > limit[zt][zn]) {
638 zn++;
639 {
640 {
641 while (bsLive < 1) {
642 int zzi;
643 char thech = 0;
644 try {
645 thech = (char) bsStream.read();
646 } catch (IOException e) {
647 compressedStreamEOF();
648 }
649 zzi = thech;
650 bsBuff = (bsBuff << 8) | (zzi & 0xff);
651 bsLive += 8;
652 }
653 }
654 zj = (bsBuff >> (bsLive - 1)) & 1;
655 bsLive--;
656 }
657 zvec = (zvec << 1) | zj;
658 }
659 nextSym = perm[zt][zvec - base[zt][zn]];
660 }
661 continue;
662 }
663 }
664 }
665
666 private void setupBlock() {
667 int[] cftab = new int[257];
668 char ch;
669
670 cftab[0] = 0;
671 for (i = 1; i <= 256; i++) {
672 cftab[i] = unzftab[i - 1];
673 }
674 for (i = 1; i <= 256; i++) {
675 cftab[i] += cftab[i - 1];
676 }
677
678 for (i = 0; i <= last; i++) {
679 ch = (char) ll8[i];
680 tt[cftab[ch]] = i;
681 cftab[ch]++;
682 }
683 cftab = null;
684
685 tPos = tt[origPtr];
686
687 count = 0;
688 i2 = 0;
689 ch2 = 256; /* not a char and not EOF */
690
691 if (blockRandomised) {
692 rNToGo = 0;
693 rTPos = 0;
694 setupRandPartA();
695 } else {
696 setupNoRandPartA();
697 }
698 }
699
700 private void setupRandPartA() {
701 if (i2 <= last) {
702 chPrev = ch2;
703 ch2 = ll8[tPos];
704 tPos = tt[tPos];
705 if (rNToGo == 0) {
706 rNToGo = rNums[rTPos];
707 rTPos++;
708 if (rTPos == 512) {
709 rTPos = 0;
710 }
711 }
712 rNToGo--;
713 ch2 ^= (int) ((rNToGo == 1) ? 1 : 0);
714 i2++;
715
716 currentChar = ch2;
717 currentState = RAND_PART_B_STATE;
718 mCrc.updateCRC(ch2);
719 } else {
720 endBlock();
721 initBlock();
722 setupBlock();
723 }
724 }
725
726 private void setupNoRandPartA() {
727 if (i2 <= last) {
728 chPrev = ch2;
729 ch2 = ll8[tPos];
730 tPos = tt[tPos];
731 i2++;
732
733 currentChar = ch2;
734 currentState = NO_RAND_PART_B_STATE;
735 mCrc.updateCRC(ch2);
736 } else {
737 endBlock();
738 initBlock();
739 setupBlock();
740 }
741 }
742
743 private void setupRandPartB() {
744 if (ch2 != chPrev) {
745 currentState = RAND_PART_A_STATE;
746 count = 1;
747 setupRandPartA();
748 } else {
749 count++;
750 if (count >= 4) {
751 z = ll8[tPos];
752 tPos = tt[tPos];
753 if (rNToGo == 0) {
754 rNToGo = rNums[rTPos];
755 rTPos++;
756 if (rTPos == 512) {
757 rTPos = 0;
758 }
759 }
760 rNToGo--;
761 z ^= ((rNToGo == 1) ? 1 : 0);
762 j2 = 0;
763 currentState = RAND_PART_C_STATE;
764 setupRandPartC();
765 } else {
766 currentState = RAND_PART_A_STATE;
767 setupRandPartA();
768 }
769 }
770 }
771
772 private void setupRandPartC() {
773 if (j2 < (int) z) {
774 currentChar = ch2;
775 mCrc.updateCRC(ch2);
776 j2++;
777 } else {
778 currentState = RAND_PART_A_STATE;
779 i2++;
780 count = 0;
781 setupRandPartA();
782 }
783 }
784
785 private void setupNoRandPartB() {
786 if (ch2 != chPrev) {
787 currentState = NO_RAND_PART_A_STATE;
788 count = 1;
789 setupNoRandPartA();
790 } else {
791 count++;
792 if (count >= 4) {
793 z = ll8[tPos];
794 tPos = tt[tPos];
795 currentState = NO_RAND_PART_C_STATE;
796 j2 = 0;
797 setupNoRandPartC();
798 } else {
799 currentState = NO_RAND_PART_A_STATE;
800 setupNoRandPartA();
801 }
802 }
803 }
804
805 private void setupNoRandPartC() {
806 if (j2 < (int) z) {
807 currentChar = ch2;
808 mCrc.updateCRC(ch2);
809 j2++;
810 } else {
811 currentState = NO_RAND_PART_A_STATE;
812 i2++;
813 count = 0;
814 setupNoRandPartA();
815 }
816 }
817
818 private void setDecompressStructureSizes(int newSize100k) {
819 if (!(0 <= newSize100k && newSize100k <= 9 && 0 <= blockSize100k
820 && blockSize100k <= 9)) {
821 // throw new IOException("Invalid block size");
822 }
823
824 blockSize100k = newSize100k;
825
826 if (newSize100k == 0) {
827 return;
828 }
829
830 int n = baseBlockSize * newSize100k;
831 ll8 = new char[n];
832 tt = new int[n];
833 }
834}
835
Note: See TracBrowser for help on using the repository browser.