extlz4 0.2.4.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.
- checksums.yaml +7 -0
- data/HISTORY.ja.md +116 -0
- data/LICENSE +24 -0
- data/README.md +203 -0
- data/Rakefile +212 -0
- data/bin/extlz4 +220 -0
- data/contrib/lz4/INSTALL +15 -0
- data/contrib/lz4/LICENSE +11 -0
- data/contrib/lz4/NEWS +231 -0
- data/contrib/lz4/README.md +114 -0
- data/contrib/lz4/circle.yml +39 -0
- data/contrib/lz4/lib/LICENSE +24 -0
- data/contrib/lz4/lib/README.md +73 -0
- data/contrib/lz4/lib/liblz4.pc.in +14 -0
- data/contrib/lz4/lib/lz4.c +1478 -0
- data/contrib/lz4/lib/lz4.h +463 -0
- data/contrib/lz4/lib/lz4frame.c +1669 -0
- data/contrib/lz4/lib/lz4frame.h +391 -0
- data/contrib/lz4/lib/lz4frame_static.h +143 -0
- data/contrib/lz4/lib/lz4hc.c +807 -0
- data/contrib/lz4/lib/lz4hc.h +278 -0
- data/contrib/lz4/lib/lz4opt.h +366 -0
- data/contrib/lz4/lib/xxhash.c +894 -0
- data/contrib/lz4/lib/xxhash.h +293 -0
- data/examples/frameapi.rb +43 -0
- data/ext/blockapi.c +1046 -0
- data/ext/depend +4 -0
- data/ext/extconf.rb +60 -0
- data/ext/extlz4.c +69 -0
- data/ext/extlz4.h +109 -0
- data/ext/frameapi.c +780 -0
- data/ext/hashargs.c +151 -0
- data/ext/hashargs.h +110 -0
- data/ext/lz4_amalgam.c +31 -0
- data/gemstub.rb +40 -0
- data/lib/extlz4.rb +327 -0
- data/lib/extlz4/compat.rb +12 -0
- data/lib/extlz4/fix-0.1bug.rb +96 -0
- data/lib/extlz4/oldstream.rb +529 -0
- data/lib/extlz4/version.rb +3 -0
- data/test/common.rb +18 -0
- data/test/test_blockapi.rb +105 -0
- data/test/test_frameapi.rb +59 -0
- metadata +126 -0
data/ext/hashargs.c
ADDED
@@ -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
|
+
}
|
data/ext/hashargs.h
ADDED
@@ -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) */
|
data/ext/lz4_amalgam.c
ADDED
@@ -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"
|
data/gemstub.rb
ADDED
@@ -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
|
data/lib/extlz4.rb
ADDED
@@ -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"
|