extbzip3 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +24 -0
- data/README.md +159 -0
- data/Rakefile +247 -0
- data/ext/compat.h +32 -0
- data/ext/extbzip3.c +220 -0
- data/ext/extbzip3.h +279 -0
- data/ext/extbzip3_decoder.c +484 -0
- data/ext/extbzip3_encoder.c +344 -0
- data/ext/extconf.rb +43 -0
- data/gemstub.rb +17 -0
- data/lib/extbzip3/decoder.rb +90 -0
- data/lib/extbzip3/fordoc.rb +38 -0
- data/lib/extbzip3/version.rb +8 -0
- data/lib/extbzip3.rb +65 -0
- data/test/test_bzip3.rb +77 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d337adb887c6e5dbda229b8536addfcd5b5e91af292ff118ae586c94ce90d5c9
|
4
|
+
data.tar.gz: feea5218e03eb301e8b346993803572076259f446e8260bd4ff73b882735f85f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b8e1c8883e87f405f263451d479bd00f0ac3bf0631da8d2f19fb3faedac0e342f90815bdc3143c3c772d459778dc6f80df6ee779d751096bf61f432c510463a5
|
7
|
+
data.tar.gz: 918a07bcb7f75f91bea44e7e10fe5746d314393ecae805e48484324291cd8c92ddcd3c6900e330b9323273fc79ce54825cffe8d46e2472ec5c677f464bc5b1c4
|
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2023, dearblue. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or
|
4
|
+
without modification, are permitted provided that the following
|
5
|
+
conditions are met:
|
6
|
+
|
7
|
+
1. Redistributions of source code must retain the above copyright
|
8
|
+
notice, this list of conditions and the following disclaimer.
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright
|
10
|
+
notice, this list of conditions and the following disclaimer in
|
11
|
+
the documentation and/or other materials provided with the
|
12
|
+
distribution.
|
13
|
+
|
14
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
15
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
16
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
17
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
18
|
+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
19
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
20
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
21
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
22
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
extbzip3 - bzip3 for Ruby
|
2
|
+
=========================
|
3
|
+
|
4
|
+
This document is written in Japanese.
|
5
|
+
|
6
|
+
[bzip3](https://github.com/kspalaiologos/bzip3) の非公式 Ruby バインディングです。
|
7
|
+
|
8
|
+
|
9
|
+
できること
|
10
|
+
----------
|
11
|
+
|
12
|
+
- `require "extbzip3"`
|
13
|
+
- `Bzip3` module
|
14
|
+
|
15
|
+
| method | annotation
|
16
|
+
| ----- | -----
|
17
|
+
| `Bzip3.decode(str, ...)` | see `Bzip3::Decoder.decode`
|
18
|
+
| `Bzip3.encode(str, ...)` | see `Bzip3::Encoder.encode`
|
19
|
+
| `Bzip3.decode(obj, ...)` | see `Bzip3::Decoder.open`
|
20
|
+
| `Bzip3.encode(obj, ...)` | see `Bzip3::Encoder.open`
|
21
|
+
|
22
|
+
- `Bzip3::Decoder` class
|
23
|
+
|
24
|
+
| method | annotation
|
25
|
+
| ----- | -----
|
26
|
+
| `Bzip3::Decoder.decode(str, maxdest = nil, dest = "", *opts)` | returns dest with bzip3 decoded
|
27
|
+
| `Bzip3::Decoder.decode(str, dest, *opts)` | returns dest with bzip3 decoded
|
28
|
+
| `Bzip3::Decoder.open(obj, *opts)` | returns bzip3 decoder
|
29
|
+
| `Bzip3::Decoder.open(obj, *opts) { \|decoder\| ... }` | returns object from yield returned
|
30
|
+
| `Bzip3::Decoder#read(size = nil, dest = "")` | returns dest with bzip3 decoded
|
31
|
+
| `Bzip3::Decoder#close` |
|
32
|
+
| `Bzip3::Decoder#eof?` |
|
33
|
+
|
34
|
+
- `Bzip3::Encoder` class
|
35
|
+
|
36
|
+
| method | annotation
|
37
|
+
| ----- | -----
|
38
|
+
| `Bzip3::Encoder.encode(str, maxdest = nil, dest = "", *opts)` | returns dest with bzip3'ed sequence
|
39
|
+
| `Bzip3::Encoder.encode(str, dest, *opts)` | returns dest with bzip3'ed sequence
|
40
|
+
| `Bzip3::Encoder.open(obj, *opts)` | returns bzip3 encoder
|
41
|
+
| `Bzip3::Encoder.open(obj, *opts) { \|encoder\| ... }` | returns object from yield returned
|
42
|
+
| `Bzip3::Encoder#write(src)` | returns receiver
|
43
|
+
| `Bzip3::Encoder#flush` | returns receiver
|
44
|
+
| `Bzip3::Encoder#close` |
|
45
|
+
| `Bzip3::Encoder#eof?` |
|
46
|
+
|
47
|
+
- `Bzip3::BlockProcessor` class
|
48
|
+
|
49
|
+
| method | annotation
|
50
|
+
| ----- | -----
|
51
|
+
| `Bzip3::BlockProcessor.new(blocksize)` |
|
52
|
+
| `Bzip3::BlockProcessor#decode(src, dest, original_size)` | returns `dest` string as original data
|
53
|
+
| `Bzip3::BlockProcessor#encode(src, dest)` | returns `dest` string as bzip3'ed data
|
54
|
+
| `Bzip3::BlockProcessor#blocksize` | returns `blocksize` integer with when `new`
|
55
|
+
|
56
|
+
- `using Bzip3` (refinements)
|
57
|
+
|
58
|
+
| method | annotation
|
59
|
+
| ----- | -----
|
60
|
+
| `String#to_bzip3(...)` | see `Bzip3::Encoder.encode`
|
61
|
+
| `String#bunzip3(...)` | see `Bzip3::Decoder.decode`
|
62
|
+
| `Object#to_bzip3(...)` | see `Bzip3::Encoder.open`
|
63
|
+
| `Object#bunzip3(...)` | see `Bzip3::Decoder.open`
|
64
|
+
|
65
|
+
### データ形式について
|
66
|
+
|
67
|
+
- extbzip3 は [「bzip3 ファイル形式」](https://github.com/kspalaiologos/bzip3/blob/1.3.1/doc/file_format.md) を標準で扱います。
|
68
|
+
利用者は特別な操作や指定を行う必要がありません。
|
69
|
+
- extbzip3 は [「bzip3 ブロック形式」](https://github.com/kspalaiologos/bzip3/blob/1.3.1/doc/low_level_format.md) を扱うことも出来ます。
|
70
|
+
`Bzip3::BlockProcessor` クラスを使ってください。
|
71
|
+
- extbzip3 は [「bzip3 フレーム形式」](https://github.com/kspalaiologos/bzip3/blob/1.3.1/doc/high_level_format.md) を扱うことも出来ます。
|
72
|
+
文字列を圧縮・伸長する特異メソッド `Bzip3::Encoder.encode` または `Bzip3::Decoder.decode` にキーワード引数として `format: Bzip3::V1_FRAME_FORMAT` を与えてください。
|
73
|
+
ストリーム指向 API を「bzip3 フレーム形式」に対応させる予定はありません。
|
74
|
+
|
75
|
+
|
76
|
+
つかいかた
|
77
|
+
----------
|
78
|
+
|
79
|
+
### 導入
|
80
|
+
|
81
|
+
事前にシステム上へ [bzip3](https://github.com/kspalaiologos/bzip3) をインストールしてください。
|
82
|
+
|
83
|
+
```console
|
84
|
+
% sudo gem install extbzip3
|
85
|
+
```
|
86
|
+
|
87
|
+
### 単発圧縮・伸長
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
require "extbzip3"
|
91
|
+
|
92
|
+
src = "123456789"
|
93
|
+
bin = Bzip3.encode(src)
|
94
|
+
# => "BZ3v1\x00\x00\x10\x00\x11\x00\x00\x00\t\x00\x00\x00'F\xE3\xEB\xFF\xFF\xFF\xFF123456789"
|
95
|
+
src1 = Bzip3.decode(bin)
|
96
|
+
# => "123456789"
|
97
|
+
```
|
98
|
+
|
99
|
+
### ストリーミング圧縮と伸長
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
require "extbzip3"
|
103
|
+
|
104
|
+
# 圧縮処理してファイルとして出力
|
105
|
+
File.open("/boot/kernel/kernel", "rb") do |src|
|
106
|
+
File.open("kernel.bz3", "wb") do |dest|
|
107
|
+
Bzip3.encode(dest) do |bz3|
|
108
|
+
buf = ""
|
109
|
+
bz3.write buf while src.read(123456, buf)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# 伸張処理してファイルとして出力
|
115
|
+
File.open("kernel.bz3", "rb") do |src|
|
116
|
+
File.open("kernel.1", "wb") do |dest|
|
117
|
+
Bzip3.decode(src) do |bz3|
|
118
|
+
buf = ""
|
119
|
+
dest.write buf while bz3.read(123456, buf)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# ファイルの比較
|
125
|
+
system "md5 /boot/kernel/kernel kernel.1"
|
126
|
+
# => MD5 (/boot/kernel/kernel) = 71b8f6c6a29f4d647f45d9501d549cf3
|
127
|
+
# => MD5 (kernel.1) = 71b8f6c6a29f4d647f45d9501d549cf3
|
128
|
+
```
|
129
|
+
|
130
|
+
### bzip3 フレーム形式による単発圧縮・伸長
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
require "extbzip3"
|
134
|
+
|
135
|
+
src = "123456789"
|
136
|
+
bin = Bzip3.encode(src, format: Bzip3::V1_FRAME_FORMAT)
|
137
|
+
# => "BZ3v1\x00\x00\x10\x00\x01\x00\x00\x00\x11\x00\x00\x00\t\x00\x00\x00'F\xE3\xEB\xFF\xFF\xFF\xFF123456789"
|
138
|
+
src1 = Bzip3.decode(bin, format: Bzip3::V1_FRAME_FORMAT)
|
139
|
+
# => "123456789"
|
140
|
+
```
|
141
|
+
|
142
|
+
|
143
|
+
しょげん
|
144
|
+
--------
|
145
|
+
|
146
|
+
- Project page: <https://github.com/dearblue/ruby-extbzip3>
|
147
|
+
- Licensing: [2-clause BSD License](LICENSE) by [dearblue](https://github.com/dearblue)
|
148
|
+
- Version: 0.0.1
|
149
|
+
- Project status: CONCEPT
|
150
|
+
- Dependency gems: none
|
151
|
+
- Dependency external C libraries:
|
152
|
+
- [bzip3](https://github.com/kspalaiologos/bzip3)
|
153
|
+
version 1.3.2 or later
|
154
|
+
under [GNU Lesser General Public License version 3 or later](https://github.com/kspalaiologos/bzip3/blob/master/LICENSE)
|
155
|
+
by [Kamila Szewczyk](https://github.com/kspalaiologos)
|
156
|
+
and [Apache License, Version 2.0](https://github.com/kspalaiologos/bzip3/blob/master/libsais-LICENSE)
|
157
|
+
by [Ilya Grebnov](https://github.com/IlyaGrebnov)
|
158
|
+
and [Kamila Szewczyk](https://github.com/kspalaiologos)
|
159
|
+
- Bundled external C libraries: none
|
data/Rakefile
ADDED
@@ -0,0 +1,247 @@
|
|
1
|
+
|
2
|
+
require "pathname"
|
3
|
+
require "rake/clean"
|
4
|
+
|
5
|
+
RUBYSET ||= (ENV["RUBYSET"] || "").split(",").yield_self { |me| me.empty? ? nil : me }
|
6
|
+
|
7
|
+
docnames = "{README,LICENSE,CHANGELOG,Changelog,HISTORY}"
|
8
|
+
doctypes = "{,.txt,.rd,.rdoc,.md,.markdown}"
|
9
|
+
cexttypes = "{c,C,cc,cxx,cpp,h,H,hh}"
|
10
|
+
|
11
|
+
DOC = FileList["#{docnames}{,.ja}#{doctypes}"] +
|
12
|
+
FileList["{contrib,ext}/**/#{docnames}{,.ja}#{doctypes}"] +
|
13
|
+
FileList["ext/**/*.#{cexttypes}"]
|
14
|
+
EXT = FileList["ext/**/*"]
|
15
|
+
BIN = FileList["bin/*"]
|
16
|
+
LIB = FileList["lib/**/*.rb"]
|
17
|
+
SPEC = FileList["spec/**/*"]
|
18
|
+
TEST = FileList["test/**/*"]
|
19
|
+
EXAMPLE = FileList["examples/**/*"]
|
20
|
+
GEMSTUB_SRC = "gemstub.rb"
|
21
|
+
RAKEFILE = [File.basename(__FILE__), GEMSTUB_SRC]
|
22
|
+
EXTRA = []
|
23
|
+
EXTCONF = FileList["ext/**/extconf.rb"]
|
24
|
+
EXTCONF.reject! { |n| !File.file?(n) }
|
25
|
+
EXTMAP = {}
|
26
|
+
|
27
|
+
load GEMSTUB_SRC
|
28
|
+
|
29
|
+
EXTMAP.dup.each_pair do |dir, name|
|
30
|
+
EXTMAP[Pathname.new(dir).cleanpath.to_s] = Pathname.new(name).cleanpath.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
GEMSTUB.extensions += EXTCONF
|
34
|
+
GEMSTUB.executables += FileList["bin/*"].map { |n| File.basename n }
|
35
|
+
GEMSTUB.executables.sort!
|
36
|
+
|
37
|
+
PACKAGENAME = "#{GEMSTUB.name}-#{GEMSTUB.version}"
|
38
|
+
GEMFILE = "#{PACKAGENAME}.gem"
|
39
|
+
GEMSPEC = "#{PACKAGENAME}.gemspec"
|
40
|
+
BUNDLER_GEMFILE = "Gemfile"
|
41
|
+
|
42
|
+
GEMSTUB.files += DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + RAKEFILE + EXTRA
|
43
|
+
GEMSTUB.files.sort!
|
44
|
+
if GEMSTUB.rdoc_options.nil? || GEMSTUB.rdoc_options.empty?
|
45
|
+
readme = %W(.md .markdown .rd .rdoc .txt #{""}).map { |ext| "README#{ext}" }.find { |m| DOC.find { |n| n == m } }
|
46
|
+
GEMSTUB.rdoc_options = %w(--charset UTF-8) + (readme ? %W(-m #{readme}) : [])
|
47
|
+
end
|
48
|
+
GEMSTUB.extra_rdoc_files += DOC + LIB + EXT.reject { |n| n.include?("/externals/") || !%w(.h .hh .c .cc .cpp .cxx).include?(File.extname(n)) }
|
49
|
+
GEMSTUB.extra_rdoc_files.sort!
|
50
|
+
|
51
|
+
GEMSTUB_TRYOUT = GEMSTUB.dup
|
52
|
+
GEMSTUB_TRYOUT.version = "#{GEMSTUB.version}#{Time.now.strftime(".TRYOUT.%Y%m%d.%H%M%S")}"
|
53
|
+
PACKAGENAME_TRYOUT = "#{GEMSTUB.name}-#{GEMSTUB_TRYOUT.version}"
|
54
|
+
GEMFILE_TRYOUT = "#{PACKAGENAME_TRYOUT}.gem"
|
55
|
+
GEMSPEC_TRYOUT = "#{PACKAGENAME_TRYOUT}.gemspec"
|
56
|
+
|
57
|
+
CLEAN << GEMSPEC << GEMSPEC_TRYOUT
|
58
|
+
CLOBBER << GEMFILE
|
59
|
+
|
60
|
+
task :default => :tryout do
|
61
|
+
$stderr.puts <<-EOS
|
62
|
+
#{__FILE__}:#{__LINE__}:
|
63
|
+
\ttype ``rake release'' to build release package.
|
64
|
+
EOS
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "build tryout package"
|
68
|
+
task :tryout
|
69
|
+
|
70
|
+
desc "build release package"
|
71
|
+
task :release => :all
|
72
|
+
|
73
|
+
unless EXTCONF.empty?
|
74
|
+
if RUBYSET.nil?
|
75
|
+
$stderr.puts <<-EOS
|
76
|
+
#{__FILE__}:
|
77
|
+
|
|
78
|
+
| If you want binary gem package, launch rake with ``RUBYSET`` enviroment
|
79
|
+
| variable for set ruby interpreters by comma separated.
|
80
|
+
|
|
81
|
+
| e.g.) $ rake RUBYSET=ruby
|
82
|
+
| or) $ rake RUBYSET=ruby21,ruby22,ruby23
|
83
|
+
|
|
84
|
+
EOS
|
85
|
+
else
|
86
|
+
platforms = RUBYSET.map { |ruby| `#{ruby} --disable-gems -e "puts RUBY_PLATFORM"`.chomp }
|
87
|
+
platforms1 = platforms.uniq
|
88
|
+
unless platforms1.size == 1 && !platforms1[0].empty?
|
89
|
+
abort <<-EOS
|
90
|
+
#{__FILE__}:#{__LINE__}: different platforms:
|
91
|
+
#{RUBYSET.zip(platforms).map { |ruby, platform| "%24s => %s" % [ruby, platform] }.join("\n")}
|
92
|
+
ABORTED.
|
93
|
+
EOS
|
94
|
+
end
|
95
|
+
PLATFORM = platforms1[0]
|
96
|
+
|
97
|
+
RUBY_VERSIONS = RUBYSET.map do |ruby|
|
98
|
+
ver = `#{ruby} --disable-gems -e "puts RUBY_VERSION"`.slice(/\d+\.\d+/)
|
99
|
+
raise "failed ruby checking - ``#{ruby}''" unless $?.success?
|
100
|
+
[ver, ruby]
|
101
|
+
end
|
102
|
+
|
103
|
+
SOFILES_SET = RUBY_VERSIONS.map { |(ver, ruby)|
|
104
|
+
EXTCONF.map { |extconf|
|
105
|
+
extdir = Pathname.new(extconf).cleanpath.dirname.to_s
|
106
|
+
case
|
107
|
+
when soname = EXTMAP[extdir.sub(/^ext\//i, "")]
|
108
|
+
soname = soname.sub(/\.so$/i, "")
|
109
|
+
when extdir == "ext" || extdir == "."
|
110
|
+
soname = GEMSTUB.name
|
111
|
+
else
|
112
|
+
soname = File.basename(extdir)
|
113
|
+
end
|
114
|
+
|
115
|
+
[ruby, File.join("lib", "#{soname.sub(/(?<=\/)|^(?!.*\/)/, "#{ver}/")}.so"), extconf]
|
116
|
+
}
|
117
|
+
}.flatten(1)
|
118
|
+
SOFILES = SOFILES_SET.map { |(ruby, sopath, extconf)| sopath }
|
119
|
+
|
120
|
+
GEMSTUB_NATIVE = GEMSTUB.dup
|
121
|
+
GEMSTUB_NATIVE.files += SOFILES
|
122
|
+
GEMSTUB_NATIVE.platform = Gem::Platform.new(PLATFORM).to_s
|
123
|
+
GEMSTUB_NATIVE.extensions.clear
|
124
|
+
GEMFILE_NATIVE = "#{GEMSTUB_NATIVE.name}-#{GEMSTUB_NATIVE.version}-#{GEMSTUB_NATIVE.platform}.gem"
|
125
|
+
GEMSPEC_NATIVE = "#{GEMSTUB_NATIVE.name}-#{GEMSTUB_NATIVE.platform}.gemspec"
|
126
|
+
|
127
|
+
task :all => ["native-gem", GEMFILE]
|
128
|
+
|
129
|
+
desc "build binary gem package"
|
130
|
+
task "native-gem" => GEMFILE_NATIVE
|
131
|
+
|
132
|
+
desc "generate binary gemspec"
|
133
|
+
task "native-gemspec" => GEMSPEC_NATIVE
|
134
|
+
|
135
|
+
file GEMFILE_NATIVE => DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + SOFILES + RAKEFILE + [GEMSPEC_NATIVE] do
|
136
|
+
sh "gem build #{GEMSPEC_NATIVE}"
|
137
|
+
end
|
138
|
+
|
139
|
+
file GEMSPEC_NATIVE => RAKEFILE do
|
140
|
+
File.write(GEMSPEC_NATIVE, GEMSTUB_NATIVE.to_ruby, mode: "wb")
|
141
|
+
end
|
142
|
+
|
143
|
+
desc "build c-extension libraries"
|
144
|
+
task "sofiles" => SOFILES
|
145
|
+
|
146
|
+
task "test" => SOFILES
|
147
|
+
|
148
|
+
SOFILES_SET.each do |(ruby, soname, extconf)|
|
149
|
+
sodir = File.dirname(soname)
|
150
|
+
makefile = File.join(sodir, "Makefile")
|
151
|
+
|
152
|
+
CLEAN << GEMSPEC_NATIVE << sodir
|
153
|
+
CLOBBER << GEMFILE_NATIVE
|
154
|
+
|
155
|
+
directory sodir
|
156
|
+
|
157
|
+
desc "generate Makefile for binary extension library"
|
158
|
+
file makefile => [sodir, extconf] do
|
159
|
+
rel_extconf = Pathname.new(extconf).relative_path_from(Pathname.new(sodir)).to_s
|
160
|
+
cd sodir do
|
161
|
+
sh *%W"#{ruby} #{rel_extconf} --ruby=#{ruby} #{ENV["EXTCONF"]}"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
desc "build binary extension library"
|
166
|
+
file soname => [makefile] + EXT do
|
167
|
+
cd sodir do
|
168
|
+
sh "make"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
task :all => GEMFILE
|
177
|
+
task :tryout => GEMFILE_TRYOUT
|
178
|
+
|
179
|
+
desc "generate local rdoc"
|
180
|
+
task :rdoc => DOC + LIB do
|
181
|
+
sh *(%w(rdoc) + GEMSTUB.rdoc_options + DOC + LIB)
|
182
|
+
end
|
183
|
+
|
184
|
+
desc "launch rspec"
|
185
|
+
task rspec: :all do
|
186
|
+
sh "rspec"
|
187
|
+
end
|
188
|
+
|
189
|
+
desc "test library"
|
190
|
+
task "test" do
|
191
|
+
(RUBYSET || ["ruby"]).each do |ruby|
|
192
|
+
lib = File.join(__dir__, "lib")
|
193
|
+
dir2 = __dir__.gsub(/[\[\{\*\?]/) { |m| "\\#{m}" }
|
194
|
+
Dir.glob(File.join(dir2, "test/**/test_*.rb")) do |test|
|
195
|
+
sh *%W(#{ruby} -I#{lib} #{test})
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
desc "build gem package"
|
201
|
+
task gem: GEMFILE
|
202
|
+
|
203
|
+
desc "generate gemspec"
|
204
|
+
task gemspec: GEMSPEC
|
205
|
+
|
206
|
+
desc "print package name"
|
207
|
+
task "package-name" do
|
208
|
+
puts PACKAGENAME
|
209
|
+
end
|
210
|
+
|
211
|
+
desc "generate Gemfile for bundler"
|
212
|
+
task "gemfile" => BUNDLER_GEMFILE
|
213
|
+
|
214
|
+
file GEMFILE => DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + RAKEFILE + [GEMSPEC] do
|
215
|
+
sh "gem build #{GEMSPEC}"
|
216
|
+
end
|
217
|
+
|
218
|
+
file GEMFILE_TRYOUT => DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + RAKEFILE + [GEMSPEC_TRYOUT] do
|
219
|
+
#file GEMFILE_TRYOUT do
|
220
|
+
sh "gem build #{GEMSPEC_TRYOUT}"
|
221
|
+
end
|
222
|
+
|
223
|
+
file GEMSPEC => RAKEFILE do
|
224
|
+
File.write(GEMSPEC, GEMSTUB.to_ruby, mode: "wb")
|
225
|
+
end
|
226
|
+
|
227
|
+
file GEMSPEC_TRYOUT => RAKEFILE do
|
228
|
+
File.write(GEMSPEC_TRYOUT, GEMSTUB_TRYOUT.to_ruby, mode: "wb")
|
229
|
+
end
|
230
|
+
|
231
|
+
file BUNDLER_GEMFILE => RAKEFILE do
|
232
|
+
File.write(BUNDLER_GEMFILE, <<~GemfileSource, mode: "wb")
|
233
|
+
source "https://rubygems.org/"
|
234
|
+
|
235
|
+
group "default" do
|
236
|
+
#{GEMSTUB.runtime_dependencies.map { |e|
|
237
|
+
%( gem #{e.name.inspect}, #{e.requirements_list.map { |ee| ee.inspect }.join(", ")})
|
238
|
+
}.join("\n")}
|
239
|
+
end
|
240
|
+
|
241
|
+
group "development", "test" do
|
242
|
+
#{GEMSTUB.development_dependencies.map { |e|
|
243
|
+
%( gem #{e.name.inspect}, #{e.requirements_list.map { |ee| ee.inspect }.join(", ")})
|
244
|
+
}.join("\n")}
|
245
|
+
end
|
246
|
+
GemfileSource
|
247
|
+
end
|
data/ext/compat.h
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
/*
|
2
|
+
* Licensed under Creative Commons Zero License (CC0; Public Domain)
|
3
|
+
*/
|
4
|
+
|
5
|
+
#ifndef AUX_COMPAT_H
|
6
|
+
|
7
|
+
// for older than 2.7.0
|
8
|
+
#ifndef RUBY_ASSERT_ALWAYS
|
9
|
+
# define RUBY_ASSERT_ALWAYS(...)
|
10
|
+
#endif
|
11
|
+
|
12
|
+
// for older than 3.0.0
|
13
|
+
#ifndef TRUE
|
14
|
+
# define TRUE 1
|
15
|
+
#endif
|
16
|
+
|
17
|
+
// for older than 3.0.0
|
18
|
+
#ifndef RB_EXT_RACTOR_SAFE
|
19
|
+
# define RB_EXT_RACTOR_SAFE(FEATURE)
|
20
|
+
#endif
|
21
|
+
|
22
|
+
// for older than 3.2.0
|
23
|
+
#ifndef RB_UNDEF_P
|
24
|
+
# define RB_UNDEF_P(OBJ) ((OBJ) == Qundef)
|
25
|
+
#endif
|
26
|
+
|
27
|
+
// for older than 3.2.0
|
28
|
+
#ifndef RB_NIL_OR_UNDEF_P
|
29
|
+
# define RB_NIL_OR_UNDEF_P(OBJ) (RB_NIL_P(OBJ) || RB_UNDEF_P(OBJ))
|
30
|
+
#endif
|
31
|
+
|
32
|
+
#endif // AUX_COMPAT_H
|
data/ext/extbzip3.c
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
#include "extbzip3.h"
|
2
|
+
|
3
|
+
static uint32_t
|
4
|
+
aux_version_code(const char *ver)
|
5
|
+
{
|
6
|
+
uint32_t code = 0;
|
7
|
+
const char *o = ver, *p = o;
|
8
|
+
int i = 4;
|
9
|
+
|
10
|
+
while (i > 0) {
|
11
|
+
if (*p == '\0' || *p == '.') {
|
12
|
+
char *pp = (char *)p;
|
13
|
+
unsigned long n = strtoul(o, &pp, 10);
|
14
|
+
code = (code << 8) | (uint32_t)n;
|
15
|
+
i--;
|
16
|
+
|
17
|
+
if (*p == '\0' || i <= 1) {
|
18
|
+
for (; i > 0; i--) {
|
19
|
+
code <<= 8;
|
20
|
+
}
|
21
|
+
|
22
|
+
break;
|
23
|
+
}
|
24
|
+
|
25
|
+
o = p + 1;
|
26
|
+
}
|
27
|
+
|
28
|
+
p++;
|
29
|
+
}
|
30
|
+
|
31
|
+
return code;
|
32
|
+
}
|
33
|
+
|
34
|
+
static VALUE
|
35
|
+
version_to_s(VALUE self)
|
36
|
+
{
|
37
|
+
return rb_iv_get(self, "LIBBZIP3_VERSION");
|
38
|
+
}
|
39
|
+
|
40
|
+
static void
|
41
|
+
init_version(VALUE bzip3_module)
|
42
|
+
{
|
43
|
+
RDOCFAKE(VALUE bzip3_module = rb_define_module("Bzip3"))
|
44
|
+
|
45
|
+
VALUE libver = rb_ary_new_capa(3);
|
46
|
+
const char *bz3ver = bz3_version();
|
47
|
+
uint32_t code = aux_version_code(bz3ver);
|
48
|
+
|
49
|
+
if (code < 0x01030200) {
|
50
|
+
const char *e = getenv("RUBY_EXTBZIP3_USE_BZIP3_1_3_1_OR_OLDER");
|
51
|
+
|
52
|
+
if (!e || strtol(e, NULL, 10) < 1) {
|
53
|
+
rb_raise(rb_eLoadError, "%s",
|
54
|
+
"YOU ARE USING AN BZIP3-1.3.1 OR OLDER LIBRARY.\n"
|
55
|
+
"PLEASE UPDATE TO BZIP3-1.3.2 OR A NEWER LIBRARY ON YOUR SYSTEM.\n"
|
56
|
+
"\n"
|
57
|
+
"BZIP3-1.3.1 OR OLDER HAS DATA COMPATIBILITY ISSUES.\n"
|
58
|
+
"IF YOU WANT TO FORCE THE USE OF EXTBZIP3,\n"
|
59
|
+
"PLEASE SET THE FOLLOWING ENVIRONMENT VARIABLES:\n"
|
60
|
+
"\n"
|
61
|
+
" RUBY_EXTBZIP3_USE_BZIP3_1_3_1_OR_OLDER=1");
|
62
|
+
} else {
|
63
|
+
rb_warn("%s",
|
64
|
+
"YOU ARE USING AN BZIP3-1.3.1 OR OLDER LIBRARY.\n"
|
65
|
+
"PLEASE UPDATE TO BZIP3-1.3.2 OR A NEWER LIBRARY ON YOUR SYSTEM.\n"
|
66
|
+
"\n"
|
67
|
+
"BZIP3-1.3.1 OR OLDER HAS DATA COMPATIBILITY ISSUES.\n"
|
68
|
+
"IF YOU CONTINUE USE, YOUR DATA WILL NOT BE ABLE TO BE MIGRATED IN THE FUTURE.");
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
rb_ary_push(libver, INT2FIX((code >> 24) & 0xff));
|
73
|
+
rb_ary_push(libver, INT2FIX((code >> 16) & 0xff));
|
74
|
+
rb_ary_push(libver, INT2FIX((code >> 8) & 0xff));
|
75
|
+
|
76
|
+
rb_iv_set(libver, "LIBBZIP3_VERSION", rb_str_new_static(bz3ver, strlen(bz3ver)));
|
77
|
+
rb_iv_set(libver, "LIBBZIP3_VERSION_CODE", UINT2NUM(code));
|
78
|
+
|
79
|
+
rb_define_singleton_method(libver, "to_s", version_to_s, 0);
|
80
|
+
rb_obj_freeze(libver);
|
81
|
+
|
82
|
+
rb_define_const(bzip3_module, "LIBRARY_VERSION", libver);
|
83
|
+
}
|
84
|
+
|
85
|
+
static void
|
86
|
+
init_constants(VALUE bzip3_module)
|
87
|
+
{
|
88
|
+
RDOCFAKE(VALUE bzip3_module = rb_define_module("Bzip3"))
|
89
|
+
|
90
|
+
rb_define_const(bzip3_module, "V1_FILE_FORMAT", INT2FIX(AUX_BZIP3_V1_FILE_FORMAT));
|
91
|
+
rb_define_const(bzip3_module, "V1_FRAME_FORMAT", INT2FIX(AUX_BZIP3_V1_FRAME_FORMAT));
|
92
|
+
rb_define_const(bzip3_module, "BLOCKSIZE_MIN", UINT2NUM(65 << 10));
|
93
|
+
rb_define_const(bzip3_module, "BLOCKSIZE_MAX", UINT2NUM(511 << 20));
|
94
|
+
}
|
95
|
+
|
96
|
+
struct block_processor
|
97
|
+
{
|
98
|
+
struct bz3_state *bzip3;
|
99
|
+
size_t blocksize;
|
100
|
+
};
|
101
|
+
|
102
|
+
#define BLOCK_PROCESSOR_FREE_BLOCK(P) \
|
103
|
+
if ((P)->bzip3) { \
|
104
|
+
bz3_free((P)->bzip3); \
|
105
|
+
} \
|
106
|
+
|
107
|
+
#define BLOCK_PROCESSOR_VALUE_FOREACH(DEF)
|
108
|
+
|
109
|
+
AUX_DEFINE_TYPED_DATA(block_processor, block_processor_allocate, BLOCK_PROCESSOR_FREE_BLOCK, BLOCK_PROCESSOR_VALUE_FOREACH)
|
110
|
+
|
111
|
+
/*
|
112
|
+
* @overload initialize(blocksize)
|
113
|
+
*/
|
114
|
+
static VALUE
|
115
|
+
block_processor_initialize(VALUE self, VALUE blocksize)
|
116
|
+
{
|
117
|
+
struct block_processor *p = get_block_processor_ptr(self);
|
118
|
+
if (p->bzip3 != NULL) {
|
119
|
+
rb_raise(rb_eTypeError, "wrong re-initializing - %" PRIsVALUE, self);
|
120
|
+
}
|
121
|
+
|
122
|
+
p->blocksize = NUM2UINT(blocksize);
|
123
|
+
|
124
|
+
if (p->blocksize < AUX_BZIP3_BLOCKSIZE_MIN) {
|
125
|
+
p->blocksize = AUX_BZIP3_BLOCKSIZE_MIN;
|
126
|
+
} else if (p->blocksize > AUX_BZIP3_BLOCKSIZE_MAX) {
|
127
|
+
rb_raise(rb_eRuntimeError, "blocksize too big - %" PRIsVALUE " (expect ..%u)",
|
128
|
+
blocksize, AUX_BZIP3_BLOCKSIZE_MAX);
|
129
|
+
}
|
130
|
+
|
131
|
+
p->bzip3 = aux_bz3_new((uint32_t)p->blocksize);
|
132
|
+
|
133
|
+
return self;
|
134
|
+
}
|
135
|
+
|
136
|
+
static VALUE
|
137
|
+
block_processor_blocksize(VALUE self)
|
138
|
+
{
|
139
|
+
return SIZET2NUM(get_block_processor(self)->blocksize);
|
140
|
+
}
|
141
|
+
|
142
|
+
static VALUE
|
143
|
+
block_processor_decode(VALUE self, VALUE src, VALUE dest, VALUE originalsize)
|
144
|
+
{
|
145
|
+
rb_check_type(src, RUBY_T_STRING);
|
146
|
+
rb_check_type(dest, RUBY_T_STRING);
|
147
|
+
|
148
|
+
struct block_processor *p = get_block_processor(self);
|
149
|
+
|
150
|
+
size_t origsize = NUM2SIZET(originalsize);
|
151
|
+
if (origsize > (size_t)p->blocksize) {
|
152
|
+
rb_raise(rb_eRuntimeError, "originalsize too big - %" PRIsVALUE, originalsize);
|
153
|
+
}
|
154
|
+
|
155
|
+
size_t srclen = RSTRING_LEN(src);
|
156
|
+
size_t destcapa = bz3_bound((uint32_t)origsize);
|
157
|
+
rb_str_modify(dest);
|
158
|
+
rb_str_set_len(dest, 0);
|
159
|
+
rb_str_modify_expand(dest, destcapa);
|
160
|
+
|
161
|
+
memmove(RSTRING_PTR(dest), RSTRING_PTR(src), srclen);
|
162
|
+
int32_t ret = aux_bz3_decode_block_nogvl(p->bzip3, RSTRING_PTR(dest), srclen, NUM2UINT(originalsize));
|
163
|
+
extbzip3_check_error(ret);
|
164
|
+
|
165
|
+
rb_str_set_len(dest, ret);
|
166
|
+
|
167
|
+
return dest;
|
168
|
+
}
|
169
|
+
|
170
|
+
static VALUE
|
171
|
+
block_processor_encode(VALUE self, VALUE src, VALUE dest)
|
172
|
+
{
|
173
|
+
rb_check_type(src, RUBY_T_STRING);
|
174
|
+
rb_check_type(dest, RUBY_T_STRING);
|
175
|
+
|
176
|
+
struct block_processor *p = get_block_processor(self);
|
177
|
+
|
178
|
+
size_t srclen = RSTRING_LEN(src);
|
179
|
+
if (srclen > p->blocksize) {
|
180
|
+
rb_raise(rb_eRuntimeError, "src too big - #<%" PRIsVALUE ":0x%" PRIxVALUE ">", rb_class_of(src), src);
|
181
|
+
}
|
182
|
+
|
183
|
+
size_t destcapa = bz3_bound((uint32_t)srclen);
|
184
|
+
rb_str_modify(dest);
|
185
|
+
rb_str_set_len(dest, 0);
|
186
|
+
rb_str_modify_expand(dest, (uint32_t)destcapa);
|
187
|
+
|
188
|
+
memmove(RSTRING_PTR(dest), RSTRING_PTR(src), srclen);
|
189
|
+
int32_t ret = aux_bz3_encode_block_nogvl(p->bzip3, RSTRING_PTR(dest), (int32_t)srclen);
|
190
|
+
extbzip3_check_error(ret);
|
191
|
+
|
192
|
+
rb_str_set_len(dest, ret);
|
193
|
+
|
194
|
+
return dest;
|
195
|
+
}
|
196
|
+
|
197
|
+
static void
|
198
|
+
init_processor(VALUE bzip3_module)
|
199
|
+
{
|
200
|
+
VALUE block_processor_class = rb_define_class_under(bzip3_module, "BlockProcessor", rb_cObject);
|
201
|
+
rb_define_alloc_func(block_processor_class, block_processor_allocate);
|
202
|
+
rb_define_method(block_processor_class, "initialize", block_processor_initialize, 1);
|
203
|
+
rb_define_method(block_processor_class, "blocksize", block_processor_blocksize, 0);
|
204
|
+
rb_define_method(block_processor_class, "decode", block_processor_decode, 3);
|
205
|
+
rb_define_method(block_processor_class, "encode", block_processor_encode, 2);
|
206
|
+
}
|
207
|
+
|
208
|
+
EXTBZIP3_API void
|
209
|
+
Init_extbzip3(void)
|
210
|
+
{
|
211
|
+
RB_EXT_RACTOR_SAFE(true);
|
212
|
+
|
213
|
+
VALUE bzip3_module = rb_define_module("Bzip3");
|
214
|
+
|
215
|
+
init_version(bzip3_module);
|
216
|
+
init_constants(bzip3_module);
|
217
|
+
init_processor(bzip3_module);
|
218
|
+
extbzip3_init_decoder(bzip3_module);
|
219
|
+
extbzip3_init_encoder(bzip3_module);
|
220
|
+
}
|