liblzma 0.2
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/README.txt +43 -0
- data/ext/extconf.rb +11 -0
- data/ext/liblzma.c +1027 -0
- data/lib/liblzma.rb +131 -0
- data/samples/01-easy_using.rb +58 -0
- data/samples/02-streaming.rb +82 -0
- metadata +53 -0
data/README.txt
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding:utf-8
|
2
|
+
|
3
|
+
= liblzma for Ruby
|
4
|
+
|
5
|
+
- AUTHOR : dearblue
|
6
|
+
- MAIL : dearblue@users.sourceforge.jp
|
7
|
+
- LICENSE : 2-clause BSD License (二条項BSDライセンス)
|
8
|
+
- PROJECTPAGE : http://sourceforge.jp/projects/rutsubo/
|
9
|
+
|
10
|
+
This document is written in Japanese.
|
11
|
+
|
12
|
+
|
13
|
+
== はじめに
|
14
|
+
|
15
|
+
xzユーティリティに含まれるliblzmaのRubyバインディングです。
|
16
|
+
|
17
|
+
gemパッケージになっており、『gem install liblzma-0.2.gem』でビルド、インストールが完了します。
|
18
|
+
|
19
|
+
MinGW32およびFreeBSD 9.0R i386で動作確認を行っています。
|
20
|
+
|
21
|
+
MinGW32向けにはバイナリパッケージも用意してあります (もしかしたらruby-mswin32でも動作するかもしれません)。
|
22
|
+
|
23
|
+
FreeBSD 9.0R i386 上では標準コンパイラであるGCCのほかにllvm clangでもビルド可能なことを確認してあります。
|
24
|
+
|
25
|
+
|
26
|
+
== 利用できる主な機能
|
27
|
+
|
28
|
+
※カッコ内は、本来のliblzmaが提供する関数を示す
|
29
|
+
|
30
|
+
* LZMA::Stream::Encoder/Decoder (lzma_stream_encoder / lzma_stream_decoder)
|
31
|
+
* LZMA::Stream::RawEncoder/RawDecoder (lzma_raw_encoder / lzma_raw_decoder)
|
32
|
+
* LZMA::Utils.crc32/crc64 (lzma_crc32 / lzma_crc64)
|
33
|
+
* LZMA::Filter::LZMA1/LZMA2/Delta
|
34
|
+
|
35
|
+
|
36
|
+
== 実際に利用するには
|
37
|
+
|
38
|
+
まともな文書化が出来ていないため、gemパッケージ内の『samples』ディレクトリに含まれる各サンプルを頼りにして下さい。
|
39
|
+
|
40
|
+
|
41
|
+
== ライセンスについて
|
42
|
+
|
43
|
+
liblzma for Ruby は、二条項BSDライセンスの下で利用できます。
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
|
3
|
+
have_header "lzma.h" or raise "need lzma.h"
|
4
|
+
have_library "lzma" or raise "need liblzma.a"
|
5
|
+
create_makefile "liblzma"
|
6
|
+
|
7
|
+
# Makefile から、『-L.』を取り除く
|
8
|
+
# (本来のliblzma.aではなく、これから作成するliblzma.soへの結合を抑止するため)
|
9
|
+
mf = File.read("Makefile", mode: "r:binary")
|
10
|
+
mf.gsub!(/(?<=\s)-L\.(?=\s|$)/, " ")
|
11
|
+
File.write("Makefile", mf, mode: "wb")
|
data/ext/liblzma.c
ADDED
@@ -0,0 +1,1027 @@
|
|
1
|
+
/*
|
2
|
+
* liblzma.c -
|
3
|
+
* Author:: dearblue <dearblue@sourceforge.jp>
|
4
|
+
* Copyright:: Copyright (c) 2010 dearblue
|
5
|
+
* License:: Distributed under the 2-clause BSD License
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include <ruby.h>
|
9
|
+
#include <ruby/intern.h>
|
10
|
+
#include <lzma.h>
|
11
|
+
|
12
|
+
|
13
|
+
static VALUE mLZMA;
|
14
|
+
|
15
|
+
|
16
|
+
static VALUE symDICTSIZE;
|
17
|
+
static VALUE symPRESETDICT;
|
18
|
+
static VALUE symLC;
|
19
|
+
static VALUE symLP;
|
20
|
+
static VALUE symPB;
|
21
|
+
static VALUE symMODE;
|
22
|
+
static VALUE symNICE;
|
23
|
+
static VALUE symMF;
|
24
|
+
static VALUE symDEPTH;
|
25
|
+
static VALUE symCHECK;
|
26
|
+
|
27
|
+
|
28
|
+
static inline int
|
29
|
+
lzma_isfailed(lzma_ret status)
|
30
|
+
{
|
31
|
+
return status != 0;
|
32
|
+
}
|
33
|
+
|
34
|
+
|
35
|
+
// SECTION: LZMA::Constants
|
36
|
+
|
37
|
+
static VALUE mConstants;
|
38
|
+
|
39
|
+
static void
|
40
|
+
setup_constants(void)
|
41
|
+
{
|
42
|
+
mConstants = rb_define_module_under(mLZMA, "Constants");
|
43
|
+
rb_include_module(mLZMA, mConstants);
|
44
|
+
|
45
|
+
#define DEFINE_CONSTANT(NAME, VALUE) \
|
46
|
+
{ \
|
47
|
+
rb_define_const(mConstants, #NAME, VALUE); \
|
48
|
+
rb_define_const(mConstants, "LZMA_" #NAME, VALUE); \
|
49
|
+
} \
|
50
|
+
|
51
|
+
DEFINE_CONSTANT(NICE_DEFAULT, SIZET2NUM(64));
|
52
|
+
DEFINE_CONSTANT(DEPTH_DEFAULT, SIZET2NUM(0));
|
53
|
+
|
54
|
+
DEFINE_CONSTANT(PRESET_DEFAULT, UINT2NUM(LZMA_PRESET_DEFAULT));
|
55
|
+
DEFINE_CONSTANT(PRESET_LEVEL_MASK, UINT2NUM(LZMA_PRESET_LEVEL_MASK));
|
56
|
+
DEFINE_CONSTANT(PRESET_EXTREME, UINT2NUM(LZMA_PRESET_EXTREME));
|
57
|
+
DEFINE_CONSTANT(DICT_SIZE_MIN, UINT2NUM(LZMA_DICT_SIZE_MIN));
|
58
|
+
DEFINE_CONSTANT(DICT_SIZE_DEFAULT, UINT2NUM(LZMA_DICT_SIZE_DEFAULT));
|
59
|
+
DEFINE_CONSTANT(LCLP_MIN, UINT2NUM(LZMA_LCLP_MIN));
|
60
|
+
DEFINE_CONSTANT(LCLP_MAX, UINT2NUM(LZMA_LCLP_MAX));
|
61
|
+
DEFINE_CONSTANT(LC_DEFAULT, UINT2NUM(LZMA_LC_DEFAULT));
|
62
|
+
DEFINE_CONSTANT(LP_DEFAULT, UINT2NUM(LZMA_LP_DEFAULT));
|
63
|
+
DEFINE_CONSTANT(PB_MIN, UINT2NUM(LZMA_PB_MIN));
|
64
|
+
DEFINE_CONSTANT(PB_MAX, UINT2NUM(LZMA_PB_MAX));
|
65
|
+
DEFINE_CONSTANT(PB_DEFAULT, UINT2NUM(LZMA_PB_DEFAULT));
|
66
|
+
DEFINE_CONSTANT(MODE_FAST, UINT2NUM(LZMA_MODE_FAST));
|
67
|
+
DEFINE_CONSTANT(MODE_NORMAL, UINT2NUM(LZMA_MODE_NORMAL));
|
68
|
+
DEFINE_CONSTANT(MF_HC3, UINT2NUM(LZMA_MF_HC3));
|
69
|
+
DEFINE_CONSTANT(MF_HC4, UINT2NUM(LZMA_MF_HC4));
|
70
|
+
DEFINE_CONSTANT(MF_BT2, UINT2NUM(LZMA_MF_BT2));
|
71
|
+
DEFINE_CONSTANT(MF_BT3, UINT2NUM(LZMA_MF_BT3));
|
72
|
+
DEFINE_CONSTANT(MF_BT4, UINT2NUM(LZMA_MF_BT4));
|
73
|
+
|
74
|
+
DEFINE_CONSTANT(CHECK_NONE, UINT2NUM(LZMA_CHECK_NONE));
|
75
|
+
DEFINE_CONSTANT(CHECK_CRC32, UINT2NUM(LZMA_CHECK_CRC32));
|
76
|
+
DEFINE_CONSTANT(CHECK_CRC64, UINT2NUM(LZMA_CHECK_CRC64));
|
77
|
+
DEFINE_CONSTANT(CHECK_SHA256, UINT2NUM(LZMA_CHECK_SHA256));
|
78
|
+
|
79
|
+
DEFINE_CONSTANT(RUN, UINT2NUM(LZMA_RUN));
|
80
|
+
DEFINE_CONSTANT(FULL_FLUSH, UINT2NUM(LZMA_FULL_FLUSH));
|
81
|
+
DEFINE_CONSTANT(SYNC_FLUSH, UINT2NUM(LZMA_SYNC_FLUSH));
|
82
|
+
DEFINE_CONSTANT(FINISH, UINT2NUM(LZMA_FINISH));
|
83
|
+
|
84
|
+
#undef DEFINE_CONSTANT
|
85
|
+
}
|
86
|
+
|
87
|
+
|
88
|
+
// SECTION: LZMA::Exceptions
|
89
|
+
|
90
|
+
static VALUE mExceptions;
|
91
|
+
|
92
|
+
static VALUE eBasicException;
|
93
|
+
static VALUE eStreamEnd;
|
94
|
+
static VALUE eNoCheck;
|
95
|
+
static VALUE eUnsupportedCheck;
|
96
|
+
static VALUE eGetCheck;
|
97
|
+
static VALUE eMemError;
|
98
|
+
static VALUE eMemlimitError;
|
99
|
+
static VALUE eFormatError;
|
100
|
+
static VALUE eOptionsError;
|
101
|
+
static VALUE eDataError;
|
102
|
+
static VALUE eBufError;
|
103
|
+
static VALUE eProgError;
|
104
|
+
static VALUE eFilterTooLong;
|
105
|
+
static VALUE eBadPreset;
|
106
|
+
|
107
|
+
static inline VALUE
|
108
|
+
lookup_exception(lzma_ret status)
|
109
|
+
{
|
110
|
+
switch (status) {
|
111
|
+
case LZMA_OK: return Qnil;
|
112
|
+
case LZMA_STREAM_END: return eStreamEnd;
|
113
|
+
case LZMA_NO_CHECK: return eNoCheck;
|
114
|
+
case LZMA_UNSUPPORTED_CHECK: return eUnsupportedCheck;
|
115
|
+
case LZMA_GET_CHECK: return eGetCheck;
|
116
|
+
case LZMA_MEM_ERROR: return eMemError;
|
117
|
+
case LZMA_MEMLIMIT_ERROR: return eMemlimitError;
|
118
|
+
case LZMA_FORMAT_ERROR: return eFormatError;
|
119
|
+
case LZMA_OPTIONS_ERROR: return eOptionsError;
|
120
|
+
case LZMA_DATA_ERROR: return eDataError;
|
121
|
+
case LZMA_BUF_ERROR: return eBufError;
|
122
|
+
case LZMA_PROG_ERROR: return eProgError;
|
123
|
+
default: return rb_eRuntimeError;
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
static void
|
128
|
+
setup_exceptions(void)
|
129
|
+
{
|
130
|
+
mExceptions = rb_define_module_under(mLZMA, "Exceptions");
|
131
|
+
rb_include_module(mLZMA, mExceptions);
|
132
|
+
|
133
|
+
eBasicException = rb_define_class_under(mExceptions, "BasicException", rb_eStandardError);
|
134
|
+
rb_define_class_under(mExceptions, "FilterTooLong", eBasicException);
|
135
|
+
rb_define_class_under(mExceptions, "BadPreset", eBasicException);
|
136
|
+
|
137
|
+
#define DEFINE_EXCEPTION(CLASS, STATUS) \
|
138
|
+
{ \
|
139
|
+
e ## CLASS = rb_define_class_under(mExceptions, #CLASS, eBasicException); \
|
140
|
+
rb_define_const(e ## CLASS, "STATUS", SIZET2NUM(STATUS)); \
|
141
|
+
} \
|
142
|
+
|
143
|
+
DEFINE_EXCEPTION(StreamEnd, LZMA_STREAM_END);
|
144
|
+
DEFINE_EXCEPTION(NoCheck, LZMA_NO_CHECK);
|
145
|
+
DEFINE_EXCEPTION(UnsupportedCheck, LZMA_UNSUPPORTED_CHECK);
|
146
|
+
DEFINE_EXCEPTION(GetCheck, LZMA_GET_CHECK);
|
147
|
+
DEFINE_EXCEPTION(MemError, LZMA_MEM_ERROR);
|
148
|
+
DEFINE_EXCEPTION(MemlimitError, LZMA_MEMLIMIT_ERROR);
|
149
|
+
DEFINE_EXCEPTION(FormatError, LZMA_FORMAT_ERROR);
|
150
|
+
DEFINE_EXCEPTION(OptionsError, LZMA_OPTIONS_ERROR);
|
151
|
+
DEFINE_EXCEPTION(DataError, LZMA_DATA_ERROR);
|
152
|
+
DEFINE_EXCEPTION(BufError, LZMA_BUF_ERROR);
|
153
|
+
DEFINE_EXCEPTION(ProgError, LZMA_PROG_ERROR);
|
154
|
+
#undef DEFINE_EXCEPTION
|
155
|
+
}
|
156
|
+
|
157
|
+
|
158
|
+
// SECTION: LZMA::Filter
|
159
|
+
|
160
|
+
static VALUE cFilter;
|
161
|
+
static VALUE cBasicLZMA;
|
162
|
+
static VALUE cLZMA1;
|
163
|
+
static VALUE cLZMA2;
|
164
|
+
static VALUE cDelta;
|
165
|
+
|
166
|
+
|
167
|
+
static inline lzma_filter *
|
168
|
+
getfilter(VALUE obj)
|
169
|
+
{
|
170
|
+
lzma_filter *filter;
|
171
|
+
Data_Get_Struct(obj, lzma_filter, filter);
|
172
|
+
return filter;
|
173
|
+
}
|
174
|
+
|
175
|
+
static void *
|
176
|
+
setup_lzma_preset(size_t preset)
|
177
|
+
{
|
178
|
+
lzma_options_lzma *lzma = xcalloc(sizeof(lzma_options_lzma), 1);
|
179
|
+
if (lzma_lzma_preset(lzma, preset)) {
|
180
|
+
rb_raise(rb_eArgError,
|
181
|
+
"wrong preset level (%d for 0..9) or wrong flag bit(s) (%08x)",
|
182
|
+
preset & LZMA_PRESET_LEVEL_MASK,
|
183
|
+
preset & ~LZMA_PRESET_LEVEL_MASK & ~LZMA_PRESET_EXTREME);
|
184
|
+
}
|
185
|
+
return (void *)(lzma);
|
186
|
+
}
|
187
|
+
|
188
|
+
static const char PRIVATE_DICTPRESET[] = "dict_preset";
|
189
|
+
|
190
|
+
static inline void
|
191
|
+
lzma_set_dict_0(lzma_options_lzma *filter, VALUE dict, VALUE self)
|
192
|
+
{
|
193
|
+
if (NIL_P(dict)) {
|
194
|
+
filter->preset_dict = NULL;
|
195
|
+
filter->preset_dict_size = 0;
|
196
|
+
} else {
|
197
|
+
if (TYPE(dict) != T_STRING) {
|
198
|
+
rb_raise(rb_eTypeError, "%s", "dict is not a String or nil");
|
199
|
+
}
|
200
|
+
dict = rb_str_new_frozen(dict);
|
201
|
+
filter->preset_dict = (uint8_t *)(RSTRING_PTR(dict));
|
202
|
+
filter->preset_dict_size = RSTRING_LEN(dict);
|
203
|
+
}
|
204
|
+
rb_iv_set(self, PRIVATE_DICTPRESET, dict);
|
205
|
+
}
|
206
|
+
|
207
|
+
static VALUE
|
208
|
+
lzma_set_dict(VALUE self, VALUE dict)
|
209
|
+
{
|
210
|
+
lzma_set_dict_0((lzma_options_lzma *)getfilter(self)->options, dict, self);
|
211
|
+
return self;
|
212
|
+
}
|
213
|
+
|
214
|
+
static VALUE
|
215
|
+
lzma_get_dict(VALUE self)
|
216
|
+
{
|
217
|
+
return rb_str_new_shared(rb_iv_get(self, PRIVATE_DICTPRESET));
|
218
|
+
}
|
219
|
+
|
220
|
+
|
221
|
+
#define DEFINE_ACCESSOR_ENTITY(NAME, MEMBER, DEFAULT) \
|
222
|
+
static inline void \
|
223
|
+
lzma_set_ ## NAME ## _0(lzma_options_lzma *filter, VALUE n) \
|
224
|
+
{ \
|
225
|
+
if (NIL_P(n)) { \
|
226
|
+
filter->MEMBER = DEFAULT; \
|
227
|
+
} else { \
|
228
|
+
filter->MEMBER = NUM2UINT(n); \
|
229
|
+
} \
|
230
|
+
} \
|
231
|
+
\
|
232
|
+
static VALUE \
|
233
|
+
lzma_set_ ## NAME(VALUE self, VALUE n) \
|
234
|
+
{ \
|
235
|
+
lzma_set_ ## NAME ## _0((lzma_options_lzma *)getfilter(self)->options, n); \
|
236
|
+
return self; \
|
237
|
+
} \
|
238
|
+
\
|
239
|
+
static VALUE \
|
240
|
+
lzma_get_ ## NAME(VALUE self) \
|
241
|
+
{ \
|
242
|
+
return UINT2NUM(((lzma_options_lzma *)getfilter(self)->options)->MEMBER); \
|
243
|
+
} \
|
244
|
+
|
245
|
+
DEFINE_ACCESSOR_ENTITY(dictsize, dict_size, LZMA_DICT_SIZE_DEFAULT) // lzma_set_dictsize_0, lzma_set_dictsize, lzma_set_lc
|
246
|
+
DEFINE_ACCESSOR_ENTITY(lc, lc, LZMA_LC_DEFAULT)
|
247
|
+
DEFINE_ACCESSOR_ENTITY(lp, lp, LZMA_LP_DEFAULT)
|
248
|
+
DEFINE_ACCESSOR_ENTITY(pb, pb, LZMA_PB_DEFAULT)
|
249
|
+
DEFINE_ACCESSOR_ENTITY(mode, mode, LZMA_MODE_NORMAL)
|
250
|
+
DEFINE_ACCESSOR_ENTITY(nice, nice_len, 64)
|
251
|
+
DEFINE_ACCESSOR_ENTITY(mf, mf, LZMA_MF_BT4)
|
252
|
+
DEFINE_ACCESSOR_ENTITY(depth, depth, 0)
|
253
|
+
|
254
|
+
#undef DEFINE_ACCESSOR_ENTITY
|
255
|
+
|
256
|
+
static void *
|
257
|
+
setup_lzma(VALUE obj, uint32_t preset,
|
258
|
+
VALUE dictsize, VALUE dictpreset, VALUE lc, VALUE lp, VALUE pb,
|
259
|
+
VALUE mode, VALUE nice, VALUE mf, VALUE depth)
|
260
|
+
{
|
261
|
+
lzma_options_lzma lzma = { 0 };
|
262
|
+
if (lzma_lzma_preset(&lzma, preset) != 0) {
|
263
|
+
rb_raise(eBadPreset, "bad preset (%08x)", preset);
|
264
|
+
}
|
265
|
+
|
266
|
+
if (RTEST(dictpreset)) { lzma_set_dict_0(&lzma, dictpreset, obj); }
|
267
|
+
|
268
|
+
#define SETVAR(NAME) \
|
269
|
+
if (RTEST(NAME)) { lzma_set_ ## NAME ## _0(&lzma, NAME); } \
|
270
|
+
|
271
|
+
SETVAR(dictsize);
|
272
|
+
SETVAR(lc);
|
273
|
+
SETVAR(lp);
|
274
|
+
SETVAR(pb);
|
275
|
+
SETVAR(mode);
|
276
|
+
SETVAR(nice);
|
277
|
+
SETVAR(mf);
|
278
|
+
SETVAR(depth);
|
279
|
+
|
280
|
+
#undef SETVAR
|
281
|
+
|
282
|
+
{
|
283
|
+
lzma_options_lzma *p = ALLOC(lzma_options_lzma);
|
284
|
+
memcpy(p, &lzma, sizeof(lzma));
|
285
|
+
return (void *)(p);
|
286
|
+
}
|
287
|
+
}
|
288
|
+
|
289
|
+
static void
|
290
|
+
cleanup_filter(lzma_filter *filter)
|
291
|
+
{
|
292
|
+
if (filter->options) { xfree(filter->options); }
|
293
|
+
xfree(filter);
|
294
|
+
}
|
295
|
+
|
296
|
+
|
297
|
+
static uint32_t
|
298
|
+
getpreset(VALUE preset)
|
299
|
+
{
|
300
|
+
if (NIL_P(preset)) {
|
301
|
+
return LZMA_PRESET_DEFAULT;
|
302
|
+
} else {
|
303
|
+
return NUM2UINT(preset);
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
/*
|
308
|
+
* call-seq:
|
309
|
+
* LZMA::Filter.lzma1(....)
|
310
|
+
*
|
311
|
+
* LZMA::Filter::LZMA1.newを呼ぶための補助機構である
|
312
|
+
*
|
313
|
+
* LZMA::Filter::LZMA1クラスの .new や #initialize を書き換えた場合はそれに従う
|
314
|
+
* (あくまで .new を呼ぶだけである)
|
315
|
+
*/
|
316
|
+
static VALUE
|
317
|
+
lzma1_new(int argc, VALUE argv[], VALUE self)
|
318
|
+
{
|
319
|
+
return rb_class_new_instance(argc, argv, cLZMA1);
|
320
|
+
}
|
321
|
+
|
322
|
+
/*
|
323
|
+
* call-seq:
|
324
|
+
* LZMA::Filter.lzma2(...)
|
325
|
+
*
|
326
|
+
* LZMA::Filter::LZMA2.new を呼ぶための補助機構である
|
327
|
+
*
|
328
|
+
* LZMA::Filter::LZMA2クラスの .new や #initialize を書き換えた場合はそれに従う
|
329
|
+
* (あくまで .new を呼ぶだけである)
|
330
|
+
*/
|
331
|
+
static VALUE
|
332
|
+
lzma2_new(int argc, VALUE argv[], VALUE self)
|
333
|
+
{
|
334
|
+
return rb_class_new_instance(argc, argv, cLZMA2);
|
335
|
+
}
|
336
|
+
|
337
|
+
/*
|
338
|
+
* call-seq:
|
339
|
+
* LZMA::Filter.delta(....)
|
340
|
+
*
|
341
|
+
* LZMA::Filter::Delta.newを呼ぶための補助機構である
|
342
|
+
*
|
343
|
+
* LZMA::Filter::Deltaクラスの .new や #initialize を書き換えた場合はそれに従う
|
344
|
+
* (あくまで .new を呼ぶだけである)
|
345
|
+
*/
|
346
|
+
static VALUE
|
347
|
+
delta_new(int argc, VALUE argv[], VALUE self)
|
348
|
+
{
|
349
|
+
return rb_class_new_instance(argc, argv, cDelta);
|
350
|
+
}
|
351
|
+
|
352
|
+
|
353
|
+
|
354
|
+
static inline VALUE
|
355
|
+
filter_alloc(VALUE klass, lzma_vli id)
|
356
|
+
{
|
357
|
+
lzma_filter *filter;
|
358
|
+
VALUE obj = Data_Make_Struct(klass, lzma_filter, NULL, cleanup_filter, filter);
|
359
|
+
memset(filter, 0, sizeof(*filter));
|
360
|
+
filter->id = id;
|
361
|
+
return obj;
|
362
|
+
}
|
363
|
+
|
364
|
+
static VALUE
|
365
|
+
lzma1_alloc(VALUE klass)
|
366
|
+
{
|
367
|
+
return filter_alloc(klass, LZMA_FILTER_LZMA1);
|
368
|
+
}
|
369
|
+
|
370
|
+
static VALUE
|
371
|
+
lzma2_alloc(VALUE klass)
|
372
|
+
{
|
373
|
+
return filter_alloc(klass, LZMA_FILTER_LZMA2);
|
374
|
+
}
|
375
|
+
|
376
|
+
static VALUE
|
377
|
+
delta_alloc(VALUE klass)
|
378
|
+
{
|
379
|
+
return filter_alloc(cDelta, LZMA_FILTER_DELTA);
|
380
|
+
}
|
381
|
+
|
382
|
+
/*
|
383
|
+
* call-seq:
|
384
|
+
* LZMA::Filter::Delta.new(dist = LZMA::DELTA_DIST_MIN)
|
385
|
+
*
|
386
|
+
* 差分フィルタ設定オブジェクトを返す。
|
387
|
+
*
|
388
|
+
* distは1要素あたりのバイト長で、1以上を指定する。
|
389
|
+
*
|
390
|
+
* 使用する場合多くの場合1で十分だろうし、音楽CDの音声データであれば2を指定するのがいいだろう。
|
391
|
+
*
|
392
|
+
* しかし元のデータによっては圧縮効率を低下させることがあるため、常に適用することはしないほうがいい。
|
393
|
+
*/
|
394
|
+
static VALUE
|
395
|
+
delta_init(int argc, VALUE argv[], VALUE self)
|
396
|
+
{
|
397
|
+
lzma_filter *filter = getfilter(self);
|
398
|
+
lzma_options_delta *delta = ALLOC(lzma_options_delta);
|
399
|
+
memset(delta, 0, sizeof(*delta));
|
400
|
+
|
401
|
+
VALUE preset = Qnil;
|
402
|
+
rb_scan_args(argc, argv, "01", &preset);
|
403
|
+
delta->type = LZMA_DELTA_TYPE_BYTE;
|
404
|
+
delta->dist = NIL_P(preset) ? LZMA_DELTA_DIST_MIN : NUM2UINT(preset);
|
405
|
+
filter->options = delta;
|
406
|
+
return self;
|
407
|
+
}
|
408
|
+
|
409
|
+
/*
|
410
|
+
* call-seq:
|
411
|
+
* LZMA::Filter::BasicLZMA.new(preset = LZMA::PRESET_DEFAULT, opts = { .... } ) -> filter
|
412
|
+
*
|
413
|
+
* フィルタ設定オブジェクトを返す。
|
414
|
+
*
|
415
|
+
* この段階で各値の確認を行うことはせず、*encoderに渡すときに初めて確認される
|
416
|
+
*
|
417
|
+
* 引数::
|
418
|
+
* 引数は、presetは整数で、続くoptsはハッシュであり、細かい調整を行う場合に指定する。
|
419
|
+
*
|
420
|
+
* どちらも任意に省略可能であり、presetを省略してoptsを指定することも可能である。
|
421
|
+
*
|
422
|
+
* preset:: プリセット値 (≒圧縮レベル) を0-9の範囲で指定する。既定値はLZMA::PRESET_DEFAULTである。
|
423
|
+
* dictsize:: 既定値はLZMA::DICT_SIZE_DEFAULT
|
424
|
+
* presetdict:: 既定値はnil
|
425
|
+
* lc:: 既定値はLZMA::LC_DEFAULT
|
426
|
+
* lp:: 既定値はLZMA::LP_DEFAULT
|
427
|
+
* pb:: 既定値はLZMA::PB_DEFAULT
|
428
|
+
* mode:: 既定値はLZMA::MODE_NORMAL
|
429
|
+
* nice:: 既定値はLZMA::NICE_DEFAULT
|
430
|
+
* mf:: 既定値はLZMA::MF_BT4
|
431
|
+
* depth:: 既定値はLZMA::DEPTH_DEFAULT
|
432
|
+
*/
|
433
|
+
static VALUE
|
434
|
+
lzma_init(int argc, VALUE argv[], VALUE self)
|
435
|
+
{
|
436
|
+
VALUE preset = Qnil;
|
437
|
+
VALUE opts = Qnil;
|
438
|
+
rb_scan_args(argc, argv, "01:", &preset, &opts);
|
439
|
+
lzma_filter *filter = getfilter(self);
|
440
|
+
if (NIL_P(opts)) {
|
441
|
+
filter->options = setup_lzma_preset(getpreset(preset));
|
442
|
+
} else {
|
443
|
+
filter->options = setup_lzma(self, getpreset(preset),
|
444
|
+
rb_hash_lookup(opts, symDICTSIZE),
|
445
|
+
rb_hash_lookup(opts, symPRESETDICT),
|
446
|
+
rb_hash_lookup(opts, symLC),
|
447
|
+
rb_hash_lookup(opts, symLP),
|
448
|
+
rb_hash_lookup(opts, symPB),
|
449
|
+
rb_hash_lookup(opts, symMODE),
|
450
|
+
rb_hash_lookup(opts, symNICE),
|
451
|
+
rb_hash_lookup(opts, symMF),
|
452
|
+
rb_hash_lookup(opts, symDEPTH));
|
453
|
+
}
|
454
|
+
return self;
|
455
|
+
}
|
456
|
+
|
457
|
+
/*
|
458
|
+
* Document-method: LZMA::Filter::BasicLZMA#dictsize
|
459
|
+
*
|
460
|
+
* call-seq:
|
461
|
+
* LZMA::Filter::BasicLZMA#dictsize -> 辞書サイズ (バイト長)
|
462
|
+
*
|
463
|
+
* 様々なフィルタ値の設定・取り出しを行う
|
464
|
+
*/
|
465
|
+
static void
|
466
|
+
setup_filter(void)
|
467
|
+
{
|
468
|
+
cFilter = rb_define_class_under(mLZMA, "Filter", rb_cObject);
|
469
|
+
rb_undef_alloc_func(cFilter);
|
470
|
+
rb_define_singleton_method(cFilter, "lzma1", RUBY_METHOD_FUNC(lzma1_new), -1);
|
471
|
+
rb_define_singleton_method(cFilter, "lzma2", RUBY_METHOD_FUNC(lzma2_new), -1);
|
472
|
+
rb_define_singleton_method(cFilter, "delta", RUBY_METHOD_FUNC(delta_new), -1);
|
473
|
+
|
474
|
+
cBasicLZMA = rb_define_class_under(cFilter, "BasicLZMA", cFilter);
|
475
|
+
rb_define_method(cBasicLZMA, "initialize", lzma_init, -1);
|
476
|
+
|
477
|
+
cLZMA1 = rb_define_class_under(cFilter, "LZMA1", cBasicLZMA);
|
478
|
+
rb_define_alloc_func(cLZMA1, lzma1_alloc);
|
479
|
+
|
480
|
+
cLZMA2 = rb_define_class_under(cFilter, "LZMA2", cBasicLZMA);
|
481
|
+
rb_define_alloc_func(cLZMA2, lzma2_alloc);
|
482
|
+
|
483
|
+
cDelta = rb_define_class_under(cFilter, "Delta", cFilter);
|
484
|
+
rb_define_alloc_func(cDelta, delta_alloc);
|
485
|
+
rb_define_method(cDelta, "initialize", delta_init, -1);
|
486
|
+
|
487
|
+
#define DEF_ACCESSOR(CLASS, NAME) \
|
488
|
+
rb_define_method(CLASS, #NAME, lzma_get_ ## NAME, 0); \
|
489
|
+
rb_define_method(CLASS, #NAME "=", lzma_set_ ## NAME, 1); \
|
490
|
+
|
491
|
+
DEF_ACCESSOR(cBasicLZMA, dictsize);
|
492
|
+
DEF_ACCESSOR(cBasicLZMA, dict);
|
493
|
+
DEF_ACCESSOR(cBasicLZMA, lc);
|
494
|
+
DEF_ACCESSOR(cBasicLZMA, lp);
|
495
|
+
DEF_ACCESSOR(cBasicLZMA, pb);
|
496
|
+
DEF_ACCESSOR(cBasicLZMA, mode);
|
497
|
+
DEF_ACCESSOR(cBasicLZMA, nice);
|
498
|
+
DEF_ACCESSOR(cBasicLZMA, mf);
|
499
|
+
DEF_ACCESSOR(cBasicLZMA, depth);
|
500
|
+
|
501
|
+
#undef DEF_ACCESSOR
|
502
|
+
}
|
503
|
+
|
504
|
+
|
505
|
+
// SECTION: LZMA::Stream
|
506
|
+
|
507
|
+
static VALUE cStream;
|
508
|
+
static VALUE cEncoder;
|
509
|
+
static VALUE cDecoder;
|
510
|
+
static VALUE cAutoDecoder;
|
511
|
+
static VALUE cRawEncoder;
|
512
|
+
static VALUE cRawDecoder;
|
513
|
+
|
514
|
+
|
515
|
+
#define LZMA_TEST(STATUS) \
|
516
|
+
{ \
|
517
|
+
lzma_ret _status = (STATUS); \
|
518
|
+
if (lzma_isfailed(_status)) { \
|
519
|
+
VALUE exc = lookup_exception(_status); \
|
520
|
+
rb_exc_raise(rb_exc_new3(exc, rb_class_name(exc))); \
|
521
|
+
} \
|
522
|
+
} \
|
523
|
+
|
524
|
+
static inline void
|
525
|
+
filter_copy(lzma_filter *dest, VALUE filter)
|
526
|
+
{
|
527
|
+
memcpy(dest, getfilter(filter), sizeof(*dest));
|
528
|
+
}
|
529
|
+
|
530
|
+
static void
|
531
|
+
stream_clear(lzma_stream *stream)
|
532
|
+
{
|
533
|
+
const lzma_stream init = LZMA_STREAM_INIT;
|
534
|
+
memcpy(stream, &init, sizeof(init));
|
535
|
+
}
|
536
|
+
|
537
|
+
static inline lzma_stream *
|
538
|
+
getstream(VALUE lzma)
|
539
|
+
{
|
540
|
+
lzma_stream *stream;
|
541
|
+
Data_Get_Struct(lzma, lzma_stream, stream);
|
542
|
+
return stream;
|
543
|
+
}
|
544
|
+
|
545
|
+
static inline void
|
546
|
+
stream_cleanup(lzma_stream *stream)
|
547
|
+
{
|
548
|
+
lzma_end(stream);
|
549
|
+
xfree(stream);
|
550
|
+
}
|
551
|
+
|
552
|
+
|
553
|
+
static inline int
|
554
|
+
is_sync(size_t sync)
|
555
|
+
{
|
556
|
+
return (sync == LZMA_SYNC_FLUSH || sync == LZMA_FULL_FLUSH || sync == LZMA_FINISH);
|
557
|
+
}
|
558
|
+
|
559
|
+
|
560
|
+
struct stream_update_args
|
561
|
+
{
|
562
|
+
lzma_stream *stream;
|
563
|
+
lzma_action action;
|
564
|
+
const uint8_t *src;
|
565
|
+
size_t srclen;
|
566
|
+
};
|
567
|
+
|
568
|
+
static VALUE
|
569
|
+
stream_update_1(struct stream_update_args *args)
|
570
|
+
{
|
571
|
+
VALUE dest = rb_str_new("", 0);
|
572
|
+
uint8_t buf[4 * 1024];
|
573
|
+
args->stream->next_in = args->src;
|
574
|
+
args->stream->avail_in = args->srclen;
|
575
|
+
while (args->stream->avail_in > 0 || is_sync(args->action)) {
|
576
|
+
do {
|
577
|
+
rb_thread_check_ints();
|
578
|
+
args->stream->next_out = buf;
|
579
|
+
args->stream->avail_out = sizeof(buf);
|
580
|
+
lzma_ret status = lzma_code(args->stream, args->action);
|
581
|
+
if (status == LZMA_STREAM_END) {
|
582
|
+
rb_str_buf_cat(dest, (const char *)buf, args->stream->next_out - buf);
|
583
|
+
return dest;
|
584
|
+
}
|
585
|
+
|
586
|
+
LZMA_TEST(status);
|
587
|
+
rb_str_buf_cat(dest, (const char *)buf, args->stream->next_out - buf);
|
588
|
+
} while (args->stream->next_out - buf > 0);
|
589
|
+
}
|
590
|
+
return dest;
|
591
|
+
}
|
592
|
+
|
593
|
+
static inline VALUE
|
594
|
+
stream_update_2(struct stream_update_args *args)
|
595
|
+
{
|
596
|
+
return rb_thread_blocking_region((VALUE (*)(void *))stream_update_1, args, RUBY_UBF_IO, NULL);
|
597
|
+
}
|
598
|
+
|
599
|
+
static inline VALUE
|
600
|
+
stream_update_3(VALUE src)
|
601
|
+
{
|
602
|
+
rb_str_unlocktmp(src);
|
603
|
+
return Qnil;
|
604
|
+
}
|
605
|
+
|
606
|
+
static inline VALUE
|
607
|
+
stream_update_0(lzma_stream *stream, lzma_action action, VALUE src)
|
608
|
+
{
|
609
|
+
if (RTEST(src)) {
|
610
|
+
StringValue(src);
|
611
|
+
rb_str_locktmp(src);
|
612
|
+
struct stream_update_args args = {
|
613
|
+
stream, action,
|
614
|
+
(const uint8_t *)RSTRING_PTR(src), RSTRING_LEN(src),
|
615
|
+
};
|
616
|
+
return rb_ensure(stream_update_2, (VALUE)&args, stream_update_3, src);
|
617
|
+
} else {
|
618
|
+
struct stream_update_args args = {
|
619
|
+
stream, action, NULL, 0,
|
620
|
+
};
|
621
|
+
return stream_update_2(&args);
|
622
|
+
}
|
623
|
+
}
|
624
|
+
|
625
|
+
/*
|
626
|
+
* call-seq:
|
627
|
+
* LZMA::Stream#update(src, flush = LZMA::RUN)
|
628
|
+
*
|
629
|
+
* データストリームとして渡されたsrcを圧縮/伸張します。
|
630
|
+
*
|
631
|
+
* [RETURN] Stringインスタンス
|
632
|
+
* [EXCEPTION] LZMA::Exceptions::BasicException
|
633
|
+
*/
|
634
|
+
static VALUE
|
635
|
+
stream_update(int argc, VALUE argv[], VALUE self)
|
636
|
+
{
|
637
|
+
VALUE src, flush1;
|
638
|
+
int flush;
|
639
|
+
if (rb_scan_args(argc, argv, "11", &src, &flush1) == 1) {
|
640
|
+
flush = LZMA_RUN;
|
641
|
+
} else {
|
642
|
+
flush = NUM2INT(flush1);
|
643
|
+
}
|
644
|
+
lzma_stream *stream = getstream(self);
|
645
|
+
return stream_update_0(stream, flush, src);
|
646
|
+
}
|
647
|
+
|
648
|
+
/*
|
649
|
+
* call-seq:
|
650
|
+
* LZMA::Stream#flush(fullsync = false)
|
651
|
+
*/
|
652
|
+
static VALUE
|
653
|
+
stream_flush(int argc, VALUE argv[], VALUE self)
|
654
|
+
{
|
655
|
+
VALUE fullsync = Qfalse;
|
656
|
+
rb_scan_args(argc, argv, "01", &fullsync);
|
657
|
+
lzma_stream *stream = getstream(self);
|
658
|
+
size_t sync = RTEST(fullsync) ? LZMA_FULL_FLUSH : LZMA_SYNC_FLUSH;
|
659
|
+
return stream_update_0(stream, sync, Qnil);
|
660
|
+
}
|
661
|
+
|
662
|
+
/*
|
663
|
+
* call-seq:
|
664
|
+
* LZMA::Stream#finish
|
665
|
+
*/
|
666
|
+
static VALUE
|
667
|
+
stream_finish(VALUE self)
|
668
|
+
{
|
669
|
+
lzma_stream *stream = getstream(self);
|
670
|
+
VALUE dest = stream_update_0(stream, LZMA_FINISH, Qnil);
|
671
|
+
|
672
|
+
lzma_end(stream);
|
673
|
+
stream_clear(stream);
|
674
|
+
|
675
|
+
return dest;
|
676
|
+
}
|
677
|
+
|
678
|
+
|
679
|
+
|
680
|
+
static VALUE
|
681
|
+
stream_alloc(VALUE klass)
|
682
|
+
{
|
683
|
+
lzma_stream *stream;
|
684
|
+
VALUE obj = Data_Make_Struct(klass, lzma_stream, NULL, stream_cleanup, stream);
|
685
|
+
stream_clear(stream);
|
686
|
+
return obj;
|
687
|
+
}
|
688
|
+
|
689
|
+
// filters0はLZMA::Filterクラスのinstanceを与えることができる
|
690
|
+
static void
|
691
|
+
filter_setup(lzma_filter filter[LZMA_FILTERS_MAX + 1], VALUE filters0[], VALUE *filters0end)
|
692
|
+
{
|
693
|
+
if ((filters0end - filters0) > LZMA_FILTERS_MAX) {
|
694
|
+
rb_raise(eFilterTooLong, "filter chain too long (max %d, but given %d)",
|
695
|
+
LZMA_FILTERS_MAX, filters0end - filters0);
|
696
|
+
}
|
697
|
+
for (; filters0 < filters0end; filters0 ++, filter ++) {
|
698
|
+
VALUE f = *filters0;
|
699
|
+
if (!rb_obj_is_kind_of(f, cFilter)) {
|
700
|
+
rb_raise(rb_eTypeError, "%s", "not a filter");
|
701
|
+
}
|
702
|
+
filter_copy(filter, f);
|
703
|
+
}
|
704
|
+
filter->id = LZMA_VLI_UNKNOWN;
|
705
|
+
filter->options = NULL;
|
706
|
+
}
|
707
|
+
|
708
|
+
|
709
|
+
// LZMA::Stream.encoder(filter1, filter2, ...., filterN, check: CRC64)
|
710
|
+
static VALUE
|
711
|
+
encoder_init(int argc, VALUE argv[], VALUE self)
|
712
|
+
{
|
713
|
+
VALUE vcheck;
|
714
|
+
rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &vcheck);
|
715
|
+
uint32_t check;
|
716
|
+
if (NIL_P(vcheck)) {
|
717
|
+
check = LZMA_CHECK_CRC64;
|
718
|
+
} else {
|
719
|
+
check = NUM2UINT(vcheck);
|
720
|
+
argc --;
|
721
|
+
}
|
722
|
+
lzma_filter filters[LZMA_FILTERS_MAX + 1];
|
723
|
+
memset(filters, 0, sizeof(filters));
|
724
|
+
filter_setup(filters, argv, argv + argc);
|
725
|
+
|
726
|
+
lzma_stream *stream = getstream(self);
|
727
|
+
LZMA_TEST(lzma_stream_encoder(stream, filters, check));
|
728
|
+
|
729
|
+
return self;
|
730
|
+
}
|
731
|
+
|
732
|
+
/*
|
733
|
+
* call-seq:
|
734
|
+
* LZMA::Stream::AutoDecoder.initialize(memlimit = nil, flags = nil)
|
735
|
+
*/
|
736
|
+
static VALUE
|
737
|
+
autodecoder_init(int argc, VALUE argv[], VALUE self)
|
738
|
+
{
|
739
|
+
VALUE memlimit0 = Qnil;
|
740
|
+
VALUE flags0 = Qnil;
|
741
|
+
uint64_t memlimit = UINT64_MAX;
|
742
|
+
uint32_t flags = 0;
|
743
|
+
rb_scan_args(argc, argv, "02", &memlimit0, &flags0);
|
744
|
+
if (!NIL_P(flags0)) { flags = NUM2SIZET(flags0); }
|
745
|
+
if (!NIL_P(memlimit0)) { memlimit = NUM2SIZET(memlimit0); }
|
746
|
+
|
747
|
+
lzma_stream *stream = getstream(self);
|
748
|
+
LZMA_TEST(lzma_auto_decoder(stream, memlimit, flags));
|
749
|
+
|
750
|
+
return self;
|
751
|
+
}
|
752
|
+
|
753
|
+
/*
|
754
|
+
* call-seq:
|
755
|
+
* LZMA::Stream::Decoder.initialize(memlimit = nil, flags = nil)
|
756
|
+
*/
|
757
|
+
static VALUE
|
758
|
+
decoder_init(int argc, VALUE argv[], VALUE self)
|
759
|
+
{
|
760
|
+
VALUE memlimit0 = Qnil;
|
761
|
+
VALUE flags0 = Qnil;
|
762
|
+
uint64_t memlimit = UINT64_MAX;
|
763
|
+
uint32_t flags = 0;
|
764
|
+
rb_scan_args(argc, argv, "02", &memlimit0, &flags0);
|
765
|
+
if (!NIL_P(flags0)) { flags = NUM2SIZET(flags0); }
|
766
|
+
if (!NIL_P(memlimit0)) { memlimit = NUM2SIZET(memlimit0); }
|
767
|
+
|
768
|
+
lzma_stream *stream = getstream(self);
|
769
|
+
LZMA_TEST(lzma_stream_decoder(stream, memlimit, flags));
|
770
|
+
|
771
|
+
return self;
|
772
|
+
}
|
773
|
+
|
774
|
+
/*
|
775
|
+
* call-seq:
|
776
|
+
* LZMA::Stream::RawEncoder.initialize(filter1 [ , filter2 [ , .... ] ]) -> encoder
|
777
|
+
*
|
778
|
+
* 生の (xzヘッダなどの付かない) LZMA1/2ストリームを構成する圧縮器機を生成する。
|
779
|
+
*
|
780
|
+
* filterは1つ以上4つまでを与える。
|
781
|
+
*/
|
782
|
+
static VALUE
|
783
|
+
rawencoder_init(int argc, VALUE argv[], VALUE self)
|
784
|
+
{
|
785
|
+
if (argc < 1 || argc > 4) {
|
786
|
+
rb_scan_args(argc, argv, "13", NULL, NULL, NULL, NULL);
|
787
|
+
}
|
788
|
+
lzma_filter filters[LZMA_FILTERS_MAX + 1];
|
789
|
+
memset(filters, 0, sizeof(filters));
|
790
|
+
filter_setup(filters, argv, argv + argc);
|
791
|
+
|
792
|
+
lzma_stream *stream = getstream(self);
|
793
|
+
LZMA_TEST(lzma_raw_encoder(stream, filters));
|
794
|
+
|
795
|
+
return self;
|
796
|
+
}
|
797
|
+
|
798
|
+
/*
|
799
|
+
* call-seq:
|
800
|
+
* LZMA::Stream::RawDecoder.initialize(filter1 [ , filter2 [ , .... ] ])
|
801
|
+
*/
|
802
|
+
static VALUE
|
803
|
+
rawdecoder_init(int argc, VALUE argv[], VALUE self)
|
804
|
+
{
|
805
|
+
if (argc < 1 || argc > 4) {
|
806
|
+
rb_scan_args(argc, argv, "13", NULL, NULL, NULL, NULL);
|
807
|
+
}
|
808
|
+
lzma_filter filters[LZMA_FILTERS_MAX + 1];
|
809
|
+
memset(filters, 0, sizeof(filters));
|
810
|
+
filter_setup(filters, argv, argv + argc);
|
811
|
+
|
812
|
+
lzma_stream *stream = getstream(self);
|
813
|
+
LZMA_TEST(lzma_raw_decoder(stream, filters));
|
814
|
+
|
815
|
+
return self;
|
816
|
+
}
|
817
|
+
|
818
|
+
static void
|
819
|
+
setup_stream(void)
|
820
|
+
{
|
821
|
+
cStream = rb_define_class_under(mLZMA, "Stream", rb_cObject);
|
822
|
+
rb_undef_alloc_func(cStream);
|
823
|
+
rb_define_method(cStream, "update", stream_update, -1);
|
824
|
+
rb_define_method(cStream, "flush", stream_flush, -1);
|
825
|
+
rb_define_method(cStream, "finish", stream_finish, 0);
|
826
|
+
|
827
|
+
cEncoder = rb_define_class_under(cStream, "Encoder", cStream);
|
828
|
+
rb_define_alloc_func(cEncoder, stream_alloc);
|
829
|
+
rb_define_method(cEncoder, "initialize", RUBY_METHOD_FUNC(encoder_init), -1);
|
830
|
+
|
831
|
+
cDecoder = rb_define_class_under(cStream, "Decoder", cStream);
|
832
|
+
rb_define_alloc_func(cDecoder, stream_alloc);
|
833
|
+
rb_define_method(cDecoder, "initialize", RUBY_METHOD_FUNC(decoder_init), -1);
|
834
|
+
|
835
|
+
cAutoDecoder = rb_define_class_under(cStream, "AutoDecoder", cStream);
|
836
|
+
rb_define_alloc_func(cAutoDecoder, stream_alloc);
|
837
|
+
rb_define_method(cAutoDecoder, "initialize", RUBY_METHOD_FUNC(autodecoder_init), -1);
|
838
|
+
|
839
|
+
cRawEncoder = rb_define_class_under(cStream, "RawEncoder", cStream);
|
840
|
+
rb_define_alloc_func(cRawEncoder, stream_alloc);
|
841
|
+
rb_define_method(cRawEncoder, "initialize", RUBY_METHOD_FUNC(rawencoder_init), -1);
|
842
|
+
|
843
|
+
cRawDecoder = rb_define_class_under(cStream, "RawDecoder", cStream);
|
844
|
+
rb_define_alloc_func(cRawDecoder, stream_alloc);
|
845
|
+
rb_define_method(cRawDecoder, "initialize", RUBY_METHOD_FUNC(rawdecoder_init), -1);
|
846
|
+
}
|
847
|
+
|
848
|
+
|
849
|
+
// SECTION: LZMA::Index
|
850
|
+
|
851
|
+
|
852
|
+
static VALUE cIndex;
|
853
|
+
static VALUE cIEncoder;
|
854
|
+
static VALUE cIDecoder;
|
855
|
+
|
856
|
+
static VALUE
|
857
|
+
iencoder_alloc(VALUE klass)
|
858
|
+
{
|
859
|
+
rb_raise(rb_eNotImpError, "%s", "IMPLEMENT ME!");
|
860
|
+
}
|
861
|
+
|
862
|
+
static VALUE
|
863
|
+
iencoder_init(int argc, VALUE argv[], VALUE self)
|
864
|
+
{
|
865
|
+
rb_raise(rb_eNotImpError, "%s", "IMPLEMENT ME!");
|
866
|
+
}
|
867
|
+
|
868
|
+
static VALUE
|
869
|
+
idecoder_alloc(VALUE klass)
|
870
|
+
{
|
871
|
+
rb_raise(rb_eNotImpError, "%s", "IMPLEMENT ME!");
|
872
|
+
}
|
873
|
+
|
874
|
+
static VALUE
|
875
|
+
idecoder_init(int argc, VALUE argv[], VALUE self)
|
876
|
+
{
|
877
|
+
rb_raise(rb_eNotImpError, "%s", "IMPLEMENT ME!");
|
878
|
+
}
|
879
|
+
|
880
|
+
|
881
|
+
static void
|
882
|
+
setup_index(void)
|
883
|
+
{
|
884
|
+
cIndex = rb_define_class_under(mLZMA, "Index", rb_cObject);
|
885
|
+
rb_undef_alloc_func(cIndex);
|
886
|
+
|
887
|
+
cIEncoder = rb_define_class_under(cIndex, "Encoder", cIndex);
|
888
|
+
rb_define_alloc_func(cIEncoder, iencoder_alloc);
|
889
|
+
rb_define_method(cIEncoder, "initialize", RUBY_METHOD_FUNC(iencoder_init), -1);
|
890
|
+
|
891
|
+
cIDecoder = rb_define_class_under(cIndex, "Decoder", cIndex);
|
892
|
+
rb_define_alloc_func(cIDecoder, idecoder_alloc);
|
893
|
+
rb_define_method(cIDecoder, "initialize", RUBY_METHOD_FUNC(idecoder_init), -1);
|
894
|
+
}
|
895
|
+
|
896
|
+
|
897
|
+
// SECTION: LZMA::Utils
|
898
|
+
|
899
|
+
struct utils_crc32_args
|
900
|
+
{
|
901
|
+
const uint8_t *ptr;
|
902
|
+
size_t len;
|
903
|
+
uint32_t crc;
|
904
|
+
};
|
905
|
+
|
906
|
+
static VALUE
|
907
|
+
utils_crc32_update(struct utils_crc32_args *args)
|
908
|
+
{
|
909
|
+
return UINT2NUM(lzma_crc32(args->ptr, args->len, args->crc));
|
910
|
+
}
|
911
|
+
|
912
|
+
/*
|
913
|
+
* call-seq:
|
914
|
+
* LZMA::Utils.crc32(string, crc = 0)
|
915
|
+
*
|
916
|
+
* liblzmaに含まれるlzma_crc32を呼び出します。
|
917
|
+
*/
|
918
|
+
static VALUE
|
919
|
+
utils_crc32(int argc, VALUE argv[], VALUE self)
|
920
|
+
{
|
921
|
+
VALUE src, crc;
|
922
|
+
rb_scan_args(argc, argv, "11", &src, &crc);
|
923
|
+
|
924
|
+
StringValue(src);
|
925
|
+
rb_str_locktmp(src);
|
926
|
+
|
927
|
+
struct utils_crc32_args args = {
|
928
|
+
(const uint8_t *)RSTRING_PTR(src),
|
929
|
+
RSTRING_LEN(src),
|
930
|
+
NIL_P(crc) ? 0 : NUM2UINT(crc),
|
931
|
+
};
|
932
|
+
|
933
|
+
crc = rb_thread_blocking_region((VALUE (*)(void *))utils_crc32_update, &args, RUBY_UBF_IO, NULL);
|
934
|
+
|
935
|
+
rb_str_unlocktmp(src);
|
936
|
+
|
937
|
+
return crc;
|
938
|
+
}
|
939
|
+
|
940
|
+
|
941
|
+
|
942
|
+
struct utils_crc64_args
|
943
|
+
{
|
944
|
+
const uint8_t *ptr;
|
945
|
+
size_t len;
|
946
|
+
uint64_t crc;
|
947
|
+
};
|
948
|
+
|
949
|
+
static VALUE
|
950
|
+
utils_crc64_update(struct utils_crc64_args *args)
|
951
|
+
{
|
952
|
+
return ULL2NUM(lzma_crc64(args->ptr, args->len, args->crc));
|
953
|
+
}
|
954
|
+
|
955
|
+
/*
|
956
|
+
* call-seq:
|
957
|
+
* LZMA::Utils.crc64(string, crc = 0)
|
958
|
+
*
|
959
|
+
* liblzmaに含まれるlzma_crc64を呼び出します。
|
960
|
+
*/
|
961
|
+
static VALUE
|
962
|
+
utils_crc64(int argc, VALUE argv[], VALUE self)
|
963
|
+
{
|
964
|
+
VALUE src, crc;
|
965
|
+
rb_scan_args(argc, argv, "11", &src, &crc);
|
966
|
+
|
967
|
+
StringValue(src);
|
968
|
+
rb_str_locktmp(src);
|
969
|
+
|
970
|
+
struct utils_crc64_args args = {
|
971
|
+
(const uint8_t *)RSTRING_PTR(src),
|
972
|
+
RSTRING_LEN(src),
|
973
|
+
NIL_P(crc) ? 0 : NUM2ULL(crc),
|
974
|
+
};
|
975
|
+
|
976
|
+
crc = rb_thread_blocking_region((VALUE (*)(void *))utils_crc64_update, &args, RUBY_UBF_IO, NULL);
|
977
|
+
|
978
|
+
rb_str_unlocktmp(src);
|
979
|
+
|
980
|
+
return crc;
|
981
|
+
}
|
982
|
+
|
983
|
+
|
984
|
+
static VALUE mUtils;
|
985
|
+
|
986
|
+
static void
|
987
|
+
setup_utils(void)
|
988
|
+
{
|
989
|
+
mUtils = rb_define_module_under(mLZMA, "Utils");
|
990
|
+
rb_include_module(mLZMA, mUtils);
|
991
|
+
rb_extend_object(mLZMA, mUtils);
|
992
|
+
|
993
|
+
// rb_define_module_functionを使わない理由は、rb_define_module_functionで定義すると
|
994
|
+
// インスタンスメソッドがprivateで定義されるため、その対策。
|
995
|
+
|
996
|
+
rb_extend_object(mUtils, mUtils);
|
997
|
+
|
998
|
+
rb_define_method(mUtils, "crc32", RUBY_METHOD_FUNC(utils_crc32), -1);
|
999
|
+
rb_define_method(mUtils, "crc64", RUBY_METHOD_FUNC(utils_crc64), -1);
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
|
1003
|
+
// SECTION: LZMA
|
1004
|
+
|
1005
|
+
void
|
1006
|
+
Init_liblzma(void)
|
1007
|
+
{
|
1008
|
+
symDICTSIZE = ID2SYM(rb_intern("dict_size"));
|
1009
|
+
symPRESETDICT = ID2SYM(rb_intern("preset_dict"));
|
1010
|
+
symLC = ID2SYM(rb_intern("lc"));
|
1011
|
+
symLP = ID2SYM(rb_intern("lp"));
|
1012
|
+
symPB = ID2SYM(rb_intern("pb"));
|
1013
|
+
symMODE = ID2SYM(rb_intern("mode"));
|
1014
|
+
symNICE = ID2SYM(rb_intern("nice"));
|
1015
|
+
symMF = ID2SYM(rb_intern("mf"));
|
1016
|
+
symDEPTH = ID2SYM(rb_intern("depth"));
|
1017
|
+
symCHECK = ID2SYM(rb_intern("check"));
|
1018
|
+
|
1019
|
+
mLZMA = rb_define_module("LZMA");
|
1020
|
+
|
1021
|
+
setup_utils();
|
1022
|
+
setup_constants();
|
1023
|
+
setup_exceptions();
|
1024
|
+
setup_filter();
|
1025
|
+
setup_stream();
|
1026
|
+
setup_index();
|
1027
|
+
}
|