poise-archive 1.0.0 → 1.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +2 -0
- data/README.md +3 -0
- data/lib/poise_archive/archive_providers/tar.rb +76 -70
- data/lib/poise_archive/bzip2.rb +16 -0
- data/lib/poise_archive/bzip2/LICENSE +25 -0
- data/lib/poise_archive/bzip2/constants.rb +83 -0
- data/lib/poise_archive/bzip2/crc.rb +73 -0
- data/lib/poise_archive/bzip2/decompressor.rb +704 -0
- data/lib/poise_archive/bzip2/input_data.rb +43 -0
- data/lib/poise_archive/bzip2/output_data.rb +57 -0
- data/lib/poise_archive/version.rb +1 -1
- data/test/spec/archive_providers/tar_spec.rb +44 -89
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed1a6f15b6ab1ebc7f37e710fb97e3eb57875c24
|
4
|
+
data.tar.gz: 72373e0a9bc17188f4d551c5c682b271e4d3f0c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b40e2e071adb5e3bf1141ce6a28b06ac6ac18949c2f59eb7c3a0435dd55b8447eb98e6a3655d013be2725bda178cde72c0ab59144788e409a3ddb9ee982275b9
|
7
|
+
data.tar.gz: 896dd2cc1d7344aebd8b10709522168ad57f5d385a4e8268772b4641a0f6293765f26e175cc5aa5de7332664fc89674f47b899e851a76d1f1beccdae798917db
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -77,3 +77,6 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
|
77
77
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
78
78
|
See the License for the specific language governing permissions and
|
79
79
|
limitations under the License.
|
80
|
+
|
81
|
+
BZip2 implementation is based on RBzip2. Copyright Sebastian Staudt, Brian Lopez.
|
82
|
+
RBzip2 code used under the terms of the new BSD license.
|
@@ -15,105 +15,111 @@
|
|
15
15
|
#
|
16
16
|
|
17
17
|
require 'fileutils'
|
18
|
-
require '
|
18
|
+
require 'rubygems/package'
|
19
|
+
require 'zlib'
|
19
20
|
|
20
21
|
require 'poise_archive/archive_providers/base'
|
22
|
+
require 'poise_archive/bzip2'
|
21
23
|
|
22
24
|
|
23
25
|
module PoiseArchive
|
24
26
|
module ArchiveProviders
|
25
|
-
# The `tar` provider class for `poise_archive` to install from
|
27
|
+
# The `tar` provider class for `poise_archive` to install from tar archives.
|
26
28
|
#
|
27
29
|
# @see PoiseArchive::Resources::PoiseArchive::Resource
|
28
30
|
# @provides poise_archive
|
29
31
|
class Tar < Base
|
30
|
-
provides_extension(/\.t(ar|gz|bz
|
32
|
+
provides_extension(/\.t(ar|gz|bz)/)
|
33
|
+
|
34
|
+
# Hack that GNU tar uses for paths over 100 bytes.
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
# @see #unpack_tar
|
38
|
+
TAR_LONGLINK = '././@LongLink'
|
31
39
|
|
32
40
|
private
|
33
41
|
|
34
42
|
def unpack_archive
|
35
|
-
notifying_block do
|
36
|
-
install_prereqs
|
37
|
-
end
|
38
43
|
unpack_tar
|
39
44
|
end
|
40
45
|
|
41
|
-
#
|
46
|
+
# Unpack the archive.
|
42
47
|
#
|
43
48
|
# @return [void]
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
49
|
+
def unpack_tar
|
50
|
+
tar_each do |entry|
|
51
|
+
entry_name = if entry.full_name == TAR_LONGLINK
|
52
|
+
entry.read.strip
|
53
|
+
else
|
54
|
+
entry.full_name
|
55
|
+
end.split(/\//).drop(new_resource.strip_components).join('/')
|
56
|
+
next if entry_name.empty?
|
57
|
+
dest = ::File.join(new_resource.destination, entry_name)
|
58
|
+
if entry.directory?
|
59
|
+
Dir.mkdir(dest, entry.header.mode)
|
60
|
+
elsif entry.file?
|
61
|
+
::File.open(dest, 'wb', entry.header.mode) do |dest_f|
|
62
|
+
while buf = entry.read(4096)
|
63
|
+
dest_f.write(buf)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
elsif entry.symlink?
|
67
|
+
::File.symlink(entry.header.linkname, dest)
|
68
|
+
else
|
69
|
+
raise RuntimeError.new("Unknown tar entry type #{entry.header.typeflag.inspect} in #{new_resource.path}")
|
70
|
+
end
|
71
|
+
FileUtils.chown(new_resource.user, new_resource.group, dest)
|
72
|
+
end
|
54
73
|
end
|
55
74
|
|
56
|
-
#
|
75
|
+
# Sequence the opening, iteration, and closing.
|
57
76
|
#
|
77
|
+
# @param block [Proc] Block to process each tar entry.
|
58
78
|
# @return [void]
|
59
|
-
def
|
60
|
-
#
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
'-xjvf'
|
67
|
-
elsif new_resource.path =~ /\.t?xz/
|
68
|
-
'-xJvf'
|
69
|
-
else
|
70
|
-
'-xvf'
|
71
|
-
end
|
72
|
-
cmd << new_resource.path
|
73
|
-
|
74
|
-
# Create a temp directory to unpack in to. Do I want to try and force
|
75
|
-
# this to be on the same filesystem as the target?
|
76
|
-
self.class.mktmpdir do |dir|
|
77
|
-
# Change the temp dir to be owned by the unpack user if needed.
|
78
|
-
FileUtils.chown(new_resource.user, new_resource.group, dir) if new_resource.user || new_resource.group
|
79
|
-
|
80
|
-
# Run the unpack into the temp dir.
|
81
|
-
poise_shell_out!(cmd, cwd: dir, group: new_resource.group, user: new_resource.user)
|
82
|
-
|
83
|
-
# Re-implementation of the logic for tar --strip-components because
|
84
|
-
# that option isn't part of non-GNU tar (read: Solaris and AIX).
|
85
|
-
entries_at_depth(dir, new_resource.strip_components).each do |source|
|
86
|
-
# At some point this might need to fall back to a real copy.
|
87
|
-
::File.rename(source, ::File.join(new_resource.absolute_destination, ::File.basename(source)))
|
88
|
-
end
|
89
|
-
end
|
79
|
+
def tar_each(&block)
|
80
|
+
# In case of extreme weirdness where this happens twice.
|
81
|
+
close_file!
|
82
|
+
open_file!
|
83
|
+
@tar_reader.each(&block)
|
84
|
+
ensure
|
85
|
+
close_file!
|
90
86
|
end
|
91
87
|
|
92
|
-
#
|
88
|
+
# Open a file handle of the correct flavor.
|
93
89
|
#
|
94
|
-
# @
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
108
|
-
entries.flatten!
|
109
|
-
current_depth += 1
|
90
|
+
# @return [void]
|
91
|
+
def open_file!
|
92
|
+
@raw_file = ::File.open(new_resource.path, 'rb')
|
93
|
+
@file = case new_resource.path
|
94
|
+
when /\.tar$/
|
95
|
+
nil # So it uses @raw_file instead.
|
96
|
+
when /\.t?gz/
|
97
|
+
Zlib::GzipReader.wrap(@raw_file)
|
98
|
+
when /\.t?bz/
|
99
|
+
# This can't take a block, hence the gross non-block forms for everything.
|
100
|
+
PoiseArchive::Bzip2::Decompressor.new(@raw_file)
|
101
|
+
else
|
102
|
+
raise RuntimeError.new("Unknown or unsupported file extension for #{new_resource.path}")
|
110
103
|
end
|
111
|
-
|
104
|
+
@tar_reader = Gem::Package::TarReader.new(@file || @raw_file)
|
112
105
|
end
|
113
106
|
|
114
|
-
#
|
115
|
-
|
116
|
-
|
107
|
+
# Close all the various file handles.
|
108
|
+
#
|
109
|
+
# @return [void]
|
110
|
+
def close_file!
|
111
|
+
if @tar_reader
|
112
|
+
@tar_reader.close
|
113
|
+
@tar_reader = nil
|
114
|
+
end
|
115
|
+
if @file
|
116
|
+
@file.close
|
117
|
+
@file = nil
|
118
|
+
end
|
119
|
+
if @raw_file
|
120
|
+
@raw_file.close unless @raw_file.closed?
|
121
|
+
@raw_file = nil
|
122
|
+
end
|
117
123
|
end
|
118
124
|
|
119
125
|
end
|
@@ -0,0 +1,16 @@
|
|
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) 2013, Sebastian Staudt
|
5
|
+
|
6
|
+
|
7
|
+
module PoiseArchive::Bzip2
|
8
|
+
|
9
|
+
autoload :CRC, 'poise_archive/bzip2/crc'
|
10
|
+
autoload :Constants, 'poise_archive/bzip2/constants'
|
11
|
+
autoload :Decompressor, 'poise_archive/bzip2/decompressor'
|
12
|
+
autoload :IO, 'poise_archive/bzip2/io'
|
13
|
+
autoload :InputData, 'poise_archive/bzip2/input_data'
|
14
|
+
autoload :OutputData, 'poise_archive/bzip2/output_data'
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Copyright (c) 2011, Sebastian Staudt
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
* Redistributions of source code must retain the above copyright notice,
|
8
|
+
this list of conditions and the following disclaimer.
|
9
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
11
|
+
and/or other materials provided with the distribution.
|
12
|
+
* Neither the name of the author nor the names of its contributors
|
13
|
+
may be used to endorse or promote products derived from this software
|
14
|
+
without specific prior written permission.
|
15
|
+
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
17
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
20
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
21
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
22
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
23
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
24
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
25
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,83 @@
|
|
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-2013, Sebastian Staudt
|
5
|
+
|
6
|
+
|
7
|
+
module PoiseArchive::Bzip2::Constants
|
8
|
+
|
9
|
+
BASEBLOCKSIZE = 100000
|
10
|
+
MAX_ALPHA_SIZE = 258
|
11
|
+
MAX_CODE_LEN = 23
|
12
|
+
RUNA = 0
|
13
|
+
RUNB = 1
|
14
|
+
N_GROUPS = 6
|
15
|
+
G_SIZE = 50
|
16
|
+
N_ITERS = 4
|
17
|
+
MAX_SELECTORS = (2 + (900000 / G_SIZE))
|
18
|
+
NUM_OVERSHOOT_BYTES = 20
|
19
|
+
|
20
|
+
EOF = 0
|
21
|
+
START_BLOCK_STATE = 1
|
22
|
+
RAND_PART_A_STATE = 2
|
23
|
+
RAND_PART_B_STATE = 3
|
24
|
+
RAND_PART_C_STATE = 4
|
25
|
+
NO_RAND_PART_A_STATE = 5
|
26
|
+
NO_RAND_PART_B_STATE = 6
|
27
|
+
NO_RAND_PART_C_STATE = 7
|
28
|
+
|
29
|
+
RNUMS = [
|
30
|
+
619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863,
|
31
|
+
491, 741, 242, 949, 214, 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
|
32
|
+
419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 878, 465, 811, 169, 869,
|
33
|
+
675, 611, 697, 867, 561, 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
|
34
|
+
150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 170, 607, 520, 932, 727,
|
35
|
+
476, 693, 425, 174, 647, 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
|
36
|
+
909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 641, 801, 220, 162, 819,
|
37
|
+
984, 589, 513, 495, 799, 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
|
38
|
+
382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 98, 553, 163, 354, 666,
|
39
|
+
933, 424, 341, 533, 870, 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
|
40
|
+
469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 184, 943, 795, 384, 383,
|
41
|
+
461, 404, 758, 839, 887, 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
|
42
|
+
951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 652, 934, 970, 447, 318,
|
43
|
+
353, 859, 672, 112, 785, 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
|
44
|
+
609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 653, 282, 762, 623, 680,
|
45
|
+
81, 927, 626, 789, 125, 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
|
46
|
+
170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 857, 956, 358, 619, 580,
|
47
|
+
124, 737, 594, 701, 612, 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
|
48
|
+
944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 344, 805, 988, 739, 511,
|
49
|
+
655, 814, 334, 249, 515, 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
|
50
|
+
433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 686, 754, 806, 760, 493,
|
51
|
+
403, 415, 394, 687, 700, 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
|
52
|
+
978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 680, 879, 194, 572, 640,
|
53
|
+
724, 926, 56, 204, 700, 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
|
54
|
+
297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 134, 108, 571, 364, 631,
|
55
|
+
212, 174, 643, 304, 329, 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
|
56
|
+
140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 170, 514, 364, 692, 829,
|
57
|
+
82, 855, 953, 676, 246, 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
|
58
|
+
804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 896, 831, 547, 261, 524,
|
59
|
+
462, 293, 465, 502, 56, 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
|
60
|
+
768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 61, 688, 793, 644, 986,
|
61
|
+
403, 106, 366, 905, 644, 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
|
62
|
+
780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 920, 176, 193, 713, 857,
|
63
|
+
265, 203, 50, 668, 108, 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
|
64
|
+
936, 638
|
65
|
+
]
|
66
|
+
|
67
|
+
MIN_BLOCK_SIZE = 1
|
68
|
+
MAX_BLOCK_SIZE = 9
|
69
|
+
SETMASK = (1 << 21)
|
70
|
+
CLEARMASK = (~SETMASK)
|
71
|
+
GREATER_ICOST = 15
|
72
|
+
LESSER_ICOST = 0
|
73
|
+
SMALL_THRESH = 20
|
74
|
+
DEPTH_THRESH = 10
|
75
|
+
WORK_FACTOR = 30
|
76
|
+
QSORT_STACK_SIZE = 1000
|
77
|
+
|
78
|
+
INCS = [
|
79
|
+
1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161,
|
80
|
+
2391484
|
81
|
+
]
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,73 @@
|
|
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-2013, Sebastian Staudt
|
5
|
+
|
6
|
+
|
7
|
+
class PoiseArchive::Bzip2::CRC
|
8
|
+
|
9
|
+
CRC32_TABLE = [
|
10
|
+
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
11
|
+
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
|
12
|
+
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
|
13
|
+
0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
|
14
|
+
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
|
15
|
+
0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
16
|
+
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
|
17
|
+
0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
|
18
|
+
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
|
19
|
+
0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
|
20
|
+
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
|
21
|
+
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
|
22
|
+
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
|
23
|
+
0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
|
24
|
+
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
|
25
|
+
0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
26
|
+
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
|
27
|
+
0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
|
28
|
+
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
|
29
|
+
0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
|
30
|
+
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
|
31
|
+
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
|
32
|
+
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
|
33
|
+
0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
|
34
|
+
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
|
35
|
+
0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
36
|
+
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
|
37
|
+
0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
|
38
|
+
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
|
39
|
+
0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
|
40
|
+
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
|
41
|
+
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
|
42
|
+
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
|
43
|
+
0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
|
44
|
+
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
|
45
|
+
0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
46
|
+
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
|
47
|
+
0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
|
48
|
+
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
|
49
|
+
0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
|
50
|
+
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
|
51
|
+
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
|
52
|
+
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
53
|
+
]
|
54
|
+
|
55
|
+
attr_accessor :global_crc
|
56
|
+
|
57
|
+
def initialize
|
58
|
+
initialize_crc
|
59
|
+
end
|
60
|
+
|
61
|
+
def initialize_crc
|
62
|
+
@global_crc = 0xffffffff
|
63
|
+
end
|
64
|
+
|
65
|
+
def final_crc
|
66
|
+
@global_crc ^ 0xffffffff
|
67
|
+
end
|
68
|
+
|
69
|
+
def update_crc(in_ch)
|
70
|
+
@global_crc = ((@global_crc << 8) & 0xffffffff) ^ CRC32_TABLE[(@global_crc >> 24) ^ in_ch]
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,704 @@
|
|
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-2013, Sebastian Staudt
|
5
|
+
|
6
|
+
|
7
|
+
class PoiseArchive::Bzip2::Decompressor
|
8
|
+
|
9
|
+
include PoiseArchive::Bzip2::Constants
|
10
|
+
|
11
|
+
def initialize(io)
|
12
|
+
@buff = 0
|
13
|
+
@bytes_read = 0
|
14
|
+
@computed_combined_crc = 0
|
15
|
+
@crc = PoiseArchive::Bzip2::CRC.new
|
16
|
+
@current_char = -1
|
17
|
+
@io = io
|
18
|
+
@live = 0
|
19
|
+
@stored_combined_crc = 0
|
20
|
+
@su_t_pos = 0
|
21
|
+
init
|
22
|
+
end
|
23
|
+
|
24
|
+
def count(read)
|
25
|
+
@bytes_read += read if read != -1
|
26
|
+
end
|
27
|
+
|
28
|
+
# ADDED METHODS
|
29
|
+
def pos
|
30
|
+
@bytes_read
|
31
|
+
end
|
32
|
+
|
33
|
+
def eof?
|
34
|
+
@current_state == EOF
|
35
|
+
end
|
36
|
+
# /ADDED METHODS
|
37
|
+
|
38
|
+
def read(length = nil)
|
39
|
+
raise 'stream closed' if @io.nil?
|
40
|
+
|
41
|
+
if length == 1
|
42
|
+
r = read0
|
43
|
+
count (r < 0 ? -1 : 1)
|
44
|
+
r
|
45
|
+
else
|
46
|
+
r = ''
|
47
|
+
if length == nil
|
48
|
+
while true do
|
49
|
+
b = read0
|
50
|
+
break if b < 0
|
51
|
+
r << b.chr
|
52
|
+
end
|
53
|
+
count r.size # ADDED LINE
|
54
|
+
elsif length > 0
|
55
|
+
length.times do
|
56
|
+
b = read0
|
57
|
+
break if b < 0
|
58
|
+
r << b.chr
|
59
|
+
end
|
60
|
+
count r.size
|
61
|
+
end
|
62
|
+
r
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def read0
|
67
|
+
ret_char = @current_char
|
68
|
+
|
69
|
+
if @current_state == RAND_PART_B_STATE
|
70
|
+
setup_rand_part_b
|
71
|
+
elsif @current_state == NO_RAND_PART_B_STATE
|
72
|
+
setup_no_rand_part_b
|
73
|
+
elsif @current_state == RAND_PART_C_STATE
|
74
|
+
setup_rand_part_c
|
75
|
+
elsif @current_state == NO_RAND_PART_C_STATE
|
76
|
+
setup_no_rand_part_c
|
77
|
+
elsif @current_state == EOF
|
78
|
+
return -1
|
79
|
+
else
|
80
|
+
raise 'illegal state'
|
81
|
+
end
|
82
|
+
|
83
|
+
ret_char
|
84
|
+
end
|
85
|
+
|
86
|
+
def make_maps
|
87
|
+
in_use = @data.in_use
|
88
|
+
seq_to_unseq = @data.seq_to_unseq
|
89
|
+
|
90
|
+
n_in_use_shadow = 0
|
91
|
+
|
92
|
+
256.times do |i|
|
93
|
+
if in_use[i]
|
94
|
+
seq_to_unseq[n_in_use_shadow] = i
|
95
|
+
n_in_use_shadow += 1
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
@n_in_use = n_in_use_shadow
|
100
|
+
end
|
101
|
+
|
102
|
+
def init
|
103
|
+
check_magic
|
104
|
+
|
105
|
+
block_size = @io.read(1).to_i
|
106
|
+
raise 'Illegal block size.' if block_size < 1 || block_size > 9
|
107
|
+
@block_size = block_size
|
108
|
+
|
109
|
+
init_block
|
110
|
+
setup_block
|
111
|
+
end
|
112
|
+
|
113
|
+
def check_magic
|
114
|
+
raise 'Magic number does not match "BZh".' unless @io.read(3) == 'BZh'
|
115
|
+
end
|
116
|
+
|
117
|
+
def init_block
|
118
|
+
magic = [ubyte, ubyte, ubyte, ubyte, ubyte, ubyte]
|
119
|
+
|
120
|
+
if magic == [0x17, 0x72, 0x45, 0x38, 0x50, 0x90]
|
121
|
+
complete
|
122
|
+
elsif magic != [0x31, 0x41, 0x59, 0x26, 0x53, 0x59]
|
123
|
+
@current_state = EOF
|
124
|
+
|
125
|
+
raise 'Bad block header.'
|
126
|
+
else
|
127
|
+
@stored_block_crc = int
|
128
|
+
@block_randomised = bit
|
129
|
+
|
130
|
+
@data = PoiseArchive::Bzip2::InputData.new @block_size if @data.nil?
|
131
|
+
|
132
|
+
get_and_move_to_front_decode
|
133
|
+
|
134
|
+
@crc.initialize_crc
|
135
|
+
@current_state = START_BLOCK_STATE
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def end_block
|
140
|
+
@computed_block_crc = @crc.final_crc
|
141
|
+
|
142
|
+
if @stored_block_crc != @computed_block_crc
|
143
|
+
@computed_combined_crc = (@stored_combined_crc << 1) | (@stored_combined_crc >> 31)
|
144
|
+
@computed_combined_crc ^= @stored_block_crc
|
145
|
+
|
146
|
+
raise 'BZip2 CRC error'
|
147
|
+
end
|
148
|
+
|
149
|
+
@computed_combined_crc = (@computed_combined_crc << 1) | (@computed_combined_crc >> 31)
|
150
|
+
@computed_combined_crc ^= @computed_block_crc
|
151
|
+
end
|
152
|
+
|
153
|
+
def complete
|
154
|
+
@stored_combined_crc = int
|
155
|
+
@current_state = EOF
|
156
|
+
@data = nil
|
157
|
+
|
158
|
+
raise 'BZip2 CRC error' if @stored_combined_crc != @computed_combined_crc
|
159
|
+
end
|
160
|
+
|
161
|
+
def close
|
162
|
+
if @io != $stdin
|
163
|
+
@io = nil
|
164
|
+
@data = nil
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def r(n)
|
169
|
+
live_shadow = @live
|
170
|
+
buff_shadow = @buff
|
171
|
+
|
172
|
+
if live_shadow < n
|
173
|
+
begin
|
174
|
+
thech = @io.readbyte
|
175
|
+
|
176
|
+
raise 'unexpected end of stream' if thech < 0
|
177
|
+
|
178
|
+
buff_shadow = (buff_shadow << 8) | thech
|
179
|
+
live_shadow += 8
|
180
|
+
end while live_shadow < n
|
181
|
+
|
182
|
+
@buff = buff_shadow
|
183
|
+
end
|
184
|
+
|
185
|
+
@live = live_shadow - n
|
186
|
+
|
187
|
+
(buff_shadow >> (live_shadow - n)) & ((1 << n) - 1)
|
188
|
+
end
|
189
|
+
|
190
|
+
def bit
|
191
|
+
r(1) != 0
|
192
|
+
end
|
193
|
+
|
194
|
+
def ubyte
|
195
|
+
r 8
|
196
|
+
end
|
197
|
+
|
198
|
+
def int
|
199
|
+
(((((r(8) << 8) | r(8)) << 8) | r(8)) << 8) | r(8)
|
200
|
+
end
|
201
|
+
|
202
|
+
def create_decode_tables(limit, base, perm, length, min_len, max_len, alpha_size)
|
203
|
+
pp = 0
|
204
|
+
(min_len..max_len).each do |i|
|
205
|
+
alpha_size.times do |j|
|
206
|
+
if length[j] == i
|
207
|
+
perm[pp] = j
|
208
|
+
pp += 1
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
MAX_CODE_LEN.downto 1 do |i|
|
214
|
+
base[i] = 0
|
215
|
+
limit[i] = 0
|
216
|
+
end
|
217
|
+
|
218
|
+
alpha_size.times do |i|
|
219
|
+
base[length[i] + 1] += 1
|
220
|
+
end
|
221
|
+
|
222
|
+
b = 0
|
223
|
+
1.upto(MAX_CODE_LEN - 1) do |i|
|
224
|
+
b += base[i]
|
225
|
+
base[i] = b
|
226
|
+
end
|
227
|
+
|
228
|
+
vec = 0
|
229
|
+
min_len.upto(max_len) do |i|
|
230
|
+
b = base[i]
|
231
|
+
nb = base[i + 1]
|
232
|
+
vec += nb - b
|
233
|
+
b = nb
|
234
|
+
limit[i] = vec - 1
|
235
|
+
vec = vec << 1
|
236
|
+
end
|
237
|
+
|
238
|
+
(min_len + 1).upto(max_len) do |i|
|
239
|
+
base[i] = ((limit[i - 1] + 1) << 1) - base[i]
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def receive_decoding_tables
|
244
|
+
in_use = @data.in_use
|
245
|
+
pos = @data.receive_decoding_tables_pos
|
246
|
+
selector = @data.selector
|
247
|
+
selector_mtf = @data.selector_mtf
|
248
|
+
|
249
|
+
in_use16 = 0
|
250
|
+
|
251
|
+
16.times do |i|
|
252
|
+
in_use16 |= 1 << i if bit
|
253
|
+
end
|
254
|
+
|
255
|
+
255.downto(0) do |i|
|
256
|
+
in_use[i] = false
|
257
|
+
end
|
258
|
+
|
259
|
+
16.times do |i|
|
260
|
+
if (in_use16 & (1 << i)) != 0
|
261
|
+
i16 = i << 4
|
262
|
+
16.times do |j|
|
263
|
+
in_use[i16 + j] = true if bit
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
make_maps
|
269
|
+
alpha_size = @n_in_use + 2
|
270
|
+
|
271
|
+
groups = r 3
|
272
|
+
selectors = r 15
|
273
|
+
|
274
|
+
selectors.times do |i|
|
275
|
+
j = 0
|
276
|
+
while bit
|
277
|
+
j += 1
|
278
|
+
end
|
279
|
+
selector_mtf[i] = j
|
280
|
+
end
|
281
|
+
|
282
|
+
groups.downto(0) do |v|
|
283
|
+
pos[v] = v
|
284
|
+
end
|
285
|
+
|
286
|
+
selectors.times do |i|
|
287
|
+
v = selector_mtf[i] & 0xff
|
288
|
+
tmp = pos[v]
|
289
|
+
|
290
|
+
while v > 0 do
|
291
|
+
pos[v] = pos[v -= 1]
|
292
|
+
end
|
293
|
+
|
294
|
+
pos[0] = tmp
|
295
|
+
selector[i] = tmp
|
296
|
+
end
|
297
|
+
|
298
|
+
len = @data.temp_char_array_2d
|
299
|
+
|
300
|
+
groups.times do |t|
|
301
|
+
curr = r 5
|
302
|
+
len_t = len[t]
|
303
|
+
alpha_size.times do |i|
|
304
|
+
while bit
|
305
|
+
curr += bit ? -1 : 1
|
306
|
+
end
|
307
|
+
len_t[i] = curr
|
308
|
+
end
|
309
|
+
@data.temp_char_array_2d[t] = len_t
|
310
|
+
end
|
311
|
+
|
312
|
+
create_huffman_decoding_tables alpha_size, groups
|
313
|
+
end
|
314
|
+
|
315
|
+
def create_huffman_decoding_tables(alpha_size, groups)
|
316
|
+
len = @data.temp_char_array_2d
|
317
|
+
min_lens = @data.min_lens
|
318
|
+
limit = @data.limit
|
319
|
+
base = @data.base
|
320
|
+
perm = @data.perm
|
321
|
+
|
322
|
+
groups.times do |t|
|
323
|
+
min_len = 32
|
324
|
+
max_len = 0
|
325
|
+
len_t = len[t]
|
326
|
+
|
327
|
+
(alpha_size - 1).downto 0 do |i|
|
328
|
+
lent = len_t[i]
|
329
|
+
max_len = lent if lent > max_len
|
330
|
+
min_len = lent if lent < min_len
|
331
|
+
end
|
332
|
+
|
333
|
+
create_decode_tables limit[t], base[t], perm[t], len[t], min_len, max_len, alpha_size
|
334
|
+
min_lens[t] = min_len
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def get_and_move_to_front_decode
|
339
|
+
@orig_ptr = r 24
|
340
|
+
receive_decoding_tables
|
341
|
+
|
342
|
+
ll8 = @data.ll8
|
343
|
+
unzftab = @data.unzftab
|
344
|
+
selector = @data.selector
|
345
|
+
seq_to_unseq = @data.seq_to_unseq
|
346
|
+
yy = @data.get_and_move_to_front_decode_yy
|
347
|
+
min_lens = @data.min_lens
|
348
|
+
limit = @data.limit
|
349
|
+
base = @data.base
|
350
|
+
perm = @data.perm
|
351
|
+
limit_last = @block_size * BASEBLOCKSIZE
|
352
|
+
|
353
|
+
256.downto(0) do |i|
|
354
|
+
yy[i] = i
|
355
|
+
unzftab[i] = 0
|
356
|
+
end
|
357
|
+
|
358
|
+
group_no = 0
|
359
|
+
group_pos = G_SIZE - 1
|
360
|
+
eob = @n_in_use + 1
|
361
|
+
next_sym = get_and_move_to_front_decode0 0
|
362
|
+
buff_shadow = @buff
|
363
|
+
live_shadow = @live
|
364
|
+
last_shadow = -1
|
365
|
+
zt = selector[group_no] & 0xff
|
366
|
+
base_zt = base[zt]
|
367
|
+
limit_zt = limit[zt]
|
368
|
+
perm_zt = perm[zt]
|
369
|
+
min_lens_zt = min_lens[zt]
|
370
|
+
|
371
|
+
while next_sym != eob
|
372
|
+
if (next_sym == RUNA) || (next_sym == RUNB)
|
373
|
+
s = -1
|
374
|
+
|
375
|
+
n = 1
|
376
|
+
while true do
|
377
|
+
if next_sym == RUNA
|
378
|
+
s += n
|
379
|
+
elsif next_sym == RUNB
|
380
|
+
s += n << 1
|
381
|
+
else
|
382
|
+
break
|
383
|
+
end
|
384
|
+
|
385
|
+
if group_pos == 0
|
386
|
+
group_pos = G_SIZE - 1
|
387
|
+
group_no += 1
|
388
|
+
zt = selector[group_no] & 0xff
|
389
|
+
base_zt = base[zt]
|
390
|
+
limit_zt = limit[zt]
|
391
|
+
perm_zt = perm[zt]
|
392
|
+
min_lens_zt = min_lens[zt]
|
393
|
+
else
|
394
|
+
group_pos -= 1
|
395
|
+
end
|
396
|
+
|
397
|
+
zn = min_lens_zt
|
398
|
+
|
399
|
+
while live_shadow < zn
|
400
|
+
thech = @io.readbyte
|
401
|
+
|
402
|
+
raise 'unexpected end of stream' if thech < 0
|
403
|
+
|
404
|
+
buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech
|
405
|
+
live_shadow += 8
|
406
|
+
end
|
407
|
+
|
408
|
+
zvec = ((buff_shadow >> (live_shadow - zn)) & 0xffffffff) & ((1 << zn) - 1)
|
409
|
+
live_shadow -= zn
|
410
|
+
|
411
|
+
while zvec > limit_zt[zn]
|
412
|
+
zn += 1
|
413
|
+
|
414
|
+
while live_shadow < 1
|
415
|
+
thech = @io.readbyte
|
416
|
+
|
417
|
+
raise 'unexpected end of stream' if thech < 0
|
418
|
+
|
419
|
+
buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech
|
420
|
+
live_shadow += 8
|
421
|
+
end
|
422
|
+
|
423
|
+
live_shadow -= 1
|
424
|
+
zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
|
425
|
+
end
|
426
|
+
|
427
|
+
next_sym = perm_zt[zvec - base_zt[zn]]
|
428
|
+
|
429
|
+
n = n << 1
|
430
|
+
end
|
431
|
+
|
432
|
+
ch = seq_to_unseq[yy[0]]
|
433
|
+
unzftab[ch & 0xff] += s + 1
|
434
|
+
|
435
|
+
while s >= 0
|
436
|
+
last_shadow += 1
|
437
|
+
ll8[last_shadow] = ch
|
438
|
+
s -= 1
|
439
|
+
end
|
440
|
+
|
441
|
+
raise 'block overrun' if last_shadow >= limit_last
|
442
|
+
else
|
443
|
+
last_shadow += 1
|
444
|
+
raise 'block overrun' if last_shadow >= limit_last
|
445
|
+
|
446
|
+
tmp = yy[next_sym - 1]
|
447
|
+
unzftab[seq_to_unseq[tmp] & 0xff] += 1
|
448
|
+
ll8[last_shadow] = seq_to_unseq[tmp]
|
449
|
+
|
450
|
+
yy[1, next_sym - 1] = yy[0, next_sym - 1]
|
451
|
+
yy[0] = tmp
|
452
|
+
|
453
|
+
if group_pos == 0
|
454
|
+
group_pos = G_SIZE - 1
|
455
|
+
group_no += 1
|
456
|
+
zt = selector[group_no] & 0xff
|
457
|
+
base_zt = base[zt]
|
458
|
+
limit_zt = limit[zt]
|
459
|
+
perm_zt = perm[zt]
|
460
|
+
min_lens_zt = min_lens[zt]
|
461
|
+
else
|
462
|
+
group_pos -= 1
|
463
|
+
end
|
464
|
+
|
465
|
+
zn = min_lens_zt
|
466
|
+
|
467
|
+
while live_shadow < zn
|
468
|
+
thech = @io.readbyte
|
469
|
+
|
470
|
+
raise 'unexpected end of stream' if thech < 0
|
471
|
+
|
472
|
+
buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech
|
473
|
+
live_shadow += 8
|
474
|
+
end
|
475
|
+
zvec = (buff_shadow >> (live_shadow - zn)) & ((1 << zn) - 1)
|
476
|
+
live_shadow -= zn
|
477
|
+
|
478
|
+
while zvec > limit_zt[zn]
|
479
|
+
zn += 1
|
480
|
+
while live_shadow < 1
|
481
|
+
thech = @io.readbyte
|
482
|
+
|
483
|
+
raise 'unexpected end of stream' if thech < 0
|
484
|
+
|
485
|
+
buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech
|
486
|
+
live_shadow += 8
|
487
|
+
end
|
488
|
+
live_shadow -= 1
|
489
|
+
zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
|
490
|
+
end
|
491
|
+
|
492
|
+
next_sym = perm_zt[zvec - base_zt[zn]]
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
@last = last_shadow
|
497
|
+
@live = live_shadow
|
498
|
+
@buff = buff_shadow
|
499
|
+
end
|
500
|
+
|
501
|
+
def get_and_move_to_front_decode0(group_no)
|
502
|
+
zt = @data.selector[group_no] & 0xff
|
503
|
+
limit_zt = @data.limit[zt]
|
504
|
+
zn = @data.min_lens[zt]
|
505
|
+
zvec = r zn
|
506
|
+
live_shadow = @live
|
507
|
+
buff_shadow = @buff
|
508
|
+
|
509
|
+
while zvec > limit_zt[zn]
|
510
|
+
zn += 1
|
511
|
+
|
512
|
+
while live_shadow < 1
|
513
|
+
thech = @io.readbyte
|
514
|
+
|
515
|
+
raise 'unexpected end of stream' if thech < 0
|
516
|
+
|
517
|
+
buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech
|
518
|
+
live_shadow += 8
|
519
|
+
end
|
520
|
+
|
521
|
+
live_shadow -=1
|
522
|
+
zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
|
523
|
+
end
|
524
|
+
|
525
|
+
@live = live_shadow
|
526
|
+
@buff = buff_shadow
|
527
|
+
|
528
|
+
@data.perm[zt][zvec - @data.base[zt][zn]]
|
529
|
+
end
|
530
|
+
|
531
|
+
def setup_block
|
532
|
+
return if @data.nil?
|
533
|
+
|
534
|
+
cftab = @data.cftab
|
535
|
+
tt = @data.init_tt @last + 1
|
536
|
+
ll8 = @data.ll8
|
537
|
+
cftab[0] = 0
|
538
|
+
cftab[1, 256] = @data.unzftab[0, 256]
|
539
|
+
|
540
|
+
c = cftab[0]
|
541
|
+
1.upto(256) do |i|
|
542
|
+
c += cftab[i]
|
543
|
+
cftab[i] = c
|
544
|
+
end
|
545
|
+
|
546
|
+
last_shadow = @last
|
547
|
+
(last_shadow + 1).times do |i|
|
548
|
+
cftab_i = ll8[i] & 0xff
|
549
|
+
tt[cftab[cftab_i]] = i
|
550
|
+
cftab[cftab_i] += 1
|
551
|
+
end
|
552
|
+
|
553
|
+
raise 'stream corrupted' if @orig_ptr < 0 || @orig_ptr >= tt.size
|
554
|
+
|
555
|
+
@su_t_pos = tt[@orig_ptr]
|
556
|
+
@su_count = 0
|
557
|
+
@su_i2 = 0
|
558
|
+
@su_ch2 = 256
|
559
|
+
|
560
|
+
if @block_randomised
|
561
|
+
@su_r_n_to_go = 0
|
562
|
+
@su_r_t_pos = 0
|
563
|
+
|
564
|
+
setup_rand_part_a
|
565
|
+
else
|
566
|
+
setup_no_rand_part_a
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
570
|
+
def setup_rand_part_a
|
571
|
+
if @su_i2 <= @last
|
572
|
+
@su_ch_prev = @su_ch2
|
573
|
+
su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
|
574
|
+
@su_t_pos = @data.tt[@su_t_pos]
|
575
|
+
|
576
|
+
if @su_r_n_to_go == 0
|
577
|
+
@su_r_n_to_go = RNUMS[@su_r_t_pos] - 1
|
578
|
+
@su_r_t_pos += 1
|
579
|
+
@su_r_t_pos = 0 if @su_r_t_pos == 512
|
580
|
+
else
|
581
|
+
@su_r_n_to_go -= 1
|
582
|
+
end
|
583
|
+
|
584
|
+
@su_ch2 = su_ch2_shadow ^= (@su_r_n_to_go == 1) ? 1 : 0
|
585
|
+
@su_i2 += 1
|
586
|
+
@current_char = su_ch2_shadow
|
587
|
+
@current_state = RAND_PART_B_STATE
|
588
|
+
@crc.update_crc su_ch2_shadow
|
589
|
+
else
|
590
|
+
end_block
|
591
|
+
init_block
|
592
|
+
setup_block
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
def setup_no_rand_part_a
|
597
|
+
if @su_i2 <= @last
|
598
|
+
@su_ch_prev = @su_ch2
|
599
|
+
su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
|
600
|
+
@su_ch2 = su_ch2_shadow
|
601
|
+
@su_t_pos = @data.tt[@su_t_pos]
|
602
|
+
@su_i2 += 1
|
603
|
+
@current_char = su_ch2_shadow
|
604
|
+
@current_state = NO_RAND_PART_B_STATE
|
605
|
+
@crc.update_crc su_ch2_shadow
|
606
|
+
else
|
607
|
+
@current_state = NO_RAND_PART_A_STATE
|
608
|
+
end_block
|
609
|
+
init_block
|
610
|
+
setup_block
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
def setup_rand_part_b
|
615
|
+
if @su_ch2 != @su_ch_prev
|
616
|
+
@current_state = RAND_PART_A_STATE
|
617
|
+
@su_count = 1
|
618
|
+
setup_rand_part_a
|
619
|
+
else
|
620
|
+
@su_count += 1
|
621
|
+
if @su_count >= 4
|
622
|
+
@su_z = @data.ll8[@su_t_pos] & 0xff
|
623
|
+
@su_t_pos = @data.tt[@su_t_pos]
|
624
|
+
|
625
|
+
if @su_r_n_to_go == 0
|
626
|
+
@su_r_n_to_go = RNUMS[@su_r_t_pos] - 1
|
627
|
+
@su_r_t_pos += 1
|
628
|
+
@su_r_t_pos = 0 if @su_r_t_pos == 512
|
629
|
+
else
|
630
|
+
@su_r_n_to_go -= 1
|
631
|
+
end
|
632
|
+
|
633
|
+
@su_j2 = 0
|
634
|
+
@current_state = RAND_PART_C_STATE
|
635
|
+
@su_z ^= 1 if @su_r_n_to_go == 1
|
636
|
+
setup_rand_part_c
|
637
|
+
else
|
638
|
+
@current_state = RAND_PART_A_STATE
|
639
|
+
setup_rand_part_a
|
640
|
+
end
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
def setup_rand_part_c
|
645
|
+
if @su_j2 < @su_z
|
646
|
+
@current_char = @su_ch2
|
647
|
+
@crc.update_crc @su_ch2
|
648
|
+
@su_j2 += 1
|
649
|
+
else
|
650
|
+
@current_state = RAND_PART_A_STATE
|
651
|
+
@su_i2 += 1
|
652
|
+
@su_count = 0
|
653
|
+
setup_rand_part_a
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
657
|
+
def setup_no_rand_part_b
|
658
|
+
if @su_ch2 != @su_ch_prev
|
659
|
+
@su_count = 1
|
660
|
+
setup_no_rand_part_a
|
661
|
+
else
|
662
|
+
@su_count += 1
|
663
|
+
if @su_count >= 4
|
664
|
+
@su_z = @data.ll8[@su_t_pos] & 0xff
|
665
|
+
@su_t_pos = @data.tt[@su_t_pos]
|
666
|
+
@su_j2 = 0
|
667
|
+
setup_no_rand_part_c
|
668
|
+
else
|
669
|
+
setup_no_rand_part_a
|
670
|
+
end
|
671
|
+
end
|
672
|
+
end
|
673
|
+
|
674
|
+
def setup_no_rand_part_c
|
675
|
+
if @su_j2 < @su_z
|
676
|
+
su_ch2_shadow = @su_ch2
|
677
|
+
@current_char = su_ch2_shadow
|
678
|
+
@crc.update_crc su_ch2_shadow
|
679
|
+
@su_j2 += 1
|
680
|
+
@current_state = NO_RAND_PART_C_STATE
|
681
|
+
else
|
682
|
+
@su_i2 += 1
|
683
|
+
@su_count = 0
|
684
|
+
setup_no_rand_part_a
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
688
|
+
def size
|
689
|
+
if @io.is_a? StringIO
|
690
|
+
@io.size
|
691
|
+
elsif @io.is_a? File
|
692
|
+
@io.stat.size
|
693
|
+
end
|
694
|
+
end
|
695
|
+
|
696
|
+
def uncompressed
|
697
|
+
@last + 1
|
698
|
+
end
|
699
|
+
|
700
|
+
def inspect
|
701
|
+
"#<#{self.class}: @io=#{@io.inspect} size=#{size} uncompressed=#{uncompressed}>"
|
702
|
+
end
|
703
|
+
|
704
|
+
end
|