rbzip2 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .yardoc/
2
+ doc/
3
+ pkg/
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - jruby
6
+ - rbx
7
+ - rbx-2.0
8
+ - ree
9
+ - ruby-head
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rbzip2 (0.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.3)
10
+ metaclass (0.0.1)
11
+ mocha (0.10.0)
12
+ metaclass (~> 0.0.1)
13
+ rake (0.9.2.2)
14
+ rspec-core (2.7.1)
15
+ rspec-expectations (2.7.0)
16
+ diff-lcs (~> 1.1.2)
17
+ yard (0.7.3)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ mocha (~> 0.10.0)
24
+ rake (~> 0.9.2)
25
+ rbzip2!
26
+ rspec-core (~> 2.7.1)
27
+ rspec-expectations (~> 2.7.0)
28
+ yard (~> 0.7.3)
data/LICENSE ADDED
@@ -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.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ RBzip2
2
+ ======
3
+
4
+ RBzip2 is a gem providing a pure Ruby implementation of the [bzip2][1]
5
+ algorithm used for compression and decompression.
6
+
7
+ It is based on the code of the [Apache Commons Compress][2] project and adds
8
+ a straight Ruby-like API. There are no external dependencies like other gems or
9
+ libraries. Therefore it will run on any Ruby implementation and the respective
10
+ operating systems supported by those implementations.
11
+
12
+ ## Features
13
+
14
+ * Decompression of bzip2 compressed IOs (like `File` or `StringIO`)
15
+
16
+ ## Usage
17
+
18
+ require 'rbzip2'
19
+
20
+ file = File.new 'somefile.bz2' # open a compressed file
21
+ io = RBzip2::IO.new file # wrap the file into RBzip2's IO
22
+ data = io.read # read data into a string
23
+
24
+ ## Future plans
25
+
26
+ * Simple decompression of strings
27
+ * Compression of raw data
28
+ * Simple creation of compressed files
29
+ * Two-way compressed IO that will (de)compress as you read/write
30
+
31
+ ## Installation
32
+
33
+ To install RBzip2 as a Ruby gem use the following command:
34
+
35
+ gem install rbzip2
36
+
37
+ To use it as a dependency managed by Bundler add the following to your
38
+ `Gemfile`:
39
+
40
+ gem 'rbzip2'
41
+
42
+ ## License
43
+
44
+ This code is free software; you can redistribute it and/or modify it under the
45
+ terms of the new BSD License. A copy of this license can be found in the
46
+ included LICENSE file.
47
+
48
+ ## Credits
49
+
50
+ * Sebastian Staudt -- koraktor(at)gmail.com
51
+
52
+ ## See Also
53
+
54
+ * [Documentation](http://rubydoc.info/gems/rbzip2)
55
+ * [GitHub project page](https://github.com/koraktor/rbzip2)
56
+ * [bzip2 project page][1]
57
+
58
+ [1]: http://bzip.org
59
+ [2]: http://commons.apache.org/compress
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ # This code is free software; you can redistribute it and/or modify it under
4
+ # the terms of the new BSD License.
5
+ #
6
+ # Copyright (c) 2011, Sebastian Staudt
7
+
8
+ require 'rspec/core/rake_task'
9
+ require 'rubygems/package_task'
10
+
11
+ task :default => :spec
12
+
13
+ spec = Gem::Specification.load 'rbzip2.gemspec'
14
+ Gem::PackageTask.new(spec) do |pkg|
15
+ end
16
+
17
+ RSpec::Core::RakeTask.new('spec') do |t|
18
+ end
19
+
20
+ begin
21
+ require 'yard'
22
+
23
+ YARD::Rake::YardocTask.new do |yardoc|
24
+ yardoc.name = 'doc'
25
+ yardoc.files = [ 'lib/**/*.rb', 'LICENSE', 'README.md' ]
26
+ yardoc.options = [ '--private', '--title', 'RBzip2 — API Documentation' ]
27
+ end
28
+ rescue LoadError
29
+ desc 'Generate YARD Documentation (not available)'
30
+ task :doc do
31
+ $stderr.puts 'You need YARD to build the documentation. Install it using `gem install yard`.'
32
+ end
33
+ end
34
+
35
+ desc 'Clean documentation and package directories'
36
+ task :clean do
37
+ FileUtils.rm_rf 'doc'
38
+ FileUtils.rm_rf 'pkg'
39
+ end
@@ -0,0 +1,66 @@
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
data/lib/rbzip2/crc.rb ADDED
@@ -0,0 +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
@@ -0,0 +1,51 @@
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 'rbzip2/constants'
7
+
8
+ class RBzip2::Data
9
+
10
+ attr_reader :base, :cftab, :get_and_move_to_front_decode_yy, :in_use,
11
+ :limit, :ll8, :min_lens, :perm, :receive_decoding_tables_pos,
12
+ :selector, :selector_mtf, :seq_to_unseq, :temp_char_array_2d,
13
+ :unzftab, :tt
14
+
15
+ def initialize(block_size)
16
+ @in_use = Array.new 256, false
17
+
18
+ @seq_to_unseq = Array.new 256, 0
19
+ @selector = Array.new RBzip2::MAX_SELECTORS, 0
20
+ @selector_mtf = Array.new RBzip2::MAX_SELECTORS, 0
21
+
22
+ @unzftab = Array.new 256, 0
23
+
24
+ @base = Array.new RBzip2::N_GROUPS
25
+ RBzip2::N_GROUPS.times { |i| @base[i] = Array.new(RBzip2::MAX_ALPHA_SIZE, 0) }
26
+ @limit = Array.new RBzip2::N_GROUPS
27
+ RBzip2::N_GROUPS.times { |i| @limit[i] = Array.new(RBzip2::MAX_ALPHA_SIZE, 0) }
28
+ @perm = Array.new RBzip2::N_GROUPS
29
+ RBzip2:: N_GROUPS.times { |i| @perm[i] = Array.new(RBzip2::MAX_ALPHA_SIZE, 0) }
30
+ @min_lens = Array.new RBzip2::N_GROUPS, 0
31
+
32
+ @cftab = Array.new 257, 0
33
+ @get_and_move_to_front_decode_yy = Array.new 256
34
+ @temp_char_array_2d = Array.new RBzip2::N_GROUPS
35
+ RBzip2::N_GROUPS.times { |i| @temp_char_array_2d[i] = Array.new(RBzip2::MAX_ALPHA_SIZE, 0) }
36
+ @receive_decoding_tables_pos = Array.new RBzip2::N_GROUPS, 0
37
+
38
+ @ll8 = Array.new block_size * RBzip2::BASEBLOCKSIZE
39
+ end
40
+
41
+ def init_tt(size)
42
+ tt_shadow = @tt
43
+
44
+ if tt_shadow.nil? || tt_shadow.size < size
45
+ @tt = tt_shadow = Array.new(size)
46
+ end
47
+
48
+ tt_shadow
49
+ end
50
+
51
+ end
@@ -0,0 +1,684 @@
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
data/lib/rbzip2/io.rb ADDED
@@ -0,0 +1,25 @@
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 'rbzip2/decompressor'
7
+
8
+ class RBzip2::IO
9
+
10
+ include RBzip2::Decompressor
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
+ end
@@ -0,0 +1,10 @@
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
+ VERSION = '0.1.0' unless const_defined? :VERSION
9
+
10
+ end
data/lib/rbzip2.rb ADDED
@@ -0,0 +1,14 @@
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
+ autoload :CRC, 'rbzip2/crc'
9
+ autoload :Data, 'rbzip2/data'
10
+ autoload :Decompressor, 'rbzip2/decompressor'
11
+ autoload :IO, 'rbzip2/io'
12
+ autoload :VERSION, 'rbzip2/version'
13
+
14
+ end
data/rbzip2.gemspec ADDED
@@ -0,0 +1,27 @@
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 File.expand_path(File.dirname(__FILE__) + '/lib/rbzip2/version')
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = 'rbzip2'
10
+ s.version = RBzip2::VERSION
11
+ s.platform = Gem::Platform::RUBY
12
+ s.authors = [ 'Sebastian Staudt' ]
13
+ s.email = [ 'koraktor@gmail.com' ]
14
+ s.homepage = 'https://github.com/koraktor/rbzip2'
15
+ s.summary = 'Pure Ruby impementation of bzip2'
16
+ s.description = 'A pure Ruby implementation of the bzip2 compression algorithm.'
17
+
18
+ s.add_development_dependency 'mocha', '~> 0.10.0'
19
+ s.add_development_dependency 'rake', '~> 0.9.2'
20
+ s.add_development_dependency 'rspec-core', '~> 2.7.1'
21
+ s.add_development_dependency 'rspec-expectations', '~> 2.7.0'
22
+ s.add_development_dependency 'yard', '~> 0.7.3'
23
+
24
+ s.files = `git ls-files`.split("\n")
25
+ s.test_files = `git ls-files -- spec/*`.split("\n")
26
+ s.require_paths = [ 'lib' ]
27
+ end
Binary file
@@ -0,0 +1,11 @@
1
+ This is a test fixture for RBzip2.
2
+ Its contents will be compressed and decompressed to test the functionality.
3
+
4
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
5
+ tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
6
+ vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd
7
+ gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum
8
+ dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
9
+ invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero
10
+ eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no
11
+ sea takimata sanctus est Lorem ipsum dolor sit amet.
data/spec/helper.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'rspec/core'
2
+ require 'rspec/expectations'
3
+
4
+ require 'rbzip2'
5
+
6
+ include RBzip2
7
+
8
+ RSpec.configure do |config|
9
+ config.color_enabled = true
10
+ config.extend RBzip2
11
+ config.mock_framework = :mocha
12
+ end
data/spec/io_spec.rb ADDED
@@ -0,0 +1,37 @@
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 'helper'
7
+
8
+ describe RBzip2::IO do
9
+
10
+ before do
11
+ @txt_file = File.new File.join(File.dirname(__FILE__), 'fixtures/test.txt')
12
+ bz2_file = File.new File.join(File.dirname(__FILE__), 'fixtures/test.bz2')
13
+ @bz2_io = RBzip2::IO.new bz2_file
14
+ end
15
+
16
+ it 'allows decompressing data' do
17
+ RBzip2::IO.should include(Decompressor)
18
+ end
19
+
20
+ it 'acts like a standard IO' do
21
+ methods = RBzip2::IO.instance_methods.map { |m| m.to_sym }
22
+ methods.should include(:read, :close)
23
+ end
24
+
25
+ it 'knows its size' do
26
+ @bz2_io.size.should be(375)
27
+ end
28
+
29
+ it 'knows the size of the uncompressed data' do
30
+ @bz2_io.uncompressed.should be(704)
31
+ end
32
+
33
+ it 'should be able to decompress compressed data' do
34
+ @bz2_io.read.should eq(@txt_file.read)
35
+ end
36
+
37
+ end
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbzip2
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Sebastian Staudt
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-09 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ type: :development
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ hash: 55
28
+ segments:
29
+ - 0
30
+ - 10
31
+ - 0
32
+ version: 0.10.0
33
+ prerelease: false
34
+ name: mocha
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ type: :development
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 63
44
+ segments:
45
+ - 0
46
+ - 9
47
+ - 2
48
+ version: 0.9.2
49
+ prerelease: false
50
+ name: rake
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ type: :development
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ hash: 17
60
+ segments:
61
+ - 2
62
+ - 7
63
+ - 1
64
+ version: 2.7.1
65
+ prerelease: false
66
+ name: rspec-core
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ type: :development
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ hash: 19
76
+ segments:
77
+ - 2
78
+ - 7
79
+ - 0
80
+ version: 2.7.0
81
+ prerelease: false
82
+ name: rspec-expectations
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ type: :development
86
+ requirement: &id005 !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ~>
90
+ - !ruby/object:Gem::Version
91
+ hash: 5
92
+ segments:
93
+ - 0
94
+ - 7
95
+ - 3
96
+ version: 0.7.3
97
+ prerelease: false
98
+ name: yard
99
+ version_requirements: *id005
100
+ description: A pure Ruby implementation of the bzip2 compression algorithm.
101
+ email:
102
+ - koraktor@gmail.com
103
+ executables: []
104
+
105
+ extensions: []
106
+
107
+ extra_rdoc_files: []
108
+
109
+ files:
110
+ - .gitignore
111
+ - .travis.yml
112
+ - Gemfile
113
+ - Gemfile.lock
114
+ - LICENSE
115
+ - README.md
116
+ - Rakefile
117
+ - lib/rbzip2.rb
118
+ - lib/rbzip2/constants.rb
119
+ - lib/rbzip2/crc.rb
120
+ - lib/rbzip2/data.rb
121
+ - lib/rbzip2/decompressor.rb
122
+ - lib/rbzip2/io.rb
123
+ - lib/rbzip2/version.rb
124
+ - rbzip2.gemspec
125
+ - spec/fixtures/test.bz2
126
+ - spec/fixtures/test.txt
127
+ - spec/helper.rb
128
+ - spec/io_spec.rb
129
+ homepage: https://github.com/koraktor/rbzip2
130
+ licenses: []
131
+
132
+ post_install_message:
133
+ rdoc_options: []
134
+
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ hash: 3
143
+ segments:
144
+ - 0
145
+ version: "0"
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ hash: 3
152
+ segments:
153
+ - 0
154
+ version: "0"
155
+ requirements: []
156
+
157
+ rubyforge_project:
158
+ rubygems_version: 1.8.11
159
+ signing_key:
160
+ specification_version: 3
161
+ summary: Pure Ruby impementation of bzip2
162
+ test_files:
163
+ - spec/fixtures/test.bz2
164
+ - spec/fixtures/test.txt
165
+ - spec/helper.rb
166
+ - spec/io_spec.rb