rbzip2 0.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.
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