extlz4 0.2.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,151 @@
1
+ /*
2
+ *
3
+ * This code is under public domain (CC0)
4
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
5
+ *
6
+ * To the extent possible under law, dearblue has waived all copyright
7
+ * and related or neighboring rights to this work.
8
+ *
9
+ * dearblue <dearblue@users.noreply.github.com>
10
+ */
11
+
12
+ #include "hashargs.h"
13
+
14
+ struct rbx_scanhash_args
15
+ {
16
+ struct rbx_scanhash_arg *args;
17
+ const struct rbx_scanhash_arg *end;
18
+ VALUE rest;
19
+ };
20
+
21
+ static void
22
+ rbx_scanhash_error(ID given, struct rbx_scanhash_arg *args, const struct rbx_scanhash_arg *end)
23
+ {
24
+ // 引数の数が㌧でもない数の場合、よくないことが起きそう。
25
+
26
+ VALUE names = rb_ary_new();
27
+ for (; args < end; args ++) {
28
+ rb_ary_push(names, ID2SYM(args->name));
29
+ }
30
+
31
+ size_t namenum = RARRAY_LEN(names);
32
+ if (namenum > 2) {
33
+ VALUE w = rb_ary_pop(names);
34
+ names = rb_ary_join(names, rb_str_new_cstr(", "));
35
+ names = rb_ary_new4(1, &names);
36
+ rb_ary_push(names, w);
37
+ names = rb_ary_join(names, rb_str_new_cstr(" or "));
38
+ } else if (namenum > 1) {
39
+ names = rb_ary_join(names, rb_str_new_cstr(" or "));
40
+ }
41
+
42
+ {
43
+ VALUE key = rb_sym_to_s(ID2SYM(given));
44
+ rb_raise(rb_eArgError,
45
+ "unknown keyword (%s for %s)",
46
+ StringValueCStr(key), StringValueCStr(names));
47
+ }
48
+ }
49
+
50
+ static inline ID
51
+ rbx_scanhash_intern(VALUE key)
52
+ {
53
+ if (RB_TYPE_P(key, RUBY_T_SYMBOL)) {
54
+ return SYM2ID(key);
55
+ } else {
56
+ key = rb_String(key);
57
+ return rb_intern_str(key);
58
+ }
59
+ }
60
+
61
+ static int
62
+ rbx_scanhash_foreach(VALUE key, VALUE value, struct rbx_scanhash_args *args)
63
+ {
64
+ struct rbx_scanhash_arg *p = args->args;
65
+ const struct rbx_scanhash_arg *end = args->end;
66
+ ID keyid = rbx_scanhash_intern(key);
67
+
68
+ for (; p < end; p ++) {
69
+ if (p->name == keyid) {
70
+ if (p->dest) {
71
+ *p->dest = value;
72
+ }
73
+ return 0;
74
+ }
75
+ }
76
+
77
+ if (RTEST(args->rest)) {
78
+ rb_hash_aset(args->rest, key, value);
79
+ } else {
80
+ rbx_scanhash_error(keyid, args->args, args->end);
81
+ }
82
+
83
+ return 0;
84
+ }
85
+
86
+ static VALUE
87
+ rbx_scanhash_to_hash(VALUE hash)
88
+ {
89
+ if (NIL_P(hash)) { return Qnil; }
90
+
91
+ static ID id_to_hash;
92
+ if (!id_to_hash) { id_to_hash = rb_intern_const("to_hash"); }
93
+ VALUE hash1 = rb_funcall2(hash, id_to_hash, 0, 0);
94
+ if (TYPE(hash1) != T_HASH) {
95
+ rb_raise(rb_eTypeError,
96
+ "converted object is not a hash (<#%s:%p>)",
97
+ rb_obj_classname(hash), (void *)hash);
98
+ }
99
+ return hash1;
100
+ }
101
+
102
+ static inline void
103
+ rbx_scanhash_setdefaults(struct rbx_scanhash_arg *args, struct rbx_scanhash_arg *end)
104
+ {
105
+ for (; args < end; args ++) {
106
+ if (args->dest) {
107
+ *args->dest = args->initval;
108
+ }
109
+ }
110
+ }
111
+
112
+
113
+ static inline void
114
+ rbx_scanhash_check_missingkeys(struct rbx_scanhash_arg *args, struct rbx_scanhash_arg *end)
115
+ {
116
+ for (; args < end; args ++) {
117
+ if (args->dest && *args->dest == Qundef) {
118
+ VALUE key = rb_sym_to_s(ID2SYM(args->name));
119
+ rb_raise(rb_eArgError,
120
+ "missing keyword: `%s'",
121
+ StringValueCStr(key));
122
+ }
123
+ }
124
+ }
125
+
126
+ VALUE
127
+ rbx_scanhash(VALUE hash, VALUE rest, struct rbx_scanhash_arg *args, struct rbx_scanhash_arg *end)
128
+ {
129
+ if (RTEST(rest)) {
130
+ if (rest == Qtrue) {
131
+ rest = rb_hash_new();
132
+ } else if (!rb_obj_is_kind_of(rest, rb_cHash)) {
133
+ rb_raise(rb_eArgError,
134
+ "`rest' is not a hash");
135
+ }
136
+ } else {
137
+ rest = Qnil;
138
+ }
139
+
140
+ rbx_scanhash_setdefaults(args, end);
141
+
142
+ hash = rbx_scanhash_to_hash(hash);
143
+ if (!NIL_P(hash) && !RHASH_EMPTY_P(hash)) {
144
+ struct rbx_scanhash_args argset = { args, end, rest };
145
+ rb_hash_foreach(hash, rbx_scanhash_foreach, (VALUE)&argset);
146
+ }
147
+
148
+ rbx_scanhash_check_missingkeys(args, end);
149
+
150
+ return rest;
151
+ }
@@ -0,0 +1,110 @@
1
+ /*
2
+ *
3
+ * This code is under public domain (CC0)
4
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
5
+ *
6
+ * To the extent possible under law, dearblue has waived all copyright
7
+ * and related or neighboring rights to this work.
8
+ *
9
+ * dearblue <dearblue@users.noreply.github.com>
10
+ */
11
+
12
+ #ifndef RBX_HASHARGS_H
13
+ #define RBX_HASHARGS_H 1
14
+
15
+ #include <ruby.h>
16
+ #include <ruby/intern.h>
17
+
18
+ #define RBX_SCANHASH_ELEMENTOF(v) (sizeof((v)) / sizeof((v)[0]))
19
+ #define RBX_SCANHASH_ENDOF(v) ((v) + RBX_SCANHASH_ELEMENTOF(v))
20
+
21
+ #if defined(__cplusplus__)
22
+ # define RBX_SCANHASH_CEXTERN extern "C"
23
+ # define RBX_SCANHASH_CEXTERN_BEGIN RBX_SCANHASH_CEXTERN {
24
+ # define RBX_SCANHASH_CEXTERN_END }
25
+ #else
26
+ # define RBX_SCANHASH_CEXTERN
27
+ # define RBX_SCANHASH_CEXTERN_BEGIN
28
+ # define RBX_SCANHASH_CEXTERN_END
29
+ #endif
30
+
31
+ RBX_SCANHASH_CEXTERN_BEGIN
32
+
33
+ struct rbx_scanhash_arg
34
+ {
35
+ ID name;
36
+ VALUE *dest;
37
+ VALUE initval;
38
+ };
39
+
40
+ /*
41
+ * RBX_SCANHASH マクロから呼ばれる
42
+ */
43
+ VALUE rbx_scanhash(VALUE hash, VALUE rest, struct rbx_scanhash_arg *args, struct rbx_scanhash_arg *end);
44
+
45
+ /**
46
+ * メソッドが受け取るキーワード引数を解析します。
47
+ *
48
+ * マクロ引数はそれぞれが一度だけ評価されます (多重評価はされません)。
49
+ *
50
+ * 可変長部分の引数 (第3引数以降) の評価順は全ての環境で左から右に固定されます。
51
+ *
52
+ * 第1引数と第2引数の評価順は環境依存となります。
53
+ *
54
+ * @param hash
55
+ * 解析対象のハッシュオブジェクト。nil の場合、受け取り変数を初期化するだけです。
56
+ * @param rest
57
+ * 解析後に残ったキーワードを受け取るハッシュオブジェクトを指定します。
58
+ * true を指定した場合、内部で新規ハッシュオブジェクトを用意します。
59
+ * NULL / false / nil の場合、任意キーワードの受け取りを認めません。
60
+ * @param ...
61
+ * RBX_SCANHASH_ARG[SI] が並びます。終端を表すものの記述は不要です。
62
+ * @return
63
+ * 受け取り対象外のハッシュオブジェクト (rest で与えたもの) が返ります。
64
+ *
65
+ * @sample
66
+ *
67
+ * // 走査するハッシュオブジェクト
68
+ * VALUE user_hash_object = rb_hash_new();
69
+ *
70
+ * VALUE a, b, c, d, e, f; // これらの変数に受け取る
71
+ * RBX_SCANHASH(user_hash_object, Qnil,
72
+ * RBX_SCANHASH_ARGS("a", &a, Qnil),
73
+ * RBX_SCANHASH_ARGS("b", &b, Qtrue),
74
+ * RBX_SCANHASH_ARGS("c", &c, rb_str_new_cstr("abcdefg")),
75
+ * RBX_SCANHASH_ARGS("d", &d, INT2FIX(5)));
76
+ *
77
+ * RBX_SCANHASH_ARG 系の第2引数に NULL を与えると、名前の確認だけして、Cレベルの変数への代入は行わない。
78
+ * RBX_SCANHASH_ARGS("e", NULL, Qnil)
79
+ *
80
+ * RBX_SCANHASH_ARG 系の第3引数に Qundef を与えると、省略不可キーワード引数となる
81
+ * RBX_SCANHASH_ARGS("f", &f, Qundef)
82
+ */
83
+ #define RBX_SCANHASH(hash, rest, ...) \
84
+ ({ \
85
+ struct rbx_scanhash_arg RBX_SCANHASH_argv[] = { __VA_ARGS__ }; \
86
+ rbx_scanhash((hash), (rest), RBX_SCANHASH_argv, \
87
+ RBX_SCANHASH_ENDOF(RBX_SCANHASH_argv)); \
88
+ }) \
89
+
90
+ /*
91
+ * 評価順は左から右に固定される。
92
+ *
93
+ * [name] C の文字列を与える
94
+ * [dest] キーワード引数の代入先。NULL を指定した場合、名前の確認だけして、Cレベルの変数への代入は行わない
95
+ * [vdefault] 規定値。Qundef を指定した場合、省略不可キーワードとなる
96
+ */
97
+ #define RBX_SCANHASH_ARGS(name, dest, vdefault) { rb_intern((name)), (dest), (vdefault), }
98
+
99
+ /*
100
+ * 評価順は左から右に固定される。
101
+ *
102
+ * [name] ruby の ID をあたえる。
103
+ * [dest] キーワード引数の代入先。NULL を指定した場合、名前の確認だけして、Cレベルの変数への代入は行わない
104
+ * [vdefault] 規定値。Qundef を指定した場合、省略不可キーワードとなる
105
+ */
106
+ #define RBX_SCANHASH_ARGI(name, dest, vdefault) { (name), (dest), (vdefault), }
107
+
108
+ RBX_SCANHASH_CEXTERN_END
109
+
110
+ #endif /* !defined(RBX_HASHARGS_H) */
@@ -0,0 +1,31 @@
1
+ #if RBEXT_VISIBILITY
2
+ # define visibility(v) visibility("hidden")
3
+ #endif
4
+
5
+ #include "../contrib/lz4/lib/lz4.c"
6
+
7
+ #define LZ4_isLittleEndian amalg_LZ4_isLittleEndian
8
+ #define LZ4_read16 amalg_LZ4_read16
9
+ #define LZ4_read32 amalg_LZ4_read32
10
+ #define LZ4_read_ARCH amalg_LZ4_read_ARCH
11
+ #define LZ4_write16 amalg_LZ4_write16
12
+ #define LZ4_write32 amalg_LZ4_write32
13
+ #define LZ4_readLE16 amalg_LZ4_readLE16
14
+ #define LZ4_writeLE16 amalg_LZ4_writeLE16
15
+ #define LZ4_copy8 amalg_LZ4_copy8
16
+ #define LZ4_wildCopy amalg_LZ4_wildCopy
17
+ #define LZ4_minLength amalg_LZ4_minLength
18
+ #define LZ4_NbCommonBytes amalg_LZ4_NbCommonBytes
19
+ #define LZ4_count amalg_LZ4_count
20
+ #define limitedOutput amalg_limitedOutput
21
+ #define limitedOutput_directive amalg_limitedOutput_directive
22
+ #define unalign amalg_unalign
23
+ #include "../contrib/lz4/lib/lz4hc.c"
24
+
25
+ #undef ALLOCATOR
26
+ #undef KB
27
+ #undef MB
28
+ #undef GB
29
+ #include "../contrib/lz4/lib/lz4frame.c"
30
+
31
+ #include "../contrib/lz4/lib/xxhash.c"
@@ -0,0 +1,40 @@
1
+ unless File.read("README.md", 4096) =~ /^\s*\*\s*version:{1,2}\s*(.+)/i
2
+ raise "バージョン情報が README.md に見つかりません"
3
+ end
4
+
5
+ ver = $1
6
+ verfile = "lib/extlz4/version.rb"
7
+ LIB << verfile
8
+
9
+ file verfile => "README.md" do |*args|
10
+ File.binwrite args[0].name, <<-VERSION_FILE
11
+ module LZ4
12
+ VERSION = "#{ver}"
13
+ end
14
+ VERSION_FILE
15
+ end
16
+
17
+
18
+ unmatch = %r(\bcontrib/lz4/(?:Makefile|appveyor\.yml|contrib|doc|examples|lib/Makefile|lib/dll|programs|tests|visual)(?:$|/))
19
+
20
+ DOC.reject! { |e| e =~ unmatch }
21
+
22
+ contrib = FileList["contrib/**/*"]
23
+ contrib.reject! { |e| e =~ unmatch }
24
+ EXTRA.concat(contrib)
25
+
26
+
27
+ GEMSTUB = Gem::Specification.new do |s|
28
+ s.name = "extlz4"
29
+ s.version = ver
30
+ s.summary = "ruby bindings for LZ4"
31
+ s.description = <<EOS
32
+ ruby bindings for LZ4 <https://github.com/lz4/lz4>.
33
+ EOS
34
+ s.homepage = "https://github.com/dearblue/ruby-extlz4"
35
+ s.license = "BSD-2-Clause"
36
+ s.author = "dearblue"
37
+ s.email = "dearblue@users.noreply.github.com"
38
+
39
+ s.add_development_dependency "rake"
40
+ end
@@ -0,0 +1,327 @@
1
+ #vim: set fileencoding:utf-8
2
+
3
+ require "stringio"
4
+
5
+ ver = RUBY_VERSION[/\d+\.\d+/]
6
+ soname = File.basename(__FILE__, ".rb") << ".so"
7
+ require_relative File.join(ver, soname)
8
+
9
+ require_relative "extlz4/version"
10
+
11
+ #
12
+ # LZ4 data and streaming data processor.
13
+ #
14
+ module LZ4
15
+ LZ4 = self
16
+
17
+ #
18
+ # call-seq:
19
+ # decode_file(inpath, outpath) -> nil
20
+ #
21
+ # Decode lz4 file to regular file.
22
+ #
23
+ # [RETURN]
24
+ # Return nil always.
25
+ #
26
+ # [inpath]
27
+ # Give input file path, or input IO (liked) object its has ``read'' method.
28
+ #
29
+ # [outpath]
30
+ # Give output file path, or output IO (liked) object its has ``<<'' method.
31
+ #
32
+ def self.decode_file(inpath, outpath)
33
+ open_file(inpath, "rb") do |infile|
34
+ decode(infile) do |lz4|
35
+ open_file(outpath, "wb") do |outfile|
36
+ inbuf = ""
37
+ slicesize = 1 << 20
38
+ outfile << inbuf while lz4.read(slicesize, inbuf)
39
+ end
40
+ end
41
+ end
42
+
43
+ nil
44
+ end
45
+
46
+ #
47
+ # call-seq:
48
+ # encode_file(inpath, outpath, level = 1, opts = {}) -> nil
49
+ #
50
+ # Encode regular file to lz4 file.
51
+ #
52
+ # [RETURN]
53
+ # Return nil always.
54
+ #
55
+ # [inpath]
56
+ # Give input file path, or input IO (liked) object its has ``read'' method.
57
+ #
58
+ # [outpath]
59
+ # Give output file path, or output IO (liked) object its has ``<<'' method.
60
+ #
61
+ # [level = 1 (Integer)]
62
+ # See LZ4.encode method.
63
+ #
64
+ # [opts = {} (Hash)]
65
+ # See LZ4.encode method.
66
+ #
67
+ def self.encode_file(inpath, outpath, *args, **opts)
68
+ open_file(inpath, "rb") do |infile|
69
+ open_file(outpath, "wb") do |outfile|
70
+ encode(outfile, *args, **opts) do |lz4|
71
+ inbuf = ""
72
+ slicesize = 1 << 20
73
+ lz4 << inbuf while infile.read(slicesize, inbuf)
74
+ end
75
+ end
76
+ end
77
+
78
+ nil
79
+ end
80
+
81
+ def self.test_file(inpath)
82
+ open_file(inpath, "rb") do |infile|
83
+ decode(infile) do |lz4|
84
+ inbuf = ""
85
+ slicesize = 1 << 20
86
+ nil while lz4.read(slicesize, inbuf)
87
+ end
88
+ end
89
+
90
+ nil
91
+ end
92
+
93
+ def self.open_file(file, mode)
94
+ case
95
+ when file.kind_of?(String)
96
+ File.open(file, mode, &proc)
97
+ when file.respond_to?(:binmode)
98
+ file.binmode rescue nil
99
+ yield(file)
100
+ else
101
+ yield(file)
102
+ end
103
+ end
104
+
105
+ #
106
+ # call-seq:
107
+ # encode(source_string, level = 1, opts = {}) -> lz4 frame'd data
108
+ # encode(output_io, level = 1, opts = {}) -> stream encoder
109
+ # encode(output_io, level = 1, opts = {}) { |stream_encoder| ... } -> yield_status
110
+ #
111
+ # Encode to LZ4 Frame data. This is available streaming process.
112
+ #
113
+ # Created data is decodable by lz4-cli.
114
+ #
115
+ # ==== Common parameters
116
+ #
117
+ # [level = 1 (Integer)]
118
+ # 圧縮レベルを指定します。0 から 9 までの整数値が指定出来ます。
119
+ #
120
+ # 現時点では lz4cli (lz4io) に倣って、3以下が標準圧縮、4以上が高圧縮となります。
121
+ #
122
+ # 4以上の値は、高効率圧縮器の圧縮レベルとして渡されます。
123
+ #
124
+ # [blocklink: false (true or false)]
125
+ # Enable or disable block dependency funcion. Default is false.
126
+ #
127
+ # 真を与えた場合、ストリームの圧縮効率が向上します。
128
+ #
129
+ # [checksum: true (true or false)]
130
+ # ストリーム全体のチェックサム (XXhash32) の有効・無効を切り替えます。
131
+ #
132
+ # ==== encode(source_string, level = 1, opts = {}) -> encoded_data
133
+ #
134
+ # Basic encode method.
135
+ #
136
+ # [RETURN (String)]
137
+ # Encoded data as LZ4 stream
138
+ #
139
+ # [source_string (String)]
140
+ # LZ4 ストリームとして圧縮したいバイナリデータ列としての文字列です。
141
+ #
142
+ # 文字符号情報は無視されて純粋なバイナリデータ列として処理されます。
143
+ #
144
+ # ==== encode(output_io, level = 1, opts = {}) -> encoder
145
+ #
146
+ # Available streaming LZ4 Frame encode.
147
+ #
148
+ # Write to encoder for data encoding.
149
+ #
150
+ # After finished encode process, you must call Encoder#close.
151
+ #
152
+ # Return stream encoder if given an IO (liked) object.
153
+ #
154
+ # この圧縮器に『書き込む』ことでデータは圧縮されます。
155
+ # 圧縮処理を完了するときには #close を呼び出す必要があります。
156
+ #
157
+ # [RETURN (LZ4::Encoder)]
158
+ #
159
+ # [output_io (IO)]
160
+ # LZ4 ストリームの出力先を指定します。IO#<< と同等の機能を持つオブジェクトである必要があります。
161
+ #
162
+ # 一例を挙げると、IO、StringIO、Array などのインスタンスが当てはまります。
163
+ #
164
+ # ==== encode(output_io, level = 1, opts = {}) { |encoder| ... } -> yield_status
165
+ #
166
+ # IO オブジェクトとともにブロックを渡した場合、ブロック引数として圧縮器が渡されます。この場合は #close を呼び出す必要がありません。
167
+ #
168
+ # [RETURN]
169
+ # return value of given block
170
+ #
171
+ # [YIELD (encoder)]
172
+ #
173
+ # [YIELDRETURN]
174
+ # return as method return value
175
+ #
176
+ # ==== example: directly encode
177
+ #
178
+ # LZ4.encode("abcdefghijklmn") # => Encoded LZ4 stream data (string object)
179
+ #
180
+ # ==== example: streaming encode with block
181
+ #
182
+ # この用例は、encode_file の実装とほぼ同じです。丸写しで利用するよりは encode_file の利用を推奨します。
183
+ #
184
+ # File.open("hello.txt", "rb") do |src|
185
+ # File.open("hello.txt.lz4", "wb") do |dest|
186
+ # srcbuf = ""
187
+ # LZ4.encode(dest) do |lz4encoder|
188
+ # nil while lz4encoder << src.read(4096, srcbuf)
189
+ # end
190
+ # end
191
+ # end
192
+ #
193
+ def self.encode(*args, **opts)
194
+ if args.empty? || !args[0].kind_of?(String)
195
+ lz4 = LZ4::Encoder.new(*args, **opts)
196
+ return lz4 unless block_given?
197
+ begin
198
+ yield(lz4)
199
+ lz4.outport
200
+ ensure
201
+ lz4.close
202
+ end
203
+ else
204
+ obj = args.shift
205
+ outport = "".force_encoding(Encoding::BINARY)
206
+ lz4 = LZ4::Encoder.new(outport, *args, **opts)
207
+ lz4 << obj
208
+ lz4.close
209
+ outport
210
+ end
211
+ end
212
+
213
+ #
214
+ # call-seq:
215
+ # decode(encoded_data_string) -> decoded data
216
+ # decode(input_io) -> decoder
217
+ # decode(input_io) { |decoder| ... } -> yield_status
218
+ #
219
+ # Decode LZ4 Frame data. This is available streaming process.
220
+ #
221
+ # ==== decode(encoded_data_string)
222
+ #
223
+ # [RETURN (String)]
224
+ # decoded_data
225
+ #
226
+ # ==== decode(input_io)
227
+ #
228
+ # [RETURN (LZ4::Decoder)]
229
+ # ストリーム展開オブジェクトです。簡素な機能の読み込み専用IOオブジェクトとして扱うことが出来ます。
230
+ #
231
+ # decoder は GC によって開放処理が行われますが、利用しなくなった時点で利用者が明示的に close を呼び出すことが望まれます。
232
+ #
233
+ # [input_io (IO)]
234
+ # This is IO like object. Need read method. 'extlz4' is call as <tt>read(size, buf)</tt> style.
235
+ #
236
+ # ==== decode(input_io) { |decoder| ... }
237
+ #
238
+ # [RETURN]
239
+ # returned value from given block
240
+ #
241
+ # [YIELD (decoder)]
242
+ # ブロックなしで与えた場合の戻り値と等価です。
243
+ #
244
+ # ただしこちらはブロックを抜けたらすぐに開放処理が実施されます。利用者が明示的に close を呼んだり、GC されるのを待ったりせずに行われると言うことです。
245
+ #
246
+ # ==== example: directly decode
247
+ #
248
+ # LZ4.decode(lz4_encoded_string) # => decoded binary string
249
+ #
250
+ # ==== example: streaming decode
251
+ #
252
+ # File.open("sample.lz4", "rb") do |fd|
253
+ # LZ4.decode(fd) do |lz4dec|
254
+ # lz4dec.read(16) # string with read 16 bytes
255
+ # lz4dec.getbyte # integer with a byte
256
+ # lz4dec.read # string with rest data
257
+ # end
258
+ # end
259
+ #
260
+ def self.decode(obj, *args)
261
+ if obj.kind_of?(String)
262
+ lz4 = Decoder.new(StringIO.new(obj), *args)
263
+ dest = lz4.read
264
+ lz4.close
265
+ return (dest || "".b)
266
+ end
267
+
268
+ lz4 = Decoder.new(obj, *args)
269
+ return lz4 unless block_given?
270
+
271
+ begin
272
+ yield(lz4)
273
+ ensure
274
+ lz4.close
275
+ end
276
+ end
277
+
278
+ def self.block_encode(*args)
279
+ BlockEncoder.encode(*args)
280
+ end
281
+
282
+ def self.block_decode(*args)
283
+ BlockDecoder.decode(*args)
284
+ end
285
+
286
+ #
287
+ # Call LZ4::BlockEncoder.new.
288
+ #
289
+ def self.block_stream_encode(*args)
290
+ lz4 = BlockEncoder.new(*args)
291
+ return lz4 unless block_given?
292
+
293
+ begin
294
+ yield(lz4)
295
+ ensure
296
+ lz4.release rescue nil
297
+ end
298
+ end
299
+
300
+ #
301
+ # Call LZ4::BlockDecoder.new.
302
+ #
303
+ def self.block_stream_decode(*args)
304
+ lz4 = BlockDecoder.new(*args)
305
+ return lz4 unless block_given?
306
+
307
+ begin
308
+ yield(lz4)
309
+ rescue
310
+ lz4.release rescue nil
311
+ end
312
+ end
313
+
314
+ class << self
315
+ alias compress encode
316
+ alias decompress decode
317
+ alias uncompress decode
318
+ alias block_compress block_encode
319
+ alias block_decompress block_decode
320
+ alias block_uncompress block_decode
321
+ alias block_stream_compress block_stream_encode
322
+ alias block_stream_decompress block_stream_decode
323
+ alias block_stream_uncompress block_stream_decode
324
+ end
325
+ end
326
+
327
+ require_relative "extlz4/compat"