rbzip2 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,66 +1,82 @@
1
- # This code is free software; you can redistribute it and/or modify it under
2
- # the terms of the new BSD License.
3
- #
4
- # Copyright (c) 2011, Sebastian Staudt
5
-
6
- module RBzip2
7
-
8
- BASEBLOCKSIZE = 100000
9
- MAX_ALPHA_SIZE = 258
10
- MAX_CODE_LEN = 23
11
- RUNA = 0
12
- RUNB = 1
13
- N_GROUPS = 6
14
- G_SIZE = 50
15
- N_ITERS = 4
16
- MAX_SELECTORS = (2 + (900000 / G_SIZE))
17
- NUM_OVERSHOOT_BYTES = 20
18
-
19
- EOF = 0
20
- START_BLOCK_STATE = 1
21
- RAND_PART_A_STATE = 2
22
- RAND_PART_B_STATE = 3
23
- RAND_PART_C_STATE = 4
24
- NO_RAND_PART_A_STATE = 5
25
- NO_RAND_PART_B_STATE = 6
26
- NO_RAND_PART_C_STATE = 7
27
-
28
- RNUMS = [
29
- 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863,
30
- 491, 741, 242, 949, 214, 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
31
- 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 878, 465, 811, 169, 869,
32
- 675, 611, 697, 867, 561, 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
33
- 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 170, 607, 520, 932, 727,
34
- 476, 693, 425, 174, 647, 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
35
- 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 641, 801, 220, 162, 819,
36
- 984, 589, 513, 495, 799, 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
37
- 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 98, 553, 163, 354, 666,
38
- 933, 424, 341, 533, 870, 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
39
- 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 184, 943, 795, 384, 383,
40
- 461, 404, 758, 839, 887, 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
41
- 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 652, 934, 970, 447, 318,
42
- 353, 859, 672, 112, 785, 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
43
- 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 653, 282, 762, 623, 680,
44
- 81, 927, 626, 789, 125, 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
45
- 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 857, 956, 358, 619, 580,
46
- 124, 737, 594, 701, 612, 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
47
- 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 344, 805, 988, 739, 511,
48
- 655, 814, 334, 249, 515, 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
49
- 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 686, 754, 806, 760, 493,
50
- 403, 415, 394, 687, 700, 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
51
- 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 680, 879, 194, 572, 640,
52
- 724, 926, 56, 204, 700, 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
53
- 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 134, 108, 571, 364, 631,
54
- 212, 174, 643, 304, 329, 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
55
- 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 170, 514, 364, 692, 829,
56
- 82, 855, 953, 676, 246, 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
57
- 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 896, 831, 547, 261, 524,
58
- 462, 293, 465, 502, 56, 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
59
- 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 61, 688, 793, 644, 986,
60
- 403, 106, 366, 905, 644, 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
61
- 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 920, 176, 193, 713, 857,
62
- 265, 203, 50, 668, 108, 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
63
- 936, 638
64
- ]
65
-
66
- end
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2011, Sebastian Staudt
5
+
6
+ module RBzip2::Constants
7
+
8
+ BASEBLOCKSIZE = 100000
9
+ MAX_ALPHA_SIZE = 258
10
+ MAX_CODE_LEN = 23
11
+ RUNA = 0
12
+ RUNB = 1
13
+ N_GROUPS = 6
14
+ G_SIZE = 50
15
+ N_ITERS = 4
16
+ MAX_SELECTORS = (2 + (900000 / G_SIZE))
17
+ NUM_OVERSHOOT_BYTES = 20
18
+
19
+ EOF = 0
20
+ START_BLOCK_STATE = 1
21
+ RAND_PART_A_STATE = 2
22
+ RAND_PART_B_STATE = 3
23
+ RAND_PART_C_STATE = 4
24
+ NO_RAND_PART_A_STATE = 5
25
+ NO_RAND_PART_B_STATE = 6
26
+ NO_RAND_PART_C_STATE = 7
27
+
28
+ RNUMS = [
29
+ 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863,
30
+ 491, 741, 242, 949, 214, 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
31
+ 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 878, 465, 811, 169, 869,
32
+ 675, 611, 697, 867, 561, 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
33
+ 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 170, 607, 520, 932, 727,
34
+ 476, 693, 425, 174, 647, 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
35
+ 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 641, 801, 220, 162, 819,
36
+ 984, 589, 513, 495, 799, 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
37
+ 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 98, 553, 163, 354, 666,
38
+ 933, 424, 341, 533, 870, 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
39
+ 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 184, 943, 795, 384, 383,
40
+ 461, 404, 758, 839, 887, 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
41
+ 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 652, 934, 970, 447, 318,
42
+ 353, 859, 672, 112, 785, 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
43
+ 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 653, 282, 762, 623, 680,
44
+ 81, 927, 626, 789, 125, 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
45
+ 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 857, 956, 358, 619, 580,
46
+ 124, 737, 594, 701, 612, 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
47
+ 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 344, 805, 988, 739, 511,
48
+ 655, 814, 334, 249, 515, 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
49
+ 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 686, 754, 806, 760, 493,
50
+ 403, 415, 394, 687, 700, 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
51
+ 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 680, 879, 194, 572, 640,
52
+ 724, 926, 56, 204, 700, 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
53
+ 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 134, 108, 571, 364, 631,
54
+ 212, 174, 643, 304, 329, 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
55
+ 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 170, 514, 364, 692, 829,
56
+ 82, 855, 953, 676, 246, 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
57
+ 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 896, 831, 547, 261, 524,
58
+ 462, 293, 465, 502, 56, 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
59
+ 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 61, 688, 793, 644, 986,
60
+ 403, 106, 366, 905, 644, 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
61
+ 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 920, 176, 193, 713, 857,
62
+ 265, 203, 50, 668, 108, 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
63
+ 936, 638
64
+ ]
65
+
66
+ MIN_BLOCK_SIZE = 1
67
+ MAX_BLOCK_SIZE = 9
68
+ SETMASK = (1 << 21)
69
+ CLEARMASK = (~SETMASK)
70
+ GREATER_ICOST = 15
71
+ LESSER_ICOST = 0
72
+ SMALL_THRESH = 20
73
+ DEPTH_THRESH = 10
74
+ WORK_FACTOR = 30
75
+ QSORT_STACK_SIZE = 1000
76
+
77
+ INCS = [
78
+ 1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161,
79
+ 2391484
80
+ ]
81
+
82
+ end
@@ -1,105 +1,105 @@
1
- # This code is free software; you can redistribute it and/or modify it under
2
- # the terms of the new BSD License.
3
- #
4
- # Copyright (c) 2011, Sebastian Staudt
5
-
6
- class RBzip2::CRC
7
-
8
- CRC32_TABLE = [
9
- 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
10
- 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
11
- 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
12
- 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
13
- 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
14
- 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
15
- 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
16
- 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
17
- 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
18
- 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
19
- 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
20
- 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
21
- 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
22
- 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
23
- 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
24
- 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
25
- 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
26
- 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
27
- 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
28
- 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
29
- 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
30
- 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
31
- 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
32
- 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
33
- 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
34
- 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
35
- 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
36
- 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
37
- 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
38
- 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
39
- 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
40
- 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
41
- 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
42
- 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
43
- 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
44
- 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
45
- 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
46
- 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
47
- 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
48
- 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
49
- 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
50
- 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
51
- 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
52
- 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
53
- 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
54
- 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
55
- 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
56
- 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
57
- 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
58
- 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
59
- 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
60
- 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
61
- 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
62
- 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
63
- 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
64
- 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
65
- 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
66
- 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
67
- 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
68
- 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
69
- 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
70
- 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
71
- 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
72
- 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
73
- ]
74
-
75
- attr_accessor :global_crc
76
-
77
- def initialize
78
- initialize_crc
79
- end
80
-
81
- def initialize_crc
82
- @global_crc = 0xffffffff
83
- end
84
-
85
- def final_crc
86
- @global_crc ^ 0xffffffff
87
- end
88
-
89
- def update_crc(in_ch, repeat = -1)
90
- if repeat == -1
91
- temp = ((@global_crc >> 24) ^ in_ch) % 256
92
- temp = 256 + temp if temp < 0
93
- @global_crc = ((@global_crc << 8) ^ CRC32_TABLE[temp]) % 2**32
94
- else
95
- global_crc_shadow = @global_crc
96
- repeat.downto(0) do
97
- temp = ((global_crc_shadow >> 24) ^ in_ch) % 256
98
- temp = 256 + temp if temp < 0
99
- global_crc_shadow = (global_crc_shadow << 8) ^ CRC32_TABLE[temp]
100
- end
101
- @global_crc = global_crc_shadow % 2**32
102
- end
103
- end
104
-
105
- end
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2011, Sebastian Staudt
5
+
6
+ class RBzip2::CRC
7
+
8
+ CRC32_TABLE = [
9
+ 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
10
+ 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
11
+ 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
12
+ 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
13
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
14
+ 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
15
+ 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
16
+ 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
17
+ 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
18
+ 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
19
+ 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
20
+ 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
21
+ 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
22
+ 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
23
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
24
+ 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
25
+ 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
26
+ 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
27
+ 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
28
+ 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
29
+ 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
30
+ 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
31
+ 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
32
+ 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
33
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
34
+ 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
35
+ 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
36
+ 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
37
+ 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
38
+ 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
39
+ 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
40
+ 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
41
+ 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
42
+ 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
43
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
44
+ 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
45
+ 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
46
+ 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
47
+ 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
48
+ 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
49
+ 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
50
+ 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
51
+ 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
52
+ 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
53
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
54
+ 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
55
+ 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
56
+ 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
57
+ 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
58
+ 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
59
+ 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
60
+ 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
61
+ 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
62
+ 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
63
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
64
+ 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
65
+ 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
66
+ 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
67
+ 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
68
+ 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
69
+ 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
70
+ 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
71
+ 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
72
+ 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
73
+ ]
74
+
75
+ attr_accessor :global_crc
76
+
77
+ def initialize
78
+ initialize_crc
79
+ end
80
+
81
+ def initialize_crc
82
+ @global_crc = 0xffffffff
83
+ end
84
+
85
+ def final_crc
86
+ @global_crc ^ 0xffffffff
87
+ end
88
+
89
+ def update_crc(in_ch, repeat = -1)
90
+ if repeat == -1
91
+ temp = ((@global_crc >> 24) ^ in_ch) % 256
92
+ temp = 256 + temp if temp < 0
93
+ @global_crc = ((@global_crc << 8) ^ CRC32_TABLE[temp]) & 0xffffffff
94
+ else
95
+ global_crc_shadow = @global_crc
96
+ repeat.times do
97
+ temp = (global_crc_shadow >> 24) ^ in_ch
98
+ temp = 256 + temp if temp < 0
99
+ global_crc_shadow = ((global_crc_shadow << 8) ^ CRC32_TABLE[temp]) & 0xffffffff
100
+ end
101
+ @global_crc = global_crc_shadow
102
+ end
103
+ end
104
+
105
+ end
@@ -1,684 +1,703 @@
1
- # This code is free software; you can redistribute it and/or modify it under
2
- # the terms of the new BSD License.
3
- #
4
- # Copyright (c) 2011, Sebastian Staudt
5
-
6
- require 'stringio'
7
-
8
- require 'rbzip2/crc'
9
- require 'rbzip2/constants'
10
- require 'rbzip2/data'
11
-
12
- module RBzip2::Decompressor
13
-
14
- def count(read)
15
- @bytes_read += read if read != -1
16
- end
17
-
18
- def read(length = uncompressed)
19
- raise 'stream closed' if @io.nil?
20
-
21
- if length == 1
22
- r = read0
23
- count (r < 0 ? -1 : 1)
24
- r
25
- elsif length > 0
26
- r = StringIO.new
27
- length.times do
28
- b = read0
29
- break if b < 0
30
- r.write b.chr
31
- end
32
- count r.size
33
- r.string
34
- end
35
- end
36
-
37
- def read0
38
- ret_char = @current_char
39
-
40
- case @current_state
41
- when RBzip2::EOF
42
- return -1
43
-
44
- when RBzip2::RAND_PART_B_STATE
45
- setup_rand_part_b
46
-
47
- when RBzip2::RAND_PART_C_STATE
48
- setup_rand_part_c
49
-
50
- when RBzip2::NO_RAND_PART_B_STATE
51
- setup_no_rand_part_b
52
-
53
- when RBzip2::NO_RAND_PART_C_STATE
54
- setup_no_rand_part_c
55
-
56
- when RBzip2::START_BLOCK_STATE
57
- when RBzip2::RAND_PART_A_STATE
58
- when RBzip2::NO_RAND_PART_A_STATE
59
- else
60
- raise 'illegal state'
61
- end
62
-
63
- ret_char
64
- end
65
-
66
- def make_maps
67
- in_use = @data.in_use
68
- seq_to_unseq = @data.seq_to_unseq;
69
-
70
- n_in_use_shadow = 0;
71
-
72
- 256.times do |i|
73
- if in_use[i]
74
- seq_to_unseq[n_in_use_shadow] = i
75
- n_in_use_shadow += 1
76
- end
77
- end
78
-
79
- @n_in_use = n_in_use_shadow;
80
- end
81
-
82
- def init
83
- check_magic
84
-
85
- block_size = @io.read(1).to_i
86
- raise 'Illegal block size.' if block_size < 1 || block_size > 9
87
- @block_size = block_size
88
-
89
- init_block
90
- setup_block
91
- end
92
-
93
- def check_magic
94
- raise 'Magic number does not match "BZh".' unless @io.read(3) == 'BZh'
95
- end
96
-
97
- def init_block
98
- magic = [ubyte, ubyte, ubyte, ubyte, ubyte, ubyte]
99
-
100
- if magic == [0x17, 0x72, 0x45, 0x38, 0x50, 0x90]
101
- complete
102
- elsif magic != [0x31, 0x41, 0x59, 0x26, 0x53, 0x59]
103
- @current_state = RBzip2::EOF
104
-
105
- raise 'Bad block header.'
106
- else
107
- @stored_block_crc = int
108
- @block_randomised = bit
109
-
110
- @data = RBzip2::Data.new @block_size if @data.nil?
111
-
112
- get_and_move_to_front_decode
113
-
114
- @crc.initialize_crc
115
- @current_state = RBzip2::START_BLOCK_STATE
116
- end
117
- end
118
-
119
- def end_block
120
- @computed_block_crc = @crc.final_crc
121
-
122
- if @stored_block_crc != @computed_block_crc
123
- @computed_combined_crc = (@stored_combined_crc << 1) | (@stored_combined_crc >> 31)
124
- @computed_combined_crc ^= @stored_block_crc
125
-
126
- raise 'BZip2 CRC error'
127
- end
128
-
129
- @computed_combined_crc = (@computed_combined_crc << 1) | (@computed_combined_crc >> 31)
130
- @computed_combined_crc ^= @computed_block_crc
131
- end
132
-
133
- def complete
134
- @stored_combined_crc = int
135
- @current_state = RBzip2::EOF
136
- @data = nil
137
-
138
- raise 'BZip2 CRC error' if @stored_combined_crc != @computed_combined_crc
139
- end
140
-
141
- def close
142
- if @io != $stdin
143
- @io = nil
144
- @data = nil
145
- end
146
- end
147
-
148
- def r(n)
149
- live_shadow = @live
150
- buff_shadow = @buff
151
-
152
- if live_shadow < n
153
- begin
154
- thech = @io.read(1)[0].ord
155
-
156
- raise 'unexpected end of stream' if thech < 0
157
-
158
- buff_shadow = (buff_shadow << 8) | thech
159
- live_shadow += 8
160
- end while live_shadow < n
161
-
162
- @buff = buff_shadow
163
- end
164
-
165
- @live = live_shadow - n
166
-
167
- (buff_shadow >> (live_shadow - n)) & ((1 << n) - 1)
168
- end
169
-
170
- def bit
171
- r(1) != 0
172
- end
173
-
174
- def ubyte
175
- r 8
176
- end
177
-
178
- def int
179
- (((((r(8) << 8) | r(8)) << 8) | r(8)) << 8) | r(8)
180
- end
181
-
182
- def create_decode_tables(limit, base, perm, length, min_len, max_len, alpha_size)
183
- pp = 0
184
- (min_len..max_len).each do |i|
185
- alpha_size.times do |j|
186
- if length[j] == i
187
- perm[pp] = j
188
- pp += 1
189
- end
190
- end
191
- end
192
-
193
- RBzip2::MAX_CODE_LEN.downto 1 do |i|
194
- base[i] = 0
195
- limit[i] = 0
196
- end
197
-
198
- alpha_size.times do |i|
199
- base[length[i] + 1] += 1
200
- end
201
-
202
- b = 0
203
- 1.upto(RBzip2::MAX_CODE_LEN - 1) do |i|
204
- b += base[i]
205
- base[i] = b
206
- end
207
-
208
- vec = 0
209
- min_len.upto(max_len) do |i|
210
- b = base[i]
211
- nb = base[i + 1]
212
- vec += nb - b
213
- b = nb
214
- limit[i] = vec -1
215
- vec = vec << 1
216
- end
217
-
218
- (min_len + 1).upto(max_len) do |i|
219
- base[i] = ((limit[i - 1] + 1) << 1) - base[i]
220
- end
221
- end
222
-
223
- def receive_decoding_tables
224
- in_use = @data.in_use
225
- pos = @data.receive_decoding_tables_pos
226
- selector = @data.selector
227
- selector_mtf = @data.selector_mtf
228
-
229
- in_use16 = 0
230
-
231
- 16.times do |i|
232
- in_use16 |= 1 << i if bit
233
- end
234
-
235
- 255.downto(0) do |i|
236
- in_use[i] = false
237
- end
238
-
239
- 16.times do |i|
240
- if (in_use16 & (1 << i)) != 0
241
- i16 = i << 4
242
- 16.times do |j|
243
- in_use[i16 + j] = true if bit
244
- end
245
- end
246
- end
247
-
248
- make_maps
249
- alpha_size = @n_in_use + 2
250
-
251
- groups = r 3
252
- selectors = r 15
253
-
254
- selectors.times do |i|
255
- j = 0
256
- while bit
257
- j += 1
258
- end
259
- selector_mtf[i] = j
260
- end
261
-
262
- groups.downto(0) do |v|
263
- pos[v] = v
264
- end
265
-
266
- selectors.times do |i|
267
- v = selector_mtf[i] & 0xff
268
- tmp = pos[v]
269
-
270
- while v > 0 do
271
- pos[v] = pos[v -= 1]
272
- end
273
-
274
- pos[0] = tmp
275
- selector[i] = tmp
276
- end
277
-
278
- len = @data.temp_char_array_2d
279
-
280
- groups.times do |t|
281
- curr = r 5
282
- len_t = len[t]
283
- alpha_size.times do |i|
284
- while bit
285
- curr += bit ? -1 : 1
286
- end
287
- len_t[i] = curr
288
- end
289
- @data.temp_char_array_2d[t] = len_t
290
- end
291
-
292
- create_huffman_decoding_tables alpha_size, groups
293
- end
294
-
295
- def create_huffman_decoding_tables(alpha_size, groups)
296
- len = @data.temp_char_array_2d
297
- min_lens = @data.min_lens
298
- limit = @data.limit
299
- base = @data.base
300
- perm = @data.perm
301
-
302
- groups.times do |t|
303
- min_len = 32
304
- max_len = 0
305
- len_t = len[t]
306
-
307
- (alpha_size - 1).downto 0 do |i|
308
- lent = len_t[i]
309
- max_len = lent if lent > max_len
310
- min_len = lent if lent < min_len
311
- end
312
-
313
- create_decode_tables limit[t], base[t], perm[t], len[t], min_len, max_len, alpha_size
314
- min_lens[t] = min_len
315
- end
316
- end
317
-
318
- def get_and_move_to_front_decode
319
- @orig_ptr = r 24
320
- receive_decoding_tables
321
-
322
- ll8 = @data.ll8
323
- unzftab = @data.unzftab
324
- selector = @data.selector
325
- seq_to_unseq = @data.seq_to_unseq
326
- yy = @data.get_and_move_to_front_decode_yy
327
- min_lens = @data.min_lens
328
- limit = @data.limit
329
- base = @data.base
330
- perm = @data.perm
331
- limit_last = @block_size * RBzip2::BASEBLOCKSIZE
332
-
333
- 256.downto(0) do |i|
334
- yy[i] = i
335
- unzftab[i] = 0
336
- end
337
-
338
- group_no = 0
339
- group_pos = RBzip2::G_SIZE - 1
340
- eob = @n_in_use + 1
341
- next_sym = get_and_move_to_front_decode0 0
342
- buff_shadow = @buff
343
- live_shadow = @live
344
- last_shadow = -1
345
- zt = selector[group_no] & 0xff
346
- base_zt = base[zt]
347
- limit_zt = limit[zt]
348
- perm_zt = perm[zt]
349
- min_lens_zt = min_lens[zt]
350
-
351
- while next_sym != eob
352
- if (next_sym == RBzip2::RUNA) || (next_sym == RBzip2::RUNB)
353
- s = -1
354
-
355
- n = 1
356
- loop do
357
- if next_sym == RBzip2::RUNA
358
- s += n
359
- elsif next_sym == RBzip2::RUNB
360
- s += n << 1
361
- else
362
- break
363
- end
364
-
365
- if group_pos == 0
366
- group_pos = RBzip2::G_SIZE - 1
367
- group_no += 1
368
- zt = selector[group_no] & 0xff
369
- base_zt = base[zt]
370
- limit_zt = limit[zt]
371
- perm_zt = perm[zt]
372
- min_lens_zt = min_lens[zt]
373
- else
374
- group_pos -= 1
375
- end
376
-
377
- zn = min_lens_zt
378
-
379
- while live_shadow < zn
380
- thech = @io.read(1)[0].ord
381
-
382
- raise 'unexpected end of stream' if thech < 0
383
-
384
- buff_shadow = (buff_shadow << 8) | thech
385
- live_shadow += 8
386
- end
387
-
388
- zvec = (buff_shadow >> (live_shadow - zn)) & ((1 << zn) - 1)
389
- live_shadow -= zn
390
-
391
- while zvec > limit_zt[zn]
392
- zn += 1
393
-
394
- while live_shadow < 1
395
- thech = @io.read(1)[0].ord
396
-
397
- raise 'unexpected end of stream' if thech < 0
398
-
399
- buff_shadow = (buff_shadow << 8) | thech
400
- live_shadow += 8
401
- end
402
-
403
- live_shadow -= 1
404
- zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
405
- end
406
-
407
- next_sym = perm_zt[zvec - base_zt[zn]]
408
-
409
- n = n << 1
410
- end
411
-
412
- ch = seq_to_unseq[yy[0]]
413
- unzftab[ch & 0xff] += s + 1
414
-
415
- while s >= 0
416
- last_shadow += 1
417
- ll8[last_shadow] = ch
418
- s -= 1
419
- end
420
-
421
- raise 'block overrun' if last_shadow >= limit_last
422
- else
423
- last_shadow += 1
424
- raise 'block overrun' if last_shadow >= limit_last
425
-
426
- tmp = yy[next_sym - 1]
427
- unzftab[seq_to_unseq[tmp] & 0xff] += 1
428
- ll8[last_shadow] = seq_to_unseq[tmp]
429
-
430
- yy[1, next_sym - 1] = yy[0, next_sym - 1]
431
- yy[0] = tmp
432
-
433
- if group_pos == 0
434
- group_pos = RBzip2::G_SIZE - 1
435
- group_no += 1
436
- zt = selector[group_no] & 0xff
437
- base_zt = base[zt]
438
- limit_zt = limit[zt]
439
- perm_zt = perm[zt]
440
- min_lens_zt = min_lens[zt]
441
- else
442
- group_pos -= 1
443
- end
444
-
445
- zn = min_lens_zt
446
-
447
- while live_shadow < zn
448
- thech = @io.read(1)[0].ord
449
-
450
- raise 'unexpected end of stream' if thech < 0
451
-
452
- buff_shadow = (buff_shadow << 8) | thech
453
- live_shadow += 8
454
- end
455
- zvec = (buff_shadow >> (live_shadow - zn)) & ((1 << zn) - 1)
456
- live_shadow -= zn
457
-
458
- while zvec > limit_zt[zn]
459
- zn += 1
460
- while live_shadow < 1
461
- thech = @io.read(1)[0].ord
462
-
463
- raise 'unexpected end of stream' if thech < 0
464
-
465
- buff_shadow = (buff_shadow << 8) | thech
466
- live_shadow += 8
467
- end
468
- live_shadow -= 1
469
- zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
470
- end
471
-
472
- next_sym = perm_zt[zvec - base_zt[zn]]
473
- end
474
- end
475
-
476
- @last = last_shadow
477
- @live = live_shadow
478
- @buff = buff_shadow
479
- end
480
-
481
- def get_and_move_to_front_decode0(group_no)
482
- zt = @data.selector[group_no] & 0xff
483
- limit_zt = @data.limit[zt]
484
- zn = @data.min_lens[zt]
485
- zvec = r zn
486
- live_shadow = @live
487
- buff_shadow = @buff
488
-
489
- while zvec > limit_zt[zn]
490
- zn += 1
491
-
492
- while live_shadow < 1
493
- thech = @io.read(1)[0].ord
494
-
495
- raise 'unexpected end of stream' if thech < 0
496
-
497
- buff_shadow = (buff_shadow << 8) | thech
498
- live_shadow += 8
499
- end
500
-
501
- live_shadow -=1
502
- zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
503
- end
504
-
505
- @live = live_shadow
506
- @buff = buff_shadow
507
-
508
- @data.perm[zt][zvec - @data.base[zt][zn]]
509
- end
510
-
511
- def setup_block
512
- return if @data.nil?
513
-
514
- cftab = @data.cftab
515
- tt = @data.init_tt @last + 1
516
- ll8 = @data.ll8
517
- cftab[0] = 0
518
- cftab[1, 256] = @data.unzftab[0, 256]
519
-
520
- c = cftab[0]
521
- 1.upto(256) do |i|
522
- c += cftab[i]
523
- cftab[i] = c
524
- end
525
-
526
- last_shadow = @last
527
- (last_shadow + 1).times do |i|
528
- cftab_i = ll8[i] & 0xff
529
- tt[cftab[cftab_i]] = i
530
- cftab[cftab_i] += 1
531
- end
532
-
533
- raise 'stream corrupted' if @orig_ptr < 0 || @orig_ptr >= tt.size
534
-
535
- @su_t_pos = tt[@orig_ptr]
536
- @su_count = 0
537
- @su_i2 = 0
538
- @su_ch2 = 256
539
-
540
- if @block_randomised
541
- @su_r_n_to_go = 0
542
- @su_r_t_pos = 0
543
-
544
- setup_rand_part_a
545
- else
546
- setup_no_rand_part_a
547
- end
548
- end
549
-
550
- def setup_rand_part_a
551
- if @su_i2 <= @last
552
- @su_ch_prev = @su_ch2
553
- su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
554
- @su_t_pos = @data.tt[@su_t_pos]
555
-
556
- if @su_r_n_to_go == 0
557
- @su_r_n_to_go = RBzip2::RNUMS[@su_r_t_pos] - 1
558
- @su_r_t_pos += 1
559
- @su_r_t_pos = 0 if @su_r_t_pos == 512
560
- else
561
- @su_r_n_to_go -= 1
562
- end
563
-
564
- @su_ch2 = su_ch2_shadow ^= (@su_r_n_to_go == 1) ? 1 : 0
565
- @su_i2 += 1
566
- @current_char = su_ch2_shadow
567
- @current_state = RBzip2::RAND_PART_B_STATE
568
- @crc.update_crc su_ch2_shadow
569
- else
570
- end_block
571
- init_block
572
- setup_block
573
- end
574
- end
575
-
576
- def setup_no_rand_part_a
577
- if @su_i2 <= @last
578
- @su_ch_prev = @su_ch2
579
- su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
580
- @su_ch2 = su_ch2_shadow
581
- @su_t_pos = @data.tt[@su_t_pos]
582
- @su_i2 += 1
583
- @current_char = su_ch2_shadow
584
- @current_state = RBzip2::NO_RAND_PART_B_STATE
585
- @crc.update_crc su_ch2_shadow
586
- else
587
- @current_state = RBzip2::NO_RAND_PART_A_STATE
588
- end_block
589
- init_block
590
- setup_block
591
- end
592
- end
593
-
594
- def setup_rand_part_b
595
- if @su_ch2 != @su_ch_prev
596
- @current_state = RBzip2::RAND_PART_A_STATE
597
- @su_count = 1
598
- setup_rand_part_a
599
- else
600
- @su_count += 1
601
- if @su_count >= 4
602
- @su_z = @data.ll8[@su_t_pos] & 0xff
603
- @su_t_pos = @data.tt[@su_t_pos]
604
-
605
- if @su_r_n_to_go == 0
606
- @su_r_n_to_go = RBzip2::RNUMS[@su_r_t_pos] - 1
607
- @su_r_t_pos += 1
608
- @su_r_t_pos = 0 if @su_r_t_pos == 512
609
- else
610
- @su_r_n_to_go -= 1
611
- end
612
-
613
- @su_j2 = 0
614
- @current_state = RBzip2::RAND_PART_C_STATE
615
- @su_z ^= 1 if @su_r_n_to_go == 1
616
- setup_rand_part_c
617
- else
618
- @current_state = RBzip2::RAND_PART_A_STATE
619
- setup_rand_part_a
620
- end
621
- end
622
- end
623
-
624
- def setup_rand_part_c
625
- if @su_j2 < @su_z
626
- @current_char = @su_ch2
627
- @crc.update_crc @su_ch2
628
- @su_j2 += 1
629
- else
630
- @current_state = RBzip2::RAND_PART_A_STATE
631
- @su_i2 += 1
632
- @su_count = 0
633
- setup_rand_part_a
634
- end
635
- end
636
-
637
- def setup_no_rand_part_b
638
- if @su_ch2 != @su_ch_prev
639
- @su_count = 1
640
- setup_no_rand_part_a
641
- else
642
- @su_count += 1
643
- if @su_count >= 4
644
- @su_z = @data.ll8[@su_t_pos] & 0xff
645
- @su_t_pos = @data.tt[@su_t_pos]
646
- @su_j2 = 0
647
- setup_no_rand_part_c
648
- else
649
- setup_no_rand_part_a
650
- end
651
- end
652
- end
653
-
654
- def setup_no_rand_part_c
655
- if @su_j2 < @su_z
656
- su_ch2_shadow = @su_ch2
657
- @current_char = su_ch2_shadow
658
- @crc.update_crc su_ch2_shadow
659
- @su_j2 += 1
660
- @current_state = RBzip2::NO_RAND_PART_C_STATE
661
- else
662
- @su_i2 += 1
663
- @su_count = 0
664
- setup_no_rand_part_a
665
- end
666
- end
667
-
668
- def size
669
- if @io.is_a? StringIO
670
- @io.size
671
- elsif @io.is_a? File
672
- @io.stat.size
673
- end
674
- end
675
-
676
- def uncompressed
677
- @last + 1
678
- end
679
-
680
- def inspect
681
- "#<#{self.class}: @io=#{@io.inspect} size=#{size} uncompressed=#{uncompressed}>"
682
- end
683
-
684
- end
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2011, Sebastian Staudt
5
+
6
+ require 'stringio'
7
+
8
+ class RBzip2::Decompressor
9
+
10
+ include RBzip2::Constants
11
+
12
+ def initialize(io)
13
+ @buff = 0
14
+ @bytes_read = 0
15
+ @computed_combined_crc = 0
16
+ @crc = RBzip2::CRC.new
17
+ @current_char = -1
18
+ @io = io
19
+ @live = 0
20
+ @stored_combined_crc = 0
21
+ @su_t_pos = 0
22
+ init
23
+ end
24
+
25
+ def count(read)
26
+ @bytes_read += read if read != -1
27
+ end
28
+
29
+ def read(length = nil)
30
+ raise 'stream closed' if @io.nil?
31
+
32
+ if length == 1
33
+ r = read0
34
+ count (r < 0 ? -1 : 1)
35
+ r
36
+ else
37
+ r = StringIO.new
38
+ if length == nil
39
+ loop do
40
+ b = read0
41
+ break if b < 0
42
+ r.write b.chr
43
+ end
44
+ elsif length > 0
45
+ length.times do
46
+ b = read0
47
+ break if b < 0
48
+ r.write b.chr
49
+ end
50
+ count r.size
51
+ end
52
+ r.string
53
+ end
54
+ end
55
+
56
+ def read0
57
+ ret_char = @current_char
58
+
59
+ case @current_state
60
+ when EOF
61
+ return -1
62
+
63
+ when RAND_PART_B_STATE
64
+ setup_rand_part_b
65
+
66
+ when RAND_PART_C_STATE
67
+ setup_rand_part_c
68
+
69
+ when NO_RAND_PART_B_STATE
70
+ setup_no_rand_part_b
71
+
72
+ when NO_RAND_PART_C_STATE
73
+ setup_no_rand_part_c
74
+
75
+ when START_BLOCK_STATE
76
+ when RAND_PART_A_STATE
77
+ when NO_RAND_PART_A_STATE
78
+ else
79
+ raise 'illegal state'
80
+ end
81
+
82
+ ret_char
83
+ end
84
+
85
+ def make_maps
86
+ in_use = @data.in_use
87
+ seq_to_unseq = @data.seq_to_unseq;
88
+
89
+ n_in_use_shadow = 0;
90
+
91
+ 256.times do |i|
92
+ if in_use[i]
93
+ seq_to_unseq[n_in_use_shadow] = i
94
+ n_in_use_shadow += 1
95
+ end
96
+ end
97
+
98
+ @n_in_use = n_in_use_shadow;
99
+ end
100
+
101
+ def init
102
+ check_magic
103
+
104
+ block_size = @io.read(1).to_i
105
+ raise 'Illegal block size.' if block_size < 1 || block_size > 9
106
+ @block_size = block_size
107
+
108
+ init_block
109
+ setup_block
110
+ end
111
+
112
+ def check_magic
113
+ raise 'Magic number does not match "BZh".' unless @io.read(3) == 'BZh'
114
+ end
115
+
116
+ def init_block
117
+ magic = [ubyte, ubyte, ubyte, ubyte, ubyte, ubyte]
118
+
119
+ if magic == [0x17, 0x72, 0x45, 0x38, 0x50, 0x90]
120
+ complete
121
+ elsif magic != [0x31, 0x41, 0x59, 0x26, 0x53, 0x59]
122
+ @current_state = EOF
123
+
124
+ raise 'Bad block header.'
125
+ else
126
+ @stored_block_crc = int
127
+ @block_randomised = bit
128
+
129
+ @data = RBzip2::InputData.new @block_size if @data.nil?
130
+
131
+ get_and_move_to_front_decode
132
+
133
+ @crc.initialize_crc
134
+ @current_state = START_BLOCK_STATE
135
+ end
136
+ end
137
+
138
+ def end_block
139
+ @computed_block_crc = @crc.final_crc
140
+
141
+ if @stored_block_crc != @computed_block_crc
142
+ @computed_combined_crc = (@stored_combined_crc << 1) | (@stored_combined_crc >> 31)
143
+ @computed_combined_crc ^= @stored_block_crc
144
+
145
+ raise 'BZip2 CRC error'
146
+ end
147
+
148
+ @computed_combined_crc = (@computed_combined_crc << 1) | (@computed_combined_crc >> 31)
149
+ @computed_combined_crc ^= @computed_block_crc
150
+ end
151
+
152
+ def complete
153
+ @stored_combined_crc = int
154
+ @current_state = EOF
155
+ @data = nil
156
+
157
+ raise 'BZip2 CRC error' if @stored_combined_crc != @computed_combined_crc
158
+ end
159
+
160
+ def close
161
+ if @io != $stdin
162
+ @io = nil
163
+ @data = nil
164
+ end
165
+ end
166
+
167
+ def r(n)
168
+ live_shadow = @live
169
+ buff_shadow = @buff
170
+
171
+ if live_shadow < n
172
+ begin
173
+ thech = @io.read(1)[0].ord
174
+
175
+ raise 'unexpected end of stream' if thech < 0
176
+
177
+ buff_shadow = (buff_shadow << 8) | thech
178
+ live_shadow += 8
179
+ end while live_shadow < n
180
+
181
+ @buff = buff_shadow
182
+ end
183
+
184
+ @live = live_shadow - n
185
+
186
+ (buff_shadow >> (live_shadow - n)) & ((1 << n) - 1)
187
+ end
188
+
189
+ def bit
190
+ r(1) != 0
191
+ end
192
+
193
+ def ubyte
194
+ r 8
195
+ end
196
+
197
+ def int
198
+ (((((r(8) << 8) | r(8)) << 8) | r(8)) << 8) | r(8)
199
+ end
200
+
201
+ def create_decode_tables(limit, base, perm, length, min_len, max_len, alpha_size)
202
+ pp = 0
203
+ (min_len..max_len).each do |i|
204
+ alpha_size.times do |j|
205
+ if length[j] == i
206
+ perm[pp] = j
207
+ pp += 1
208
+ end
209
+ end
210
+ end
211
+
212
+ MAX_CODE_LEN.downto 1 do |i|
213
+ base[i] = 0
214
+ limit[i] = 0
215
+ end
216
+
217
+ alpha_size.times do |i|
218
+ base[length[i] + 1] += 1
219
+ end
220
+
221
+ b = 0
222
+ 1.upto(MAX_CODE_LEN - 1) do |i|
223
+ b += base[i]
224
+ base[i] = b
225
+ end
226
+
227
+ vec = 0
228
+ min_len.upto(max_len) do |i|
229
+ b = base[i]
230
+ nb = base[i + 1]
231
+ vec += nb - b
232
+ b = nb
233
+ limit[i] = vec -1
234
+ vec = vec << 1
235
+ end
236
+
237
+ (min_len + 1).upto(max_len) do |i|
238
+ base[i] = ((limit[i - 1] + 1) << 1) - base[i]
239
+ end
240
+ end
241
+
242
+ def receive_decoding_tables
243
+ in_use = @data.in_use
244
+ pos = @data.receive_decoding_tables_pos
245
+ selector = @data.selector
246
+ selector_mtf = @data.selector_mtf
247
+
248
+ in_use16 = 0
249
+
250
+ 16.times do |i|
251
+ in_use16 |= 1 << i if bit
252
+ end
253
+
254
+ 255.downto(0) do |i|
255
+ in_use[i] = false
256
+ end
257
+
258
+ 16.times do |i|
259
+ if (in_use16 & (1 << i)) != 0
260
+ i16 = i << 4
261
+ 16.times do |j|
262
+ in_use[i16 + j] = true if bit
263
+ end
264
+ end
265
+ end
266
+
267
+ make_maps
268
+ alpha_size = @n_in_use + 2
269
+
270
+ groups = r 3
271
+ selectors = r 15
272
+
273
+ selectors.times do |i|
274
+ j = 0
275
+ while bit
276
+ j += 1
277
+ end
278
+ selector_mtf[i] = j
279
+ end
280
+
281
+ groups.downto(0) do |v|
282
+ pos[v] = v
283
+ end
284
+
285
+ selectors.times do |i|
286
+ v = selector_mtf[i] & 0xff
287
+ tmp = pos[v]
288
+
289
+ while v > 0 do
290
+ pos[v] = pos[v -= 1]
291
+ end
292
+
293
+ pos[0] = tmp
294
+ selector[i] = tmp
295
+ end
296
+
297
+ len = @data.temp_char_array_2d
298
+
299
+ groups.times do |t|
300
+ curr = r 5
301
+ len_t = len[t]
302
+ alpha_size.times do |i|
303
+ while bit
304
+ curr += bit ? -1 : 1
305
+ end
306
+ len_t[i] = curr
307
+ end
308
+ @data.temp_char_array_2d[t] = len_t
309
+ end
310
+
311
+ create_huffman_decoding_tables alpha_size, groups
312
+ end
313
+
314
+ def create_huffman_decoding_tables(alpha_size, groups)
315
+ len = @data.temp_char_array_2d
316
+ min_lens = @data.min_lens
317
+ limit = @data.limit
318
+ base = @data.base
319
+ perm = @data.perm
320
+
321
+ groups.times do |t|
322
+ min_len = 32
323
+ max_len = 0
324
+ len_t = len[t]
325
+
326
+ (alpha_size - 1).downto 0 do |i|
327
+ lent = len_t[i]
328
+ max_len = lent if lent > max_len
329
+ min_len = lent if lent < min_len
330
+ end
331
+
332
+ create_decode_tables limit[t], base[t], perm[t], len[t], min_len, max_len, alpha_size
333
+ min_lens[t] = min_len
334
+ end
335
+ end
336
+
337
+ def get_and_move_to_front_decode
338
+ @orig_ptr = r 24
339
+ receive_decoding_tables
340
+
341
+ ll8 = @data.ll8
342
+ unzftab = @data.unzftab
343
+ selector = @data.selector
344
+ seq_to_unseq = @data.seq_to_unseq
345
+ yy = @data.get_and_move_to_front_decode_yy
346
+ min_lens = @data.min_lens
347
+ limit = @data.limit
348
+ base = @data.base
349
+ perm = @data.perm
350
+ limit_last = @block_size * BASEBLOCKSIZE
351
+
352
+ 256.downto(0) do |i|
353
+ yy[i] = i
354
+ unzftab[i] = 0
355
+ end
356
+
357
+ group_no = 0
358
+ group_pos = G_SIZE - 1
359
+ eob = @n_in_use + 1
360
+ next_sym = get_and_move_to_front_decode0 0
361
+ buff_shadow = @buff
362
+ live_shadow = @live
363
+ last_shadow = -1
364
+ zt = selector[group_no] & 0xff
365
+ base_zt = base[zt]
366
+ limit_zt = limit[zt]
367
+ perm_zt = perm[zt]
368
+ min_lens_zt = min_lens[zt]
369
+
370
+ while next_sym != eob
371
+ if (next_sym == RUNA) || (next_sym == RUNB)
372
+ s = -1
373
+
374
+ n = 1
375
+ loop do
376
+ if next_sym == RUNA
377
+ s += n
378
+ elsif next_sym == RUNB
379
+ s += n << 1
380
+ else
381
+ break
382
+ end
383
+
384
+ if group_pos == 0
385
+ group_pos = G_SIZE - 1
386
+ group_no += 1
387
+ zt = selector[group_no] & 0xff
388
+ base_zt = base[zt]
389
+ limit_zt = limit[zt]
390
+ perm_zt = perm[zt]
391
+ min_lens_zt = min_lens[zt]
392
+ else
393
+ group_pos -= 1
394
+ end
395
+
396
+ zn = min_lens_zt
397
+
398
+ while live_shadow < zn
399
+ thech = @io.read(1)[0].ord
400
+
401
+ raise 'unexpected end of stream' if thech < 0
402
+
403
+ buff_shadow = (buff_shadow << 8) | thech
404
+ live_shadow += 8
405
+ end
406
+
407
+ zvec = (buff_shadow >> (live_shadow - zn)) & ((1 << zn) - 1)
408
+ live_shadow -= zn
409
+
410
+ while zvec > limit_zt[zn]
411
+ zn += 1
412
+
413
+ while live_shadow < 1
414
+ thech = @io.read(1)[0].ord
415
+
416
+ raise 'unexpected end of stream' if thech < 0
417
+
418
+ buff_shadow = (buff_shadow << 8) | thech
419
+ live_shadow += 8
420
+ end
421
+
422
+ live_shadow -= 1
423
+ zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
424
+ end
425
+
426
+ next_sym = perm_zt[zvec - base_zt[zn]]
427
+
428
+ n = n << 1
429
+ end
430
+
431
+ ch = seq_to_unseq[yy[0]]
432
+ unzftab[ch & 0xff] += s + 1
433
+
434
+ while s >= 0
435
+ last_shadow += 1
436
+ ll8[last_shadow] = ch
437
+ s -= 1
438
+ end
439
+
440
+ raise 'block overrun' if last_shadow >= limit_last
441
+ else
442
+ last_shadow += 1
443
+ raise 'block overrun' if last_shadow >= limit_last
444
+
445
+ tmp = yy[next_sym - 1]
446
+ unzftab[seq_to_unseq[tmp] & 0xff] += 1
447
+ ll8[last_shadow] = seq_to_unseq[tmp]
448
+
449
+ yy[1, next_sym - 1] = yy[0, next_sym - 1]
450
+ yy[0] = tmp
451
+
452
+ if group_pos == 0
453
+ group_pos = G_SIZE - 1
454
+ group_no += 1
455
+ zt = selector[group_no] & 0xff
456
+ base_zt = base[zt]
457
+ limit_zt = limit[zt]
458
+ perm_zt = perm[zt]
459
+ min_lens_zt = min_lens[zt]
460
+ else
461
+ group_pos -= 1
462
+ end
463
+
464
+ zn = min_lens_zt
465
+
466
+ while live_shadow < zn
467
+ thech = @io.read(1)[0].ord
468
+
469
+ raise 'unexpected end of stream' if thech < 0
470
+
471
+ buff_shadow = (buff_shadow << 8) | thech
472
+ live_shadow += 8
473
+ end
474
+ zvec = (buff_shadow >> (live_shadow - zn)) & ((1 << zn) - 1)
475
+ live_shadow -= zn
476
+
477
+ while zvec > limit_zt[zn]
478
+ zn += 1
479
+ while live_shadow < 1
480
+ thech = @io.read(1)[0].ord
481
+
482
+ raise 'unexpected end of stream' if thech < 0
483
+
484
+ buff_shadow = (buff_shadow << 8) | thech
485
+ live_shadow += 8
486
+ end
487
+ live_shadow -= 1
488
+ zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
489
+ end
490
+
491
+ next_sym = perm_zt[zvec - base_zt[zn]]
492
+ end
493
+ end
494
+
495
+ @last = last_shadow
496
+ @live = live_shadow
497
+ @buff = buff_shadow
498
+ end
499
+
500
+ def get_and_move_to_front_decode0(group_no)
501
+ zt = @data.selector[group_no] & 0xff
502
+ limit_zt = @data.limit[zt]
503
+ zn = @data.min_lens[zt]
504
+ zvec = r zn
505
+ live_shadow = @live
506
+ buff_shadow = @buff
507
+
508
+ while zvec > limit_zt[zn]
509
+ zn += 1
510
+
511
+ while live_shadow < 1
512
+ thech = @io.read(1)[0].ord
513
+
514
+ raise 'unexpected end of stream' if thech < 0
515
+
516
+ buff_shadow = (buff_shadow << 8) | thech
517
+ live_shadow += 8
518
+ end
519
+
520
+ live_shadow -=1
521
+ zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
522
+ end
523
+
524
+ @live = live_shadow
525
+ @buff = buff_shadow
526
+
527
+ @data.perm[zt][zvec - @data.base[zt][zn]]
528
+ end
529
+
530
+ def setup_block
531
+ return if @data.nil?
532
+
533
+ cftab = @data.cftab
534
+ tt = @data.init_tt @last + 1
535
+ ll8 = @data.ll8
536
+ cftab[0] = 0
537
+ cftab[1, 256] = @data.unzftab[0, 256]
538
+
539
+ c = cftab[0]
540
+ 1.upto(256) do |i|
541
+ c += cftab[i]
542
+ cftab[i] = c
543
+ end
544
+
545
+ last_shadow = @last
546
+ (last_shadow + 1).times do |i|
547
+ cftab_i = ll8[i] & 0xff
548
+ tt[cftab[cftab_i]] = i
549
+ cftab[cftab_i] += 1
550
+ end
551
+
552
+ raise 'stream corrupted' if @orig_ptr < 0 || @orig_ptr >= tt.size
553
+
554
+ @su_t_pos = tt[@orig_ptr]
555
+ @su_count = 0
556
+ @su_i2 = 0
557
+ @su_ch2 = 256
558
+
559
+ if @block_randomised
560
+ @su_r_n_to_go = 0
561
+ @su_r_t_pos = 0
562
+
563
+ setup_rand_part_a
564
+ else
565
+ setup_no_rand_part_a
566
+ end
567
+ end
568
+
569
+ def setup_rand_part_a
570
+ if @su_i2 <= @last
571
+ @su_ch_prev = @su_ch2
572
+ su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
573
+ @su_t_pos = @data.tt[@su_t_pos]
574
+
575
+ if @su_r_n_to_go == 0
576
+ @su_r_n_to_go = RNUMS[@su_r_t_pos] - 1
577
+ @su_r_t_pos += 1
578
+ @su_r_t_pos = 0 if @su_r_t_pos == 512
579
+ else
580
+ @su_r_n_to_go -= 1
581
+ end
582
+
583
+ @su_ch2 = su_ch2_shadow ^= (@su_r_n_to_go == 1) ? 1 : 0
584
+ @su_i2 += 1
585
+ @current_char = su_ch2_shadow
586
+ @current_state = RAND_PART_B_STATE
587
+ @crc.update_crc su_ch2_shadow
588
+ else
589
+ end_block
590
+ init_block
591
+ setup_block
592
+ end
593
+ end
594
+
595
+ def setup_no_rand_part_a
596
+ if @su_i2 <= @last
597
+ @su_ch_prev = @su_ch2
598
+ su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
599
+ @su_ch2 = su_ch2_shadow
600
+ @su_t_pos = @data.tt[@su_t_pos]
601
+ @su_i2 += 1
602
+ @current_char = su_ch2_shadow
603
+ @current_state = NO_RAND_PART_B_STATE
604
+ @crc.update_crc su_ch2_shadow
605
+ else
606
+ @current_state = NO_RAND_PART_A_STATE
607
+ end_block
608
+ init_block
609
+ setup_block
610
+ end
611
+ end
612
+
613
+ def setup_rand_part_b
614
+ if @su_ch2 != @su_ch_prev
615
+ @current_state = RAND_PART_A_STATE
616
+ @su_count = 1
617
+ setup_rand_part_a
618
+ else
619
+ @su_count += 1
620
+ if @su_count >= 4
621
+ @su_z = @data.ll8[@su_t_pos] & 0xff
622
+ @su_t_pos = @data.tt[@su_t_pos]
623
+
624
+ if @su_r_n_to_go == 0
625
+ @su_r_n_to_go = RNUMS[@su_r_t_pos] - 1
626
+ @su_r_t_pos += 1
627
+ @su_r_t_pos = 0 if @su_r_t_pos == 512
628
+ else
629
+ @su_r_n_to_go -= 1
630
+ end
631
+
632
+ @su_j2 = 0
633
+ @current_state = RAND_PART_C_STATE
634
+ @su_z ^= 1 if @su_r_n_to_go == 1
635
+ setup_rand_part_c
636
+ else
637
+ @current_state = RAND_PART_A_STATE
638
+ setup_rand_part_a
639
+ end
640
+ end
641
+ end
642
+
643
+ def setup_rand_part_c
644
+ if @su_j2 < @su_z
645
+ @current_char = @su_ch2
646
+ @crc.update_crc @su_ch2
647
+ @su_j2 += 1
648
+ else
649
+ @current_state = RAND_PART_A_STATE
650
+ @su_i2 += 1
651
+ @su_count = 0
652
+ setup_rand_part_a
653
+ end
654
+ end
655
+
656
+ def setup_no_rand_part_b
657
+ if @su_ch2 != @su_ch_prev
658
+ @su_count = 1
659
+ setup_no_rand_part_a
660
+ else
661
+ @su_count += 1
662
+ if @su_count >= 4
663
+ @su_z = @data.ll8[@su_t_pos] & 0xff
664
+ @su_t_pos = @data.tt[@su_t_pos]
665
+ @su_j2 = 0
666
+ setup_no_rand_part_c
667
+ else
668
+ setup_no_rand_part_a
669
+ end
670
+ end
671
+ end
672
+
673
+ def setup_no_rand_part_c
674
+ if @su_j2 < @su_z
675
+ su_ch2_shadow = @su_ch2
676
+ @current_char = su_ch2_shadow
677
+ @crc.update_crc su_ch2_shadow
678
+ @su_j2 += 1
679
+ @current_state = NO_RAND_PART_C_STATE
680
+ else
681
+ @su_i2 += 1
682
+ @su_count = 0
683
+ setup_no_rand_part_a
684
+ end
685
+ end
686
+
687
+ def size
688
+ if @io.is_a? StringIO
689
+ @io.size
690
+ elsif @io.is_a? File
691
+ @io.stat.size
692
+ end
693
+ end
694
+
695
+ def uncompressed
696
+ @last + 1
697
+ end
698
+
699
+ def inspect
700
+ "#<#{self.class}: @io=#{@io.inspect} size=#{size} uncompressed=#{uncompressed}>"
701
+ end
702
+
703
+ end