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/depend
ADDED
data/ext/extconf.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
#!ruby
|
2
|
+
#vim: set fileencoding:utf-8
|
3
|
+
|
4
|
+
require "mkmf"
|
5
|
+
|
6
|
+
module MyExtensions
|
7
|
+
refine Object do
|
8
|
+
# ruby-2.3 から追加されたメソッドの確認と追加
|
9
|
+
|
10
|
+
unless Object.method_defined?(:append_cppflags)
|
11
|
+
def append_cppflags(flags)
|
12
|
+
return false unless try_cppflags(flags)
|
13
|
+
$CPPFLAGS << " #{flags}"
|
14
|
+
true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
unless Object.method_defined?(:append_cflags)
|
19
|
+
def append_cflags(flags)
|
20
|
+
return false unless try_cflags(flags)
|
21
|
+
$CFLAGS << " #{flags}"
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
unless Object.method_defined?(:append_ldflags)
|
27
|
+
def append_ldflags(flags)
|
28
|
+
return false unless try_ldflags(flags)
|
29
|
+
$LDFLAGS << " #{flags}"
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
using MyExtensions
|
37
|
+
|
38
|
+
|
39
|
+
# TODO: システムにインストールされた lz4 がある場合、バージョンを確認してより新しければそちらを利用する
|
40
|
+
|
41
|
+
append_cppflags "-I$(srcdir)/../contrib/lz4/lib"
|
42
|
+
|
43
|
+
if RbConfig::CONFIG["arch"] =~ /mingw/
|
44
|
+
append_ldflags "-static-libgcc"
|
45
|
+
else
|
46
|
+
if try_compile(%q(__attribute__ ((visibility("default"))) void testfunc(void) { }))
|
47
|
+
if append_cflags "-fvisibility=hidden"
|
48
|
+
localsymbol = true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if localsymbol
|
54
|
+
$defs << %q('-DRBEXT_API=__attribute__ ((visibility("default")))') <<
|
55
|
+
%q(-DRBEXT_VISIBILITY=1)
|
56
|
+
else
|
57
|
+
$defs << %q(-DRBEXT_API=)
|
58
|
+
end
|
59
|
+
|
60
|
+
create_makefile File.join(RUBY_VERSION[/\d+\.\d+/], "extlz4")
|
data/ext/extlz4.c
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#include "extlz4.h"
|
2
|
+
#include <lz4.h>
|
3
|
+
|
4
|
+
VALUE extlz4_eError;
|
5
|
+
|
6
|
+
/*
|
7
|
+
* version information
|
8
|
+
*/
|
9
|
+
|
10
|
+
static VALUE
|
11
|
+
libver_major(VALUE ver)
|
12
|
+
{
|
13
|
+
return INT2FIX(LZ4_VERSION_MAJOR);
|
14
|
+
}
|
15
|
+
|
16
|
+
static VALUE
|
17
|
+
libver_minor(VALUE ver)
|
18
|
+
{
|
19
|
+
return INT2FIX(LZ4_VERSION_MINOR);
|
20
|
+
}
|
21
|
+
|
22
|
+
static VALUE
|
23
|
+
libver_release(VALUE ver)
|
24
|
+
{
|
25
|
+
return INT2FIX(LZ4_VERSION_RELEASE);
|
26
|
+
}
|
27
|
+
|
28
|
+
static VALUE
|
29
|
+
libver_to_s(VALUE ver)
|
30
|
+
{
|
31
|
+
return rb_sprintf("%d.%d.%d", LZ4_VERSION_MAJOR, LZ4_VERSION_MINOR, LZ4_VERSION_RELEASE);
|
32
|
+
}
|
33
|
+
|
34
|
+
/*
|
35
|
+
* initialize library
|
36
|
+
*/
|
37
|
+
|
38
|
+
VALUE extlz4_mLZ4;
|
39
|
+
|
40
|
+
RBEXT_API void
|
41
|
+
Init_extlz4(void)
|
42
|
+
{
|
43
|
+
extlz4_mLZ4 = rb_define_module("LZ4");
|
44
|
+
|
45
|
+
/*
|
46
|
+
* Document-const: LZ4::LIBVERSION
|
47
|
+
*
|
48
|
+
* This constant value means api version number of original lz4 library as array'd integers.
|
49
|
+
*
|
50
|
+
* And it's has any singleton methods, so they are +#major+, +#minor+, +#release+ and +#to_s+.
|
51
|
+
*
|
52
|
+
* 実体が配列である理由は、比較を行いやすくすることを意図しているためです。
|
53
|
+
*/
|
54
|
+
VALUE ver = rb_ary_new3(3,
|
55
|
+
INT2FIX(LZ4_VERSION_MAJOR),
|
56
|
+
INT2FIX(LZ4_VERSION_MINOR),
|
57
|
+
INT2FIX(LZ4_VERSION_RELEASE));
|
58
|
+
rb_define_singleton_method(ver, "major", libver_major, 0);
|
59
|
+
rb_define_singleton_method(ver, "minor", libver_minor, 0);
|
60
|
+
rb_define_singleton_method(ver, "release", libver_release, 0);
|
61
|
+
rb_define_singleton_method(ver, "to_s", libver_to_s, 0);
|
62
|
+
rb_obj_freeze(ver);
|
63
|
+
rb_define_const(extlz4_mLZ4, "LIBVERSION", ver);
|
64
|
+
|
65
|
+
extlz4_eError = rb_define_class_under(extlz4_mLZ4, "Error", rb_eRuntimeError);
|
66
|
+
|
67
|
+
extlz4_init_blockapi();
|
68
|
+
extlz4_init_frameapi();
|
69
|
+
}
|
data/ext/extlz4.h
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
#ifndef EXTLZ4_H
|
2
|
+
#define EXTLZ4_H 1
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
#include <ruby/thread.h>
|
6
|
+
#include <stdarg.h>
|
7
|
+
#include <stdlib.h>
|
8
|
+
#include <errno.h>
|
9
|
+
|
10
|
+
#ifndef RB_OBJ_FROZEN
|
11
|
+
# define RB_OBJ_FROZEN OBJ_FROZEN
|
12
|
+
#endif
|
13
|
+
|
14
|
+
extern VALUE extlz4_mLZ4; /* module LZ4 */
|
15
|
+
extern VALUE extlz4_eError; /* class LZ4::Error < ::RuntimeError */
|
16
|
+
|
17
|
+
extern void extlz4_init_blockapi(void);
|
18
|
+
extern void extlz4_init_frameapi(void);
|
19
|
+
|
20
|
+
#define AUX_FUNCALL(RECV, METHOD, ...) \
|
21
|
+
({ \
|
22
|
+
VALUE args__[] = { __VA_ARGS__ }; \
|
23
|
+
rb_funcall2((RECV), (METHOD), \
|
24
|
+
sizeof(args__) / sizeof(args__[0]), args__); \
|
25
|
+
}) \
|
26
|
+
|
27
|
+
static inline void *
|
28
|
+
aux_thread_call_without_gvl(void *(*func)(va_list *), void (*cancel)(va_list *), ...)
|
29
|
+
{
|
30
|
+
va_list va1, va2;
|
31
|
+
va_start(va1, cancel);
|
32
|
+
va_start(va2, cancel);
|
33
|
+
void *s = rb_thread_call_without_gvl((void *(*)(void *))func, &va1, (void (*)(void *))cancel, &va2);
|
34
|
+
va_end(va1);
|
35
|
+
va_end(va2);
|
36
|
+
return s;
|
37
|
+
}
|
38
|
+
|
39
|
+
static inline void
|
40
|
+
aux_str_reserve(VALUE str, size_t size)
|
41
|
+
{
|
42
|
+
if (rb_str_capacity(str) < size) {
|
43
|
+
rb_str_modify_expand(str, size - RSTRING_LEN(str));
|
44
|
+
if (rb_str_capacity(str) < size) {
|
45
|
+
errno = ENOMEM;
|
46
|
+
rb_sys_fail("output buffer is not reallocated");
|
47
|
+
}
|
48
|
+
} else {
|
49
|
+
rb_str_modify(str);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
/*
|
53
|
+
* rb_str_drop_bytes は共有オブジェクトを生成して返すので、
|
54
|
+
* それとは違う、破壊的メソッドとしての関数。
|
55
|
+
*/
|
56
|
+
static inline VALUE
|
57
|
+
aux_str_drop_bytes(VALUE str, size_t dropsize)
|
58
|
+
{
|
59
|
+
char *p;
|
60
|
+
size_t size;
|
61
|
+
RSTRING_GETMEM(str, p, size);
|
62
|
+
if (dropsize > size) {
|
63
|
+
dropsize = size;
|
64
|
+
} else {
|
65
|
+
memmove(p, p + dropsize, size - dropsize);
|
66
|
+
}
|
67
|
+
rb_str_set_len(str, size - dropsize);
|
68
|
+
return str;
|
69
|
+
}
|
70
|
+
|
71
|
+
static inline char *
|
72
|
+
aux_str_getmem(VALUE str, char **ptr, size_t *size)
|
73
|
+
{
|
74
|
+
if (rb_type_p(str, RUBY_T_STRING)) {
|
75
|
+
RSTRING_GETMEM(str, *ptr, *size);
|
76
|
+
} else {
|
77
|
+
*ptr = NULL;
|
78
|
+
*size = 0;
|
79
|
+
}
|
80
|
+
|
81
|
+
return *ptr;
|
82
|
+
}
|
83
|
+
|
84
|
+
static inline void *
|
85
|
+
checkref(VALUE obj, void *p)
|
86
|
+
{
|
87
|
+
if (!p) {
|
88
|
+
rb_raise(rb_eRuntimeError,
|
89
|
+
"not initialized object or invalid reference - #<%s:%p>",
|
90
|
+
rb_obj_classname(obj), (void *)obj);
|
91
|
+
}
|
92
|
+
return p;
|
93
|
+
}
|
94
|
+
|
95
|
+
static inline void *
|
96
|
+
getrefp(VALUE obj, const rb_data_type_t *type)
|
97
|
+
{
|
98
|
+
void *p;
|
99
|
+
TypedData_Get_Struct(obj, void, type, p);
|
100
|
+
return p;
|
101
|
+
}
|
102
|
+
|
103
|
+
static inline void *
|
104
|
+
getref(VALUE obj, const rb_data_type_t *type)
|
105
|
+
{
|
106
|
+
return checkref(obj, getrefp(obj, type));
|
107
|
+
}
|
108
|
+
|
109
|
+
#endif /* !EXTLZ4_H */
|
data/ext/frameapi.c
ADDED
@@ -0,0 +1,780 @@
|
|
1
|
+
#include "extlz4.h"
|
2
|
+
#include <lz4frame.h>
|
3
|
+
#include <lz4frame_static.h>
|
4
|
+
#include "hashargs.h"
|
5
|
+
|
6
|
+
static ID id_op_lshift;
|
7
|
+
static ID id_read;
|
8
|
+
|
9
|
+
enum {
|
10
|
+
FLAG_LEGACY = 1 << 0,
|
11
|
+
FLAG_BLOCK_LINK = 1 << 1,
|
12
|
+
FLAG_BLOCK_SUM = 1 << 2,
|
13
|
+
FLAG_STREAM_SIZE = 1 << 3,
|
14
|
+
FLAG_STREAM_SUM = 1 << 4,
|
15
|
+
|
16
|
+
WORK_BUFFER_SIZE = 256 * 1024, /* 256 KiB */
|
17
|
+
AUX_LZ4FRAME_HEADER_MAX = 19,
|
18
|
+
|
19
|
+
AUX_LZ4F_BLOCK_SIZE_MAX = 4 * 1024 * 1024, /* 4 MiB : maximum block size of LZ4 Frame */
|
20
|
+
AUX_LZ4F_FINISH_SIZE = 16, /* from lz4frame.c */
|
21
|
+
|
22
|
+
AUX_LZ4F_PARTIAL_READ_SIZE = 256 * 1024, /* 256 KiB */
|
23
|
+
};
|
24
|
+
|
25
|
+
/*** auxiliary and common functions ***/
|
26
|
+
|
27
|
+
static inline void
|
28
|
+
aux_lz4f_check_error(size_t err)
|
29
|
+
{
|
30
|
+
if (LZ4F_isError(err)) {
|
31
|
+
rb_raise(extlz4_eError,
|
32
|
+
"%s (0x%04x)",
|
33
|
+
LZ4F_getErrorName(err), -(int)err);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
static void *
|
38
|
+
aux_LZ4F_compressUpdate_nogvl(va_list *p)
|
39
|
+
{
|
40
|
+
LZ4F_compressionContext_t encoder = va_arg(*p, LZ4F_compressionContext_t);
|
41
|
+
char *dest = va_arg(*p, char *);
|
42
|
+
size_t destsize = va_arg(*p, size_t);
|
43
|
+
const char *src = va_arg(*p, const char *);
|
44
|
+
size_t srcsize = va_arg(*p, size_t);
|
45
|
+
LZ4F_compressOptions_t *opts = va_arg(*p, LZ4F_compressOptions_t *);
|
46
|
+
|
47
|
+
return (void *)LZ4F_compressUpdate(encoder, dest, destsize, src, srcsize, opts);
|
48
|
+
}
|
49
|
+
|
50
|
+
static size_t
|
51
|
+
aux_LZ4F_compressUpdate(LZ4F_compressionContext_t encoder,
|
52
|
+
char *dest, size_t destsize, const char *src, size_t srcsize,
|
53
|
+
LZ4F_compressOptions_t *opts)
|
54
|
+
{
|
55
|
+
return (size_t)aux_thread_call_without_gvl(aux_LZ4F_compressUpdate_nogvl, NULL,
|
56
|
+
encoder, dest, destsize, src, srcsize, opts);
|
57
|
+
}
|
58
|
+
|
59
|
+
static int
|
60
|
+
aux_frame_level(const LZ4F_preferences_t *p)
|
61
|
+
{
|
62
|
+
return p->compressionLevel;
|
63
|
+
}
|
64
|
+
|
65
|
+
static int
|
66
|
+
aux_frame_blocksize(const LZ4F_frameInfo_t *info)
|
67
|
+
{
|
68
|
+
int bsid = info->blockSizeID;
|
69
|
+
if (bsid == 0) {
|
70
|
+
bsid = LZ4F_max4MB;
|
71
|
+
}
|
72
|
+
return 1 << (bsid * 2 + 8);
|
73
|
+
}
|
74
|
+
|
75
|
+
static int
|
76
|
+
aux_frame_blocklink(const LZ4F_frameInfo_t *info)
|
77
|
+
{
|
78
|
+
return info->blockMode == LZ4F_blockLinked;
|
79
|
+
}
|
80
|
+
|
81
|
+
static int
|
82
|
+
aux_frame_checksum(const LZ4F_frameInfo_t *info)
|
83
|
+
{
|
84
|
+
return info->contentChecksumFlag == LZ4F_contentChecksumEnabled;
|
85
|
+
}
|
86
|
+
|
87
|
+
/*** class LZ4::Encoder ***/
|
88
|
+
|
89
|
+
struct encoder
|
90
|
+
{
|
91
|
+
VALUE outport;
|
92
|
+
VALUE workbuf;
|
93
|
+
LZ4F_preferences_t prefs;
|
94
|
+
LZ4F_compressionContext_t encoder;
|
95
|
+
};
|
96
|
+
|
97
|
+
static void
|
98
|
+
encoder_mark(void *pp)
|
99
|
+
{
|
100
|
+
struct encoder *p = pp;
|
101
|
+
rb_gc_mark(p->outport);
|
102
|
+
rb_gc_mark(p->workbuf);
|
103
|
+
}
|
104
|
+
|
105
|
+
static void
|
106
|
+
encoder_free(void *pp)
|
107
|
+
{
|
108
|
+
struct encoder *p = pp;
|
109
|
+
if (p->encoder) {
|
110
|
+
LZ4F_freeCompressionContext(p->encoder);
|
111
|
+
}
|
112
|
+
memset(p, 0, sizeof(*p));
|
113
|
+
xfree(p);
|
114
|
+
}
|
115
|
+
|
116
|
+
static const rb_data_type_t encoder_type = {
|
117
|
+
.wrap_struct_name = "extlz4.LZ4.Encoder",
|
118
|
+
.function.dmark = encoder_mark,
|
119
|
+
.function.dfree = encoder_free,
|
120
|
+
/* .function.dsize = encoder_size, */
|
121
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
122
|
+
};
|
123
|
+
|
124
|
+
static VALUE
|
125
|
+
fenc_alloc(VALUE mod)
|
126
|
+
{
|
127
|
+
struct encoder *p;
|
128
|
+
VALUE obj = TypedData_Make_Struct(mod, struct encoder, &encoder_type, p);
|
129
|
+
p->outport = Qnil;
|
130
|
+
p->workbuf = Qnil;
|
131
|
+
return obj;
|
132
|
+
}
|
133
|
+
|
134
|
+
static inline int
|
135
|
+
fenc_init_args_blocksize(size_t size)
|
136
|
+
{
|
137
|
+
if (size == 0) {
|
138
|
+
return LZ4F_default;
|
139
|
+
} else if (size <= 64 * 1024) {
|
140
|
+
return LZ4F_max64KB;
|
141
|
+
} else if (size <= 256 * 1024) {
|
142
|
+
return LZ4F_max256KB;
|
143
|
+
} else if (size <= 1 * 1024 * 1024) {
|
144
|
+
return LZ4F_max1MB;
|
145
|
+
} else {
|
146
|
+
return LZ4F_max4MB;
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
static inline void
|
151
|
+
fenc_init_args(int argc, VALUE argv[], VALUE *outport, LZ4F_preferences_t *prefs)
|
152
|
+
{
|
153
|
+
VALUE level, opts;
|
154
|
+
rb_scan_args(argc, argv, "02:", outport, &level, &opts);
|
155
|
+
|
156
|
+
memset(prefs, 0, sizeof(*prefs));
|
157
|
+
|
158
|
+
if (NIL_P(*outport)) {
|
159
|
+
*outport = rb_str_buf_new(0);
|
160
|
+
}
|
161
|
+
|
162
|
+
prefs->compressionLevel = NIL_P(level) ? 1 : NUM2INT(level);
|
163
|
+
|
164
|
+
if (!NIL_P(opts)) {
|
165
|
+
VALUE blocksize, blocklink, checksum;
|
166
|
+
RBX_SCANHASH(opts, Qnil,
|
167
|
+
RBX_SCANHASH_ARGS("blocksize", &blocksize, Qnil),
|
168
|
+
RBX_SCANHASH_ARGS("blocklink", &blocklink, Qfalse),
|
169
|
+
RBX_SCANHASH_ARGS("checksum", &checksum, Qtrue));
|
170
|
+
// prefs->autoFlush = TODO;
|
171
|
+
prefs->frameInfo.blockSizeID = NIL_P(blocksize) ? LZ4F_default : fenc_init_args_blocksize(NUM2INT(blocksize));
|
172
|
+
prefs->frameInfo.blockMode = RTEST(blocklink) ? LZ4F_blockLinked : LZ4F_blockIndependent;
|
173
|
+
prefs->frameInfo.contentChecksumFlag = RTEST(checksum) ? LZ4F_contentChecksumEnabled : LZ4F_noContentChecksum;
|
174
|
+
} else {
|
175
|
+
prefs->frameInfo.blockSizeID = LZ4F_default;
|
176
|
+
prefs->frameInfo.blockMode = LZ4F_blockIndependent;
|
177
|
+
prefs->frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled;
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
static struct encoder *
|
182
|
+
getencoderp(VALUE enc)
|
183
|
+
{
|
184
|
+
return getrefp(enc, &encoder_type);
|
185
|
+
}
|
186
|
+
|
187
|
+
static struct encoder *
|
188
|
+
getencoder(VALUE enc)
|
189
|
+
{
|
190
|
+
return getref(enc, &encoder_type);
|
191
|
+
}
|
192
|
+
|
193
|
+
/*
|
194
|
+
* call-seq:
|
195
|
+
* initialize(outport = "".b, level = 1, blocksize: nil, blocklink: false, checksum: true)
|
196
|
+
*/
|
197
|
+
static VALUE
|
198
|
+
fenc_init(int argc, VALUE argv[], VALUE enc)
|
199
|
+
{
|
200
|
+
struct encoder *p = getencoder(enc);
|
201
|
+
VALUE outport;
|
202
|
+
fenc_init_args(argc, argv, &outport, &p->prefs);
|
203
|
+
|
204
|
+
LZ4F_errorCode_t status;
|
205
|
+
status = LZ4F_createCompressionContext(&p->encoder, LZ4F_VERSION);
|
206
|
+
aux_lz4f_check_error(status);
|
207
|
+
p->workbuf = rb_str_buf_new(AUX_LZ4F_BLOCK_SIZE_MAX);
|
208
|
+
size_t s = LZ4F_compressBegin(p->encoder, RSTRING_PTR(p->workbuf), rb_str_capacity(p->workbuf), &p->prefs);
|
209
|
+
aux_lz4f_check_error(s);
|
210
|
+
rb_str_set_len(p->workbuf, s);
|
211
|
+
rb_funcall2(outport, id_op_lshift, 1, &p->workbuf);
|
212
|
+
p->outport = outport;
|
213
|
+
rb_obj_infect(p->outport, enc);
|
214
|
+
return enc;
|
215
|
+
}
|
216
|
+
|
217
|
+
static inline void
|
218
|
+
fenc_update(struct encoder *p, VALUE src, LZ4F_compressOptions_t *opts)
|
219
|
+
{
|
220
|
+
rb_check_type(src, RUBY_T_STRING);
|
221
|
+
const char *srcp = RSTRING_PTR(src);
|
222
|
+
const char *srctail = srcp + RSTRING_LEN(src);
|
223
|
+
while (srcp < srctail) {
|
224
|
+
size_t srcsize = srctail - srcp;
|
225
|
+
if (srcsize > AUX_LZ4F_BLOCK_SIZE_MAX) { srcsize = AUX_LZ4F_BLOCK_SIZE_MAX; }
|
226
|
+
size_t destsize = LZ4F_compressBound(srcsize, &p->prefs);
|
227
|
+
aux_str_reserve(p->workbuf, destsize);
|
228
|
+
char *destp = RSTRING_PTR(p->workbuf);
|
229
|
+
size_t size = aux_LZ4F_compressUpdate(p->encoder, destp, destsize, srcp, srcsize, opts);
|
230
|
+
aux_lz4f_check_error(size);
|
231
|
+
rb_str_set_len(p->workbuf, size);
|
232
|
+
rb_funcall2(p->outport, id_op_lshift, 1, &p->workbuf);
|
233
|
+
srcp += srcsize;
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
/*
|
238
|
+
* call-seq:
|
239
|
+
* write(src) -> self
|
240
|
+
*/
|
241
|
+
static VALUE
|
242
|
+
fenc_write(int argc, VALUE argv[], VALUE enc)
|
243
|
+
{
|
244
|
+
struct encoder *p = getencoder(enc);
|
245
|
+
VALUE src;
|
246
|
+
rb_scan_args(argc, argv, "1", &src);
|
247
|
+
rb_obj_infect(enc, src);
|
248
|
+
rb_obj_infect(enc, p->workbuf);
|
249
|
+
rb_obj_infect(p->outport, enc);
|
250
|
+
fenc_update(p, src, NULL);
|
251
|
+
return enc;
|
252
|
+
}
|
253
|
+
|
254
|
+
static VALUE
|
255
|
+
fenc_push(VALUE enc, VALUE src)
|
256
|
+
{
|
257
|
+
struct encoder *p = getencoder(enc);
|
258
|
+
rb_obj_infect(enc, src);
|
259
|
+
rb_obj_infect(enc, p->workbuf);
|
260
|
+
rb_obj_infect(p->outport, enc);
|
261
|
+
fenc_update(p, src, NULL);
|
262
|
+
return enc;
|
263
|
+
}
|
264
|
+
|
265
|
+
static VALUE
|
266
|
+
fenc_flush(VALUE enc)
|
267
|
+
{
|
268
|
+
struct encoder *p = getencoder(enc);
|
269
|
+
size_t destsize = AUX_LZ4F_BLOCK_SIZE_MAX + AUX_LZ4F_FINISH_SIZE;
|
270
|
+
aux_str_reserve(p->workbuf, destsize);
|
271
|
+
char *destp = RSTRING_PTR(p->workbuf);
|
272
|
+
size_t size = LZ4F_flush(p->encoder, destp, destsize, NULL);
|
273
|
+
aux_lz4f_check_error(size);
|
274
|
+
rb_str_set_len(p->workbuf, size);
|
275
|
+
rb_funcall2(p->outport, id_op_lshift, 1, &p->workbuf);
|
276
|
+
|
277
|
+
return enc;
|
278
|
+
}
|
279
|
+
|
280
|
+
static VALUE
|
281
|
+
fenc_close(VALUE enc)
|
282
|
+
{
|
283
|
+
struct encoder *p = getencoder(enc);
|
284
|
+
size_t destsize = AUX_LZ4F_BLOCK_SIZE_MAX + AUX_LZ4F_FINISH_SIZE;
|
285
|
+
aux_str_reserve(p->workbuf, destsize);
|
286
|
+
char *destp = RSTRING_PTR(p->workbuf);
|
287
|
+
size_t size = LZ4F_compressEnd(p->encoder, destp, destsize, NULL);
|
288
|
+
aux_lz4f_check_error(size);
|
289
|
+
rb_str_set_len(p->workbuf, size);
|
290
|
+
rb_funcall2(p->outport, id_op_lshift, 1, &p->workbuf);
|
291
|
+
|
292
|
+
return enc;
|
293
|
+
}
|
294
|
+
|
295
|
+
static VALUE
|
296
|
+
fenc_getoutport(VALUE enc)
|
297
|
+
{
|
298
|
+
return getencoder(enc)->outport;
|
299
|
+
}
|
300
|
+
|
301
|
+
static VALUE
|
302
|
+
fenc_setoutport(VALUE enc, VALUE outport)
|
303
|
+
{
|
304
|
+
return getencoder(enc)->outport = outport;
|
305
|
+
}
|
306
|
+
|
307
|
+
static VALUE
|
308
|
+
fenc_prefs_level(VALUE enc)
|
309
|
+
{
|
310
|
+
return INT2NUM(aux_frame_level(&getencoder(enc)->prefs));
|
311
|
+
}
|
312
|
+
|
313
|
+
static int
|
314
|
+
fenc_blocksize(struct encoder *p)
|
315
|
+
{
|
316
|
+
return aux_frame_blocksize(&p->prefs.frameInfo);
|
317
|
+
}
|
318
|
+
|
319
|
+
static VALUE
|
320
|
+
fenc_prefs_blocksize(VALUE enc)
|
321
|
+
{
|
322
|
+
return INT2NUM(fenc_blocksize(getencoder(enc)));
|
323
|
+
}
|
324
|
+
|
325
|
+
static VALUE
|
326
|
+
fenc_prefs_blocklink(VALUE enc)
|
327
|
+
{
|
328
|
+
return aux_frame_blocklink(&getencoder(enc)->prefs.frameInfo) ? Qtrue : Qfalse;
|
329
|
+
}
|
330
|
+
|
331
|
+
static VALUE
|
332
|
+
fenc_prefs_checksum(VALUE enc)
|
333
|
+
{
|
334
|
+
return aux_frame_checksum(&getencoder(enc)->prefs.frameInfo) ? Qtrue : Qfalse;
|
335
|
+
}
|
336
|
+
|
337
|
+
static VALUE
|
338
|
+
fenc_inspect(VALUE enc)
|
339
|
+
{
|
340
|
+
struct encoder *p = getencoderp(enc);
|
341
|
+
if (p) {
|
342
|
+
return rb_sprintf("#<%s:%p outport=#<%s:%p>, level=%d, blocksize=%d, blocklink=%s, checksum=%s>",
|
343
|
+
rb_obj_classname(enc), (void *)enc,
|
344
|
+
rb_obj_classname(p->outport), (void *)p->outport,
|
345
|
+
p->prefs.compressionLevel, fenc_blocksize(p),
|
346
|
+
aux_frame_blocklink(&p->prefs.frameInfo) ? "true" : "false",
|
347
|
+
aux_frame_checksum(&p->prefs.frameInfo) ? "true" : "false");
|
348
|
+
} else {
|
349
|
+
return rb_sprintf("#<%s:%p **INVALID REFERENCE**>",
|
350
|
+
rb_obj_classname(enc), (void *)enc);
|
351
|
+
}
|
352
|
+
}
|
353
|
+
|
354
|
+
/*** class LZ4::Decoder ***/
|
355
|
+
|
356
|
+
struct decoder
|
357
|
+
{
|
358
|
+
VALUE inport;
|
359
|
+
VALUE readbuf; /* read buffer from inport */
|
360
|
+
VALUE inbuf;
|
361
|
+
VALUE outbuf;
|
362
|
+
size_t outoff; /* offset in outbuf */
|
363
|
+
size_t status; /* status code of LZ4F_decompress */
|
364
|
+
LZ4F_frameInfo_t info;
|
365
|
+
LZ4F_decompressionContext_t decoder;
|
366
|
+
};
|
367
|
+
|
368
|
+
static void
|
369
|
+
decoder_mark(void *pp)
|
370
|
+
{
|
371
|
+
struct decoder *p = pp;
|
372
|
+
rb_gc_mark(p->inport);
|
373
|
+
rb_gc_mark(p->readbuf);
|
374
|
+
rb_gc_mark(p->inbuf);
|
375
|
+
rb_gc_mark(p->outbuf);
|
376
|
+
}
|
377
|
+
|
378
|
+
static void
|
379
|
+
decoder_free(void *pp)
|
380
|
+
{
|
381
|
+
struct decoder *p = pp;
|
382
|
+
if (p->decoder) {
|
383
|
+
LZ4F_freeDecompressionContext(p->decoder);
|
384
|
+
}
|
385
|
+
memset(p, 0, sizeof(*p));
|
386
|
+
xfree(p);
|
387
|
+
}
|
388
|
+
|
389
|
+
static const rb_data_type_t decoder_type = {
|
390
|
+
.wrap_struct_name = "extlz4.LZ4.Decoder",
|
391
|
+
.function.dmark = decoder_mark,
|
392
|
+
.function.dfree = decoder_free,
|
393
|
+
/* .function.dsize = decoder_size, */
|
394
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
395
|
+
};
|
396
|
+
|
397
|
+
static VALUE
|
398
|
+
fdec_alloc(VALUE mod)
|
399
|
+
{
|
400
|
+
struct decoder *p;
|
401
|
+
VALUE obj = TypedData_Make_Struct(mod, struct decoder, &decoder_type, p);
|
402
|
+
p->inport = Qnil;
|
403
|
+
p->readbuf = Qnil;
|
404
|
+
p->inbuf = Qnil;
|
405
|
+
p->outbuf = Qnil;
|
406
|
+
p->outoff = 0;
|
407
|
+
p->status = 0;
|
408
|
+
return obj;
|
409
|
+
}
|
410
|
+
|
411
|
+
static struct decoder *
|
412
|
+
getdecoderp(VALUE dec)
|
413
|
+
{
|
414
|
+
return getrefp(dec, &decoder_type);
|
415
|
+
}
|
416
|
+
|
417
|
+
static struct decoder *
|
418
|
+
getdecoder(VALUE dec)
|
419
|
+
{
|
420
|
+
return getref(dec, &decoder_type);
|
421
|
+
}
|
422
|
+
|
423
|
+
static inline VALUE
|
424
|
+
aux_read(VALUE obj, size_t size, VALUE buf)
|
425
|
+
{
|
426
|
+
if (NIL_P(buf) || RB_OBJ_FROZEN(buf)) {
|
427
|
+
buf = rb_str_buf_new(size);
|
428
|
+
}
|
429
|
+
|
430
|
+
if (NIL_P(AUX_FUNCALL(obj, id_read, SIZET2NUM(size), buf))) {
|
431
|
+
return Qnil;
|
432
|
+
} else {
|
433
|
+
if (RSTRING_LEN(buf) > size) {
|
434
|
+
rb_raise(rb_eRuntimeError, "most read (%d, but expected to %d)", (int)RSTRING_LEN(buf), (int)size);
|
435
|
+
}
|
436
|
+
return buf;
|
437
|
+
}
|
438
|
+
}
|
439
|
+
|
440
|
+
/*
|
441
|
+
* call-seq:
|
442
|
+
* initialize(inport) -> self
|
443
|
+
*
|
444
|
+
* [inport]
|
445
|
+
* An I/O (liked) object for data read from LZ4 Frame.
|
446
|
+
*
|
447
|
+
* This object need +.read+ method.
|
448
|
+
*/
|
449
|
+
static VALUE
|
450
|
+
fdec_init(int argc, VALUE argv[], VALUE dec)
|
451
|
+
{
|
452
|
+
struct decoder *p = getdecoder(dec);
|
453
|
+
VALUE inport;
|
454
|
+
//VALUE readblocksize;
|
455
|
+
rb_scan_args(argc, argv, "1", &inport);
|
456
|
+
LZ4F_errorCode_t err = LZ4F_createDecompressionContext(&p->decoder, LZ4F_VERSION);
|
457
|
+
aux_lz4f_check_error(err);
|
458
|
+
rb_obj_infect(dec, inport);
|
459
|
+
p->inport = inport;
|
460
|
+
p->readbuf = rb_str_buf_new(0);
|
461
|
+
char *readp;
|
462
|
+
size_t readsize;
|
463
|
+
size_t zero = 0;
|
464
|
+
size_t s = 4; /* magic number size of lz4 frame */
|
465
|
+
int i;
|
466
|
+
for (i = 0; i < 2; i ++) {
|
467
|
+
/*
|
468
|
+
* first step: check magic number
|
469
|
+
* second step: check frame information
|
470
|
+
*/
|
471
|
+
aux_read(inport, s, p->readbuf);
|
472
|
+
aux_str_getmem(p->readbuf, &readp, &readsize);
|
473
|
+
if (!readp || readsize < s) {
|
474
|
+
rb_raise(extlz4_eError,
|
475
|
+
"unexpected EOF (read error) - #<%s:%p>",
|
476
|
+
rb_obj_classname(inport), (const void *)inport);
|
477
|
+
}
|
478
|
+
s = LZ4F_decompress(p->decoder, NULL, &zero, readp, &readsize, NULL);
|
479
|
+
aux_lz4f_check_error(s);
|
480
|
+
}
|
481
|
+
p->status = s;
|
482
|
+
s = LZ4F_getFrameInfo(p->decoder, &p->info, NULL, &zero);
|
483
|
+
aux_lz4f_check_error(s);
|
484
|
+
p->outbuf = rb_str_tmp_new(1 << (8 + p->info.blockSizeID * 2));
|
485
|
+
rb_str_set_len(p->outbuf, 0);
|
486
|
+
|
487
|
+
return dec;
|
488
|
+
}
|
489
|
+
|
490
|
+
static inline void
|
491
|
+
fdec_read_args(int argc, VALUE argv[], size_t *size, VALUE *buf)
|
492
|
+
{
|
493
|
+
switch (argc) {
|
494
|
+
case 0:
|
495
|
+
*size = ~(size_t)0;
|
496
|
+
*buf = rb_str_buf_new(0);
|
497
|
+
break;
|
498
|
+
case 1:
|
499
|
+
*size = NUM2SIZET(argv[0]);
|
500
|
+
*buf = rb_str_buf_new(*size);
|
501
|
+
break;
|
502
|
+
case 2:
|
503
|
+
*size = NUM2SIZET(argv[0]);
|
504
|
+
*buf = argv[1];
|
505
|
+
rb_check_type(*buf, RUBY_T_STRING);
|
506
|
+
rb_str_modify(*buf);
|
507
|
+
rb_str_set_len(*buf, 0);
|
508
|
+
break;
|
509
|
+
default:
|
510
|
+
rb_error_arity(argc, 0, 2);
|
511
|
+
}
|
512
|
+
}
|
513
|
+
|
514
|
+
static void
|
515
|
+
fdec_read_fetch(VALUE dec, struct decoder *p)
|
516
|
+
{
|
517
|
+
if (NIL_P(p->inbuf)) {
|
518
|
+
p->inbuf = rb_str_tmp_new(256);
|
519
|
+
rb_str_set_len(p->inbuf, 0);
|
520
|
+
}
|
521
|
+
|
522
|
+
while (RSTRING_LEN(p->inbuf) < p->status) {
|
523
|
+
p->readbuf = aux_read(p->inport, p->status - RSTRING_LEN(p->inbuf), p->readbuf);
|
524
|
+
if (NIL_P(p->readbuf)) {
|
525
|
+
rb_raise(rb_eRuntimeError,
|
526
|
+
"unexpected EOF (read error) - #<%s:%p>",
|
527
|
+
rb_obj_classname(p->inport), (const void *)p->inport);
|
528
|
+
}
|
529
|
+
rb_check_type(p->readbuf, RUBY_T_STRING);
|
530
|
+
rb_str_buf_cat(p->inbuf, RSTRING_PTR(p->readbuf), RSTRING_LEN(p->readbuf));
|
531
|
+
}
|
532
|
+
|
533
|
+
char *inp;
|
534
|
+
size_t insize;
|
535
|
+
aux_str_getmem(p->inbuf, &inp, &insize);
|
536
|
+
char *outp = RSTRING_PTR(p->outbuf);
|
537
|
+
size_t outsize = rb_str_capacity(p->outbuf);
|
538
|
+
p->status = LZ4F_decompress(p->decoder, outp, &outsize, inp, &insize, NULL);
|
539
|
+
aux_lz4f_check_error(p->status);
|
540
|
+
memmove(RSTRING_PTR(p->inbuf), RSTRING_PTR(p->inbuf) + insize, RSTRING_LEN(p->inbuf) - insize);
|
541
|
+
rb_str_set_len(p->inbuf, RSTRING_LEN(p->inbuf) - insize);
|
542
|
+
rb_str_set_len(p->outbuf, outsize);
|
543
|
+
p->outoff = 0;
|
544
|
+
rb_thread_check_ints();
|
545
|
+
}
|
546
|
+
|
547
|
+
static size_t
|
548
|
+
fdec_read_decode(VALUE dec, struct decoder *p, char *dest, size_t size)
|
549
|
+
{
|
550
|
+
const char *const desthead = dest;
|
551
|
+
uintptr_t desttail = (uintptr_t)dest + size;
|
552
|
+
|
553
|
+
while ((uintptr_t)dest < desttail) {
|
554
|
+
if ((ssize_t)p->status < 1 && RSTRING_LEN(p->outbuf) < 1) {
|
555
|
+
break;
|
556
|
+
}
|
557
|
+
|
558
|
+
if (p->status > 0 && p->outoff >= RSTRING_LEN(p->outbuf)) {
|
559
|
+
fdec_read_fetch(dec, p);
|
560
|
+
}
|
561
|
+
|
562
|
+
if (size < RSTRING_LEN(p->outbuf) - p->outoff) {
|
563
|
+
memcpy(dest, RSTRING_PTR(p->outbuf) + p->outoff, size);
|
564
|
+
p->outoff += size;
|
565
|
+
dest += size;
|
566
|
+
break;
|
567
|
+
} else {
|
568
|
+
size_t s = RSTRING_LEN(p->outbuf) - p->outoff;
|
569
|
+
memcpy(dest, RSTRING_PTR(p->outbuf) + p->outoff, s);
|
570
|
+
p->outoff = 0;
|
571
|
+
rb_str_set_len(p->outbuf, 0);
|
572
|
+
dest += s;
|
573
|
+
size -= s;
|
574
|
+
}
|
575
|
+
}
|
576
|
+
|
577
|
+
return dest - desthead;
|
578
|
+
}
|
579
|
+
|
580
|
+
/*
|
581
|
+
* call-seq:
|
582
|
+
* read -> string
|
583
|
+
* read(size) -> string
|
584
|
+
* read(size, buffer) -> buffer
|
585
|
+
*/
|
586
|
+
static VALUE
|
587
|
+
fdec_read(int argc, VALUE argv[], VALUE dec)
|
588
|
+
{
|
589
|
+
struct decoder *p = getdecoder(dec);
|
590
|
+
size_t size;
|
591
|
+
VALUE dest;
|
592
|
+
fdec_read_args(argc, argv, &size, &dest);
|
593
|
+
if (size == 0) {
|
594
|
+
rb_obj_infect(dest, dec);
|
595
|
+
return dest;
|
596
|
+
}
|
597
|
+
|
598
|
+
if (p->status == 0) {
|
599
|
+
return Qnil;
|
600
|
+
}
|
601
|
+
|
602
|
+
if ((ssize_t)size > 0) {
|
603
|
+
char *destp = RSTRING_PTR(dest);
|
604
|
+
size_t destsize = size;
|
605
|
+
destsize = fdec_read_decode(dec, p, destp, destsize);
|
606
|
+
rb_str_set_len(dest, destsize);
|
607
|
+
} else {
|
608
|
+
const size_t tmpsize = 4 * 1024 * 1024;
|
609
|
+
VALUE tmpbuf = rb_str_tmp_new(tmpsize);
|
610
|
+
char *tmp = RSTRING_PTR(tmpbuf);
|
611
|
+
size_t s;
|
612
|
+
rb_str_set_len(dest, 0);
|
613
|
+
while ((s = fdec_read_decode(dec, p, tmp, tmpsize)) > 0) {
|
614
|
+
rb_str_buf_cat(dest, tmp, s);
|
615
|
+
}
|
616
|
+
rb_str_resize(tmpbuf, 0);
|
617
|
+
}
|
618
|
+
|
619
|
+
rb_obj_infect(dest, dec);
|
620
|
+
|
621
|
+
if (RSTRING_LEN(dest) > 0) {
|
622
|
+
return dest;
|
623
|
+
} else {
|
624
|
+
return Qnil;
|
625
|
+
}
|
626
|
+
}
|
627
|
+
|
628
|
+
/*
|
629
|
+
* call-seq:
|
630
|
+
* getc -> String | nil
|
631
|
+
*
|
632
|
+
* Read one byte character.
|
633
|
+
*/
|
634
|
+
static VALUE
|
635
|
+
fdec_getc(VALUE dec)
|
636
|
+
{
|
637
|
+
struct decoder *p = getdecoder(dec);
|
638
|
+
|
639
|
+
if (p->status == 0) {
|
640
|
+
return Qnil;
|
641
|
+
}
|
642
|
+
|
643
|
+
char ch;
|
644
|
+
size_t s = fdec_read_decode(dec, p, &ch, 1);
|
645
|
+
if (s > 0) {
|
646
|
+
VALUE v = rb_str_new(&ch, 1);
|
647
|
+
rb_obj_infect(v, dec);
|
648
|
+
return v;
|
649
|
+
} else {
|
650
|
+
return Qnil;
|
651
|
+
}
|
652
|
+
}
|
653
|
+
|
654
|
+
/*
|
655
|
+
* call-seq:
|
656
|
+
* getbyte -> Integer | nil
|
657
|
+
*
|
658
|
+
* Read one byte code integer.
|
659
|
+
*/
|
660
|
+
static VALUE
|
661
|
+
fdec_getbyte(VALUE dec)
|
662
|
+
{
|
663
|
+
struct decoder *p = getdecoder(dec);
|
664
|
+
|
665
|
+
char ch;
|
666
|
+
size_t s = fdec_read_decode(dec, p, &ch, 1);
|
667
|
+
if (s > 0) {
|
668
|
+
return INT2FIX(ch);
|
669
|
+
} else {
|
670
|
+
return Qnil;
|
671
|
+
}
|
672
|
+
}
|
673
|
+
|
674
|
+
static VALUE
|
675
|
+
fdec_close(VALUE dec)
|
676
|
+
{
|
677
|
+
struct decoder *p = getdecoder(dec);
|
678
|
+
p->status = 0;
|
679
|
+
// TODO: destroy decoder
|
680
|
+
return dec;
|
681
|
+
}
|
682
|
+
|
683
|
+
static VALUE
|
684
|
+
fdec_eof(VALUE dec)
|
685
|
+
{
|
686
|
+
struct decoder *p = getdecoder(dec);
|
687
|
+
if (p->status == 0) {
|
688
|
+
return Qtrue;
|
689
|
+
} else {
|
690
|
+
return Qfalse;
|
691
|
+
}
|
692
|
+
}
|
693
|
+
|
694
|
+
static VALUE
|
695
|
+
fdec_inport(VALUE dec)
|
696
|
+
{
|
697
|
+
return getdecoder(dec)->inport;
|
698
|
+
}
|
699
|
+
|
700
|
+
static int
|
701
|
+
fdec_blocksize(struct decoder *p)
|
702
|
+
{
|
703
|
+
return aux_frame_blocksize(&p->info);
|
704
|
+
}
|
705
|
+
|
706
|
+
static VALUE
|
707
|
+
fdec_prefs_blocksize(VALUE dec)
|
708
|
+
{
|
709
|
+
return INT2NUM(fdec_blocksize(getdecoder(dec)));
|
710
|
+
}
|
711
|
+
|
712
|
+
static VALUE
|
713
|
+
fdec_prefs_blocklink(VALUE dec)
|
714
|
+
{
|
715
|
+
return aux_frame_blocklink(&getdecoder(dec)->info) ? Qtrue : Qfalse;
|
716
|
+
}
|
717
|
+
|
718
|
+
static VALUE
|
719
|
+
fdec_prefs_checksum(VALUE dec)
|
720
|
+
{
|
721
|
+
return aux_frame_checksum(&getdecoder(dec)->info) ? Qtrue : Qfalse;
|
722
|
+
}
|
723
|
+
|
724
|
+
static VALUE
|
725
|
+
fdec_inspect(VALUE dec)
|
726
|
+
{
|
727
|
+
struct decoder *p = getdecoderp(dec);
|
728
|
+
if (p) {
|
729
|
+
return rb_sprintf("#<%s:%p inport=#<%s:%p>, blocksize=%d, blocklink=%s, checksum=%s>",
|
730
|
+
rb_obj_classname(dec), (void *)dec,
|
731
|
+
rb_obj_classname(p->inport), (void *)p->inport,
|
732
|
+
fdec_blocksize(p),
|
733
|
+
aux_frame_blocklink(&p->info) ? "true" : "false",
|
734
|
+
aux_frame_checksum(&p->info) ? "true" : "false");
|
735
|
+
} else {
|
736
|
+
return rb_sprintf("#<%s:%p **INVALID REFERENCE**>",
|
737
|
+
rb_obj_classname(dec), (void *)dec);
|
738
|
+
}
|
739
|
+
}
|
740
|
+
|
741
|
+
/*** setup for LZ4::Encoder and LZ4::Decoder ***/
|
742
|
+
|
743
|
+
void
|
744
|
+
extlz4_init_frameapi(void)
|
745
|
+
{
|
746
|
+
id_op_lshift = rb_intern("<<");
|
747
|
+
id_read = rb_intern("read");
|
748
|
+
|
749
|
+
VALUE cEncoder = rb_define_class_under(extlz4_mLZ4, "Encoder", rb_cObject);
|
750
|
+
rb_define_alloc_func(cEncoder, fenc_alloc);
|
751
|
+
rb_define_method(cEncoder, "initialize", RUBY_METHOD_FUNC(fenc_init), -1);
|
752
|
+
rb_define_method(cEncoder, "write", RUBY_METHOD_FUNC(fenc_write), -1);
|
753
|
+
rb_define_method(cEncoder, "<<", RUBY_METHOD_FUNC(fenc_push), 1);
|
754
|
+
rb_define_method(cEncoder, "flush", RUBY_METHOD_FUNC(fenc_flush), 0);
|
755
|
+
rb_define_method(cEncoder, "close", RUBY_METHOD_FUNC(fenc_close), 0);
|
756
|
+
rb_define_alias(cEncoder, "finish", "close");
|
757
|
+
rb_define_method(cEncoder, "outport", RUBY_METHOD_FUNC(fenc_getoutport), 0);
|
758
|
+
rb_define_method(cEncoder, "outport=", RUBY_METHOD_FUNC(fenc_setoutport), 1);
|
759
|
+
rb_define_method(cEncoder, "prefs_level", RUBY_METHOD_FUNC(fenc_prefs_level), 0);
|
760
|
+
rb_define_method(cEncoder, "prefs_blocksize", RUBY_METHOD_FUNC(fenc_prefs_blocksize), 0);
|
761
|
+
rb_define_method(cEncoder, "prefs_blocklink", RUBY_METHOD_FUNC(fenc_prefs_blocklink), 0);
|
762
|
+
rb_define_method(cEncoder, "prefs_checksum", RUBY_METHOD_FUNC(fenc_prefs_checksum), 0);
|
763
|
+
rb_define_method(cEncoder, "inspect", RUBY_METHOD_FUNC(fenc_inspect), 0);
|
764
|
+
|
765
|
+
VALUE cDecoder = rb_define_class_under(extlz4_mLZ4, "Decoder", rb_cObject);
|
766
|
+
rb_define_alloc_func(cDecoder, fdec_alloc);
|
767
|
+
rb_define_method(cDecoder, "initialize", RUBY_METHOD_FUNC(fdec_init), -1);
|
768
|
+
rb_define_method(cDecoder, "read", RUBY_METHOD_FUNC(fdec_read), -1);
|
769
|
+
rb_define_method(cDecoder, "getc", RUBY_METHOD_FUNC(fdec_getc), 0);
|
770
|
+
rb_define_method(cDecoder, "getbyte", RUBY_METHOD_FUNC(fdec_getbyte), 0);
|
771
|
+
rb_define_method(cDecoder, "close", RUBY_METHOD_FUNC(fdec_close), 0);
|
772
|
+
rb_define_alias(cDecoder, "finish", "close");
|
773
|
+
rb_define_method(cDecoder, "eof", RUBY_METHOD_FUNC(fdec_eof), 0);
|
774
|
+
rb_define_method(cDecoder, "inport", RUBY_METHOD_FUNC(fdec_inport), 0);
|
775
|
+
rb_define_alias(cDecoder, "eof?", "eof");
|
776
|
+
rb_define_method(cDecoder, "prefs_blocksize", RUBY_METHOD_FUNC(fdec_prefs_blocksize), 0);
|
777
|
+
rb_define_method(cDecoder, "prefs_blocklink", RUBY_METHOD_FUNC(fdec_prefs_blocklink), 0);
|
778
|
+
rb_define_method(cDecoder, "prefs_checksum", RUBY_METHOD_FUNC(fdec_prefs_checksum), 0);
|
779
|
+
rb_define_method(cDecoder, "inspect", RUBY_METHOD_FUNC(fdec_inspect), 0);
|
780
|
+
}
|