extlzham 0.0.1.PROTOTYPE → 0.0.1.PROTOTYPE2
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 +4 -4
- data/README.md +56 -3
- data/Rakefile +8 -4
- data/ext/constants.c +50 -0
- data/ext/decoder.c +315 -0
- data/ext/depend +5 -0
- data/ext/encoder.c +338 -0
- data/ext/error.c +80 -0
- data/ext/extconf.rb +5 -3
- data/ext/extlzham.c +14 -721
- data/ext/extlzham.h +57 -0
- data/lib/extlzham/version.rb +1 -1
- data/lib/extlzham.rb +7 -1
- metadata +14 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38a6dfeed7afbd9178b072cbc682d5d239b396e5
|
4
|
+
data.tar.gz: a70c0b958bd0b1652830755f20ed86a2df3bc695
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2d6760152aac48b4e78646c02ea99fe1f5618a34bda0339de1c00ff955485650adfb389dfc729a02c03bf7d6b59e836f552923ae6810577b8a3acd5d5cebd26
|
7
|
+
data.tar.gz: 2a4324dd8844f739448e18f0f5654494a7e95d786cc6ee437c98142dd3e03a7179cabe1f402f9562dd260007efc826593c6d52f05540158bd953cb6c4c55d5d9
|
data/README.md
CHANGED
@@ -2,19 +2,72 @@
|
|
2
2
|
|
3
3
|
# extlzham - ruby binding for LZHAM
|
4
4
|
|
5
|
-
This is ruby
|
5
|
+
This is ruby bindings for compression library
|
6
6
|
[LZHAM (https://github.com/richgel999/lzham\_codec)](https://github.com/richgel999/lzham_codec).
|
7
7
|
|
8
8
|
* PACKAGE NAME: extlzham
|
9
9
|
* AUTHOR: dearblue <dearblue@users.sourceforge.jp>
|
10
|
-
* VERSION: 0.0.1.
|
10
|
+
* VERSION: 0.0.1.PROTOTYPE2
|
11
11
|
* LICENSING: 2-clause BSD License
|
12
12
|
* REPORT ISSUE TO: <http://sourceforge.jp/projects/rutsubo/ticket/>
|
13
13
|
* DEPENDENCY RUBY: ruby-2.0+
|
14
14
|
* DEPENDENCY RUBY GEMS: (none)
|
15
15
|
* DEPENDENCY LIBRARY: (none)
|
16
16
|
* BUNDLED EXTERNAL LIBRARIES:
|
17
|
-
* LZHAM
|
17
|
+
* LZHAM <https://github.com/richgel999/lzham_codec>
|
18
|
+
|
19
|
+
|
20
|
+
## HOW TO USE
|
21
|
+
|
22
|
+
### Simply process
|
23
|
+
|
24
|
+
``` ruby:ruby
|
25
|
+
# First, load library
|
26
|
+
require "extlzham"
|
27
|
+
|
28
|
+
# Prepair data
|
29
|
+
source = "sample data..." * 50
|
30
|
+
|
31
|
+
# Directly compression
|
32
|
+
encdata = LZHAM.encode(source)
|
33
|
+
|
34
|
+
# Directly decompression
|
35
|
+
decdata = LZHAM.decode(encdata)
|
36
|
+
|
37
|
+
# Comparison source and decoded data
|
38
|
+
p source == decdata
|
39
|
+
```
|
40
|
+
|
41
|
+
### Streaming process
|
42
|
+
|
43
|
+
``` ruby:ruby
|
44
|
+
# First, load library
|
45
|
+
require "extlzham"
|
46
|
+
|
47
|
+
# Prepair data
|
48
|
+
source = "sample data..." * 50
|
49
|
+
sourceio = StringIO.new(source)
|
50
|
+
|
51
|
+
# streaming compression
|
52
|
+
LZHAM.encode(dest = StringIO.new("")) do |encoder|
|
53
|
+
while buf = sourceio.read(50) # Please increase the value if you want to actually use.
|
54
|
+
encoder << buf
|
55
|
+
end
|
56
|
+
# block leave to encoder.close
|
57
|
+
end
|
58
|
+
|
59
|
+
# streaming decompression
|
60
|
+
dest.rewind
|
61
|
+
decdata = ""
|
62
|
+
LZHAM.decode(StringIO.new(decdata)) do |decoder|
|
63
|
+
while buf = dest.read(50)
|
64
|
+
decoder << buf
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Comparison source and decoded data
|
69
|
+
p source == decdata
|
70
|
+
```
|
18
71
|
|
19
72
|
----
|
20
73
|
|
data/Rakefile
CHANGED
@@ -10,10 +10,11 @@ BIN = FileList["bin/*"]
|
|
10
10
|
LIB = FileList["lib/**/*.rb"]
|
11
11
|
SPEC = FileList["spec/**/*"]
|
12
12
|
EXAMPLE = FileList["examples/**/*"]
|
13
|
-
|
13
|
+
GEMSTUB_SRC = "gemstub.rb"
|
14
|
+
RAKEFILE = [File.basename(__FILE__), GEMSTUB_SRC]
|
14
15
|
EXTRA = []
|
15
16
|
|
16
|
-
load
|
17
|
+
load GEMSTUB_SRC
|
17
18
|
|
18
19
|
EXTCONF = FileList["ext/extconf.rb"]
|
19
20
|
EXTCONF.reject! { |n| !File.file?(n) }
|
@@ -59,7 +60,7 @@ unless EXTCONF.empty?
|
|
59
60
|
PLATFORM = platforms1[0]
|
60
61
|
|
61
62
|
RUBY_VERSIONS = RUBYSET.map do |ruby|
|
62
|
-
ver = `#{ruby} --disable gem -rrbconfig -e "puts RbConfig::CONFIG['ruby_version']"`.
|
63
|
+
ver = `#{ruby} --disable gem -rrbconfig -e "puts RbConfig::CONFIG['ruby_version']"`.slice(/\d+\.\d+/)
|
63
64
|
raise "failed ruby checking - ``#{ruby}''" unless $?.success?
|
64
65
|
[ver, ruby]
|
65
66
|
end
|
@@ -85,10 +86,13 @@ unless EXTCONF.empty?
|
|
85
86
|
sh "gem build #{GEMSPEC_NATIVE}"
|
86
87
|
end
|
87
88
|
|
88
|
-
file GEMSPEC_NATIVE =>
|
89
|
+
file GEMSPEC_NATIVE => RAKEFILE do
|
89
90
|
File.write(GEMSPEC_NATIVE, GEMSTUB_NATIVE.to_ruby, mode: "wb")
|
90
91
|
end
|
91
92
|
|
93
|
+
desc "build c-extension libraries"
|
94
|
+
task "sofiles" => SOFILES
|
95
|
+
|
92
96
|
SOFILES_SET.each do |(soname, ruby)|
|
93
97
|
sodir = File.dirname(soname)
|
94
98
|
makefile = File.join(sodir, "Makefile")
|
data/ext/constants.c
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
#include "extlzham.h"
|
2
|
+
|
3
|
+
VALUE mConsts;
|
4
|
+
|
5
|
+
void
|
6
|
+
init_constants(void)
|
7
|
+
{
|
8
|
+
mConsts = rb_define_module_under(mLZHAM, "Constants");
|
9
|
+
rb_include_module(mLZHAM, mConsts);
|
10
|
+
rb_define_const(mConsts, "NO_FLUSH", INT2FIX(LZHAM_NO_FLUSH));
|
11
|
+
rb_define_const(mConsts, "SYNC_FLUSH", INT2FIX(LZHAM_SYNC_FLUSH));
|
12
|
+
rb_define_const(mConsts, "FULL_FLUSH", INT2FIX(LZHAM_FULL_FLUSH));
|
13
|
+
rb_define_const(mConsts, "FINISH", INT2FIX(LZHAM_FINISH));
|
14
|
+
rb_define_const(mConsts, "TABLE_FLUSH", INT2FIX(LZHAM_TABLE_FLUSH));
|
15
|
+
rb_define_const(mConsts, "MIN_DICT_SIZE_LOG2", INT2FIX(LZHAM_MIN_DICT_SIZE_LOG2));
|
16
|
+
rb_define_const(mConsts, "MAX_DICT_SIZE_LOG2_X86", INT2FIX(LZHAM_MAX_DICT_SIZE_LOG2_X86));
|
17
|
+
rb_define_const(mConsts, "MAX_DICT_SIZE_LOG2_X64", INT2FIX(LZHAM_MAX_DICT_SIZE_LOG2_X64));
|
18
|
+
rb_define_const(mConsts, "MAX_HELPER_THREADS", INT2FIX(LZHAM_MAX_HELPER_THREADS));
|
19
|
+
rb_define_const(mConsts, "COMP_FLAG_EXTREME_PARSING", INT2FIX(LZHAM_COMP_FLAG_EXTREME_PARSING));
|
20
|
+
rb_define_const(mConsts, "COMP_FLAG_DETERMINISTIC_PARSING", INT2FIX(LZHAM_COMP_FLAG_DETERMINISTIC_PARSING));
|
21
|
+
rb_define_const(mConsts, "COMP_FLAG_TRADEOFF_DECOMPRESSION_RATE_FOR_COMP_RATIO", INT2FIX(LZHAM_COMP_FLAG_TRADEOFF_DECOMPRESSION_RATE_FOR_COMP_RATIO));
|
22
|
+
rb_define_const(mConsts, "COMP_FLAG_WRITE_ZLIB_STREAM", INT2FIX(LZHAM_COMP_FLAG_WRITE_ZLIB_STREAM));
|
23
|
+
rb_define_const(mConsts, "INSANELY_SLOW_TABLE_UPDATE_RATE", INT2FIX(LZHAM_INSANELY_SLOW_TABLE_UPDATE_RATE));
|
24
|
+
rb_define_const(mConsts, "SLOWEST_TABLE_UPDATE_RATE", INT2FIX(LZHAM_SLOWEST_TABLE_UPDATE_RATE));
|
25
|
+
rb_define_const(mConsts, "DEFAULT_TABLE_UPDATE_RATE", INT2FIX(LZHAM_DEFAULT_TABLE_UPDATE_RATE));
|
26
|
+
rb_define_const(mConsts, "FASTEST_TABLE_UPDATE_RATE", INT2FIX(LZHAM_FASTEST_TABLE_UPDATE_RATE));
|
27
|
+
rb_define_const(mConsts, "DECOMP_FLAG_OUTPUT_UNBUFFERED", INT2FIX(LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED));
|
28
|
+
rb_define_const(mConsts, "DECOMP_FLAG_COMPUTE_ADLER32", INT2FIX(LZHAM_DECOMP_FLAG_COMPUTE_ADLER32));
|
29
|
+
rb_define_const(mConsts, "DECOMP_FLAG_READ_ZLIB_STREAM", INT2FIX(LZHAM_DECOMP_FLAG_READ_ZLIB_STREAM));
|
30
|
+
rb_define_const(mConsts, "LZHAM_NO_FLUSH", INT2FIX(LZHAM_NO_FLUSH));
|
31
|
+
rb_define_const(mConsts, "LZHAM_SYNC_FLUSH", INT2FIX(LZHAM_SYNC_FLUSH));
|
32
|
+
rb_define_const(mConsts, "LZHAM_FULL_FLUSH", INT2FIX(LZHAM_FULL_FLUSH));
|
33
|
+
rb_define_const(mConsts, "LZHAM_FINISH", INT2FIX(LZHAM_FINISH));
|
34
|
+
rb_define_const(mConsts, "LZHAM_TABLE_FLUSH", INT2FIX(LZHAM_TABLE_FLUSH));
|
35
|
+
rb_define_const(mConsts, "LZHAM_MIN_DICT_SIZE_LOG2", INT2FIX(LZHAM_MIN_DICT_SIZE_LOG2));
|
36
|
+
rb_define_const(mConsts, "LZHAM_MAX_DICT_SIZE_LOG2_X86", INT2FIX(LZHAM_MAX_DICT_SIZE_LOG2_X86));
|
37
|
+
rb_define_const(mConsts, "LZHAM_MAX_DICT_SIZE_LOG2_X64", INT2FIX(LZHAM_MAX_DICT_SIZE_LOG2_X64));
|
38
|
+
rb_define_const(mConsts, "LZHAM_MAX_HELPER_THREADS", INT2FIX(LZHAM_MAX_HELPER_THREADS));
|
39
|
+
rb_define_const(mConsts, "LZHAM_COMP_FLAG_EXTREME_PARSING", INT2FIX(LZHAM_COMP_FLAG_EXTREME_PARSING));
|
40
|
+
rb_define_const(mConsts, "LZHAM_COMP_FLAG_DETERMINISTIC_PARSING", INT2FIX(LZHAM_COMP_FLAG_DETERMINISTIC_PARSING));
|
41
|
+
rb_define_const(mConsts, "LZHAM_COMP_FLAG_TRADEOFF_DECOMPRESSION_RATE_FOR_COMP_RATIO", INT2FIX(LZHAM_COMP_FLAG_TRADEOFF_DECOMPRESSION_RATE_FOR_COMP_RATIO));
|
42
|
+
rb_define_const(mConsts, "LZHAM_COMP_FLAG_WRITE_ZLIB_STREAM", INT2FIX(LZHAM_COMP_FLAG_WRITE_ZLIB_STREAM));
|
43
|
+
rb_define_const(mConsts, "LZHAM_INSANELY_SLOW_TABLE_UPDATE_RATE", INT2FIX(LZHAM_INSANELY_SLOW_TABLE_UPDATE_RATE));
|
44
|
+
rb_define_const(mConsts, "LZHAM_SLOWEST_TABLE_UPDATE_RATE", INT2FIX(LZHAM_SLOWEST_TABLE_UPDATE_RATE));
|
45
|
+
rb_define_const(mConsts, "LZHAM_DEFAULT_TABLE_UPDATE_RATE", INT2FIX(LZHAM_DEFAULT_TABLE_UPDATE_RATE));
|
46
|
+
rb_define_const(mConsts, "LZHAM_FASTEST_TABLE_UPDATE_RATE", INT2FIX(LZHAM_FASTEST_TABLE_UPDATE_RATE));
|
47
|
+
rb_define_const(mConsts, "LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED", INT2FIX(LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED));
|
48
|
+
rb_define_const(mConsts, "LZHAM_DECOMP_FLAG_COMPUTE_ADLER32", INT2FIX(LZHAM_DECOMP_FLAG_COMPUTE_ADLER32));
|
49
|
+
rb_define_const(mConsts, "LZHAM_DECOMP_FLAG_READ_ZLIB_STREAM", INT2FIX(LZHAM_DECOMP_FLAG_READ_ZLIB_STREAM));
|
50
|
+
}
|
data/ext/decoder.c
ADDED
@@ -0,0 +1,315 @@
|
|
1
|
+
#include "extlzham.h"
|
2
|
+
|
3
|
+
VALUE cDecoder;
|
4
|
+
|
5
|
+
/*
|
6
|
+
* decoder
|
7
|
+
*/
|
8
|
+
|
9
|
+
static inline lzham_decompress_params
|
10
|
+
aux_conv_decode_params(VALUE opts)
|
11
|
+
{
|
12
|
+
lzham_decompress_params p;
|
13
|
+
memset(&p, 0, sizeof(p));
|
14
|
+
p.m_struct_size = sizeof(p);
|
15
|
+
if (NIL_P(opts)) {
|
16
|
+
p.m_dict_size_log2 = LZHAM_MIN_DICT_SIZE_LOG2;
|
17
|
+
p.m_table_update_rate = 0;
|
18
|
+
p.m_decompress_flags = 0; // (see lzham_decompress_flags enum)
|
19
|
+
p.m_num_seed_bytes = 0;
|
20
|
+
p.m_pSeed_bytes = NULL;
|
21
|
+
p.m_table_max_update_interval = 0;
|
22
|
+
p.m_table_update_interval_slow_rate = 0;
|
23
|
+
} else {
|
24
|
+
p.m_dict_size_log2 = aux_hash_lookup_to_u32(opts, IDdictsize, LZHAM_MIN_DICT_SIZE_LOG2);
|
25
|
+
p.m_table_update_rate = aux_hash_lookup_to_u32(opts, IDtable_update_rate, 0);
|
26
|
+
p.m_decompress_flags = aux_hash_lookup_to_u32(opts, IDflags, 0);
|
27
|
+
p.m_num_seed_bytes = 0;
|
28
|
+
p.m_pSeed_bytes = NULL;
|
29
|
+
p.m_table_max_update_interval = aux_hash_lookup_to_u32(opts, IDtable_max_update_interval, 0);
|
30
|
+
p.m_table_update_interval_slow_rate = aux_hash_lookup_to_u32(opts, IDtable_update_interval_slow_rate, 0);
|
31
|
+
}
|
32
|
+
|
33
|
+
return p;
|
34
|
+
}
|
35
|
+
|
36
|
+
/*
|
37
|
+
* call-seq:
|
38
|
+
* decode(string, max_decoded_size, opts = {}) -> decoded string
|
39
|
+
*/
|
40
|
+
static VALUE
|
41
|
+
ext_s_decode(int argc, VALUE argv[], VALUE mod)
|
42
|
+
{
|
43
|
+
VALUE src, size, opts;
|
44
|
+
rb_scan_args(argc, argv, "2:", &src, &size, &opts);
|
45
|
+
rb_check_type(src, RUBY_T_STRING);
|
46
|
+
rb_str_locktmp(src);
|
47
|
+
size_t srcsize = RSTRING_LEN(src);
|
48
|
+
size_t destsize = NUM2SIZET(size);
|
49
|
+
VALUE dest = rb_str_buf_new(destsize);
|
50
|
+
lzham_decompress_params p = aux_conv_decode_params(opts);
|
51
|
+
lzham_decompress_status_t s;
|
52
|
+
s = lzham_decompress_memory(&p,
|
53
|
+
(lzham_uint8 *)RSTRING_PTR(dest), &destsize,
|
54
|
+
(lzham_uint8 *)RSTRING_PTR(src), srcsize, NULL);
|
55
|
+
|
56
|
+
rb_str_unlocktmp(src);
|
57
|
+
|
58
|
+
if (s != LZHAM_DECOMP_STATUS_SUCCESS) {
|
59
|
+
rb_str_resize(dest, 0);
|
60
|
+
aux_decode_error(s);
|
61
|
+
}
|
62
|
+
|
63
|
+
rb_str_resize(dest, destsize);
|
64
|
+
rb_str_set_len(dest, destsize);
|
65
|
+
|
66
|
+
return dest;
|
67
|
+
}
|
68
|
+
|
69
|
+
struct decoder
|
70
|
+
{
|
71
|
+
lzham_decompress_state_ptr decoder;
|
72
|
+
VALUE outport;
|
73
|
+
VALUE outbuf;
|
74
|
+
};
|
75
|
+
|
76
|
+
static void
|
77
|
+
ext_dec_mark(struct decoder *p)
|
78
|
+
{
|
79
|
+
if (p) {
|
80
|
+
rb_gc_mark(p->outport);
|
81
|
+
rb_gc_mark(p->outbuf);
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
static void
|
86
|
+
ext_dec_free(struct decoder *p)
|
87
|
+
{
|
88
|
+
if (p) {
|
89
|
+
if (p->decoder) {
|
90
|
+
lzham_decompress_deinit(p->decoder);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
static VALUE
|
96
|
+
ext_dec_alloc(VALUE klass)
|
97
|
+
{
|
98
|
+
struct decoder *p;
|
99
|
+
VALUE obj = Data_Make_Struct(klass, struct decoder, ext_dec_mark, ext_dec_free, p);
|
100
|
+
return obj;
|
101
|
+
}
|
102
|
+
|
103
|
+
static inline struct decoder *
|
104
|
+
aux_decoder_refp(VALUE obj)
|
105
|
+
{
|
106
|
+
struct decoder *p;
|
107
|
+
Data_Get_Struct(obj, struct decoder, p);
|
108
|
+
return p;
|
109
|
+
}
|
110
|
+
|
111
|
+
static inline struct decoder *
|
112
|
+
aux_decoder_ref(VALUE obj)
|
113
|
+
{
|
114
|
+
struct decoder *p = aux_decoder_refp(obj);
|
115
|
+
if (!p || !p->decoder) {
|
116
|
+
rb_raise(eError,
|
117
|
+
"not initialized - #<%s:%p>",
|
118
|
+
rb_obj_classname(obj), (void *)obj);
|
119
|
+
}
|
120
|
+
return p;
|
121
|
+
}
|
122
|
+
|
123
|
+
/*
|
124
|
+
* call-seq:
|
125
|
+
* initialize(outport = nil, opts = {})
|
126
|
+
*/
|
127
|
+
static VALUE
|
128
|
+
ext_dec_init(int argc, VALUE argv[], VALUE dec)
|
129
|
+
{
|
130
|
+
struct decoder *p = DATA_PTR(dec);
|
131
|
+
if (p->decoder) {
|
132
|
+
rb_raise(eError,
|
133
|
+
"already initialized - #<%s:%p>",
|
134
|
+
rb_obj_classname(dec), (void *)dec);
|
135
|
+
}
|
136
|
+
|
137
|
+
VALUE outport, opts;
|
138
|
+
rb_scan_args(argc, argv, "01:", &outport, &opts);
|
139
|
+
if (NIL_P(outport)) { outport = rb_str_buf_new(0); }
|
140
|
+
lzham_decompress_params params = aux_conv_decode_params(opts);
|
141
|
+
p->decoder = lzham_decompress_init(¶ms);
|
142
|
+
if (!p->decoder) {
|
143
|
+
rb_raise(eError,
|
144
|
+
"failed lzham_decompress_init - #<%s:%p>",
|
145
|
+
rb_obj_classname(dec), (void *)dec);
|
146
|
+
}
|
147
|
+
|
148
|
+
p->outbuf = rb_str_buf_new(WORKBUF_SIZE);
|
149
|
+
p->outport = outport;
|
150
|
+
|
151
|
+
return dec;
|
152
|
+
}
|
153
|
+
|
154
|
+
struct aux_lzham_decompress_nogvl
|
155
|
+
{
|
156
|
+
lzham_decompress_state_ptr state;
|
157
|
+
const lzham_uint8 *inbuf;
|
158
|
+
size_t *insize;
|
159
|
+
lzham_uint8 *outbuf;
|
160
|
+
size_t *outsize;
|
161
|
+
lzham_bool flags;
|
162
|
+
};
|
163
|
+
|
164
|
+
static void *
|
165
|
+
aux_lzham_decompress_nogvl(void *px)
|
166
|
+
{
|
167
|
+
struct aux_lzham_decompress_nogvl *p = px;
|
168
|
+
return (void *)lzham_decompress(p->state, p->inbuf, p->insize, p->outbuf, p->outsize, p->flags);
|
169
|
+
}
|
170
|
+
|
171
|
+
static inline lzham_decompress_status_t
|
172
|
+
aux_lzham_decompress(lzham_decompress_state_ptr state,
|
173
|
+
const lzham_uint8 *inbuf, size_t *insize,
|
174
|
+
lzham_uint8 *outbuf, size_t *outsize,
|
175
|
+
lzham_bool flags)
|
176
|
+
{
|
177
|
+
struct aux_lzham_decompress_nogvl p = {
|
178
|
+
.state = state,
|
179
|
+
.inbuf = inbuf,
|
180
|
+
.insize = insize,
|
181
|
+
.outbuf = outbuf,
|
182
|
+
.outsize = outsize,
|
183
|
+
.flags = flags,
|
184
|
+
};
|
185
|
+
|
186
|
+
return (lzham_decompress_status_t)rb_thread_call_without_gvl(aux_lzham_decompress_nogvl, &p, 0, 0);
|
187
|
+
}
|
188
|
+
|
189
|
+
struct dec_update_args
|
190
|
+
{
|
191
|
+
VALUE decoder;
|
192
|
+
VALUE src;
|
193
|
+
int flush;
|
194
|
+
};
|
195
|
+
|
196
|
+
static VALUE
|
197
|
+
dec_update_protected(struct dec_update_args *args)
|
198
|
+
{
|
199
|
+
struct decoder *p = aux_decoder_ref(args->decoder);
|
200
|
+
const char *inbuf, *intail;
|
201
|
+
|
202
|
+
if (NIL_P(args->src)) {
|
203
|
+
inbuf = NULL;
|
204
|
+
intail = NULL;
|
205
|
+
} else {
|
206
|
+
inbuf = RSTRING_PTR(args->src);
|
207
|
+
intail = inbuf + RSTRING_LEN(args->src);
|
208
|
+
}
|
209
|
+
|
210
|
+
lzham_decompress_status_t s;
|
211
|
+
do {
|
212
|
+
size_t insize = intail - inbuf;
|
213
|
+
aux_str_reserve(p->outbuf, WORKBUF_SIZE);
|
214
|
+
rb_str_locktmp(p->outbuf);
|
215
|
+
size_t outsize = rb_str_capacity(p->outbuf);
|
216
|
+
s = aux_lzham_decompress(p->decoder,
|
217
|
+
(lzham_uint8 *)inbuf, &insize,
|
218
|
+
(lzham_uint8 *)RSTRING_PTR(p->outbuf), &outsize, args->flush);
|
219
|
+
rb_str_unlocktmp(p->outbuf);
|
220
|
+
//fprintf(stderr, "%s:%d:%s: status=%s (%d), insize=%zu, outsize=%zu\n", __FILE__, __LINE__, __func__, aux_decode_status_str(s), s, insize, outsize);
|
221
|
+
if (!NIL_P(args->src)) {
|
222
|
+
inbuf += insize;
|
223
|
+
}
|
224
|
+
if (s != LZHAM_DECOMP_STATUS_NOT_FINISHED &&
|
225
|
+
s != LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT &&
|
226
|
+
s != LZHAM_DECOMP_STATUS_NEEDS_MORE_INPUT &&
|
227
|
+
s != LZHAM_DECOMP_STATUS_SUCCESS) {
|
228
|
+
|
229
|
+
aux_decode_error(s);
|
230
|
+
}
|
231
|
+
if (outsize > 0) {
|
232
|
+
rb_str_set_len(p->outbuf, outsize);
|
233
|
+
rb_funcall2(p->outport, ID_op_lshift, 1, &p->outbuf);
|
234
|
+
}
|
235
|
+
} while (inbuf < intail || s == LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT);
|
236
|
+
|
237
|
+
return 0;
|
238
|
+
}
|
239
|
+
|
240
|
+
static inline void
|
241
|
+
dec_update(VALUE dec, VALUE src, int flush)
|
242
|
+
{
|
243
|
+
struct dec_update_args args = { dec, src, flush };
|
244
|
+
if (NIL_P(src)) {
|
245
|
+
dec_update_protected(&args);
|
246
|
+
} else {
|
247
|
+
rb_str_locktmp(src);
|
248
|
+
int state;
|
249
|
+
rb_protect((VALUE (*)(VALUE))dec_update_protected, (VALUE)&args, &state);
|
250
|
+
rb_str_unlocktmp(src);
|
251
|
+
if (state) {
|
252
|
+
rb_jump_tag(state);
|
253
|
+
}
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
/*
|
258
|
+
* call-seq:
|
259
|
+
* update(src, flush = false) -> self
|
260
|
+
*/
|
261
|
+
static VALUE
|
262
|
+
ext_dec_update(int argc, VALUE argv[], VALUE dec)
|
263
|
+
{
|
264
|
+
VALUE src, flush;
|
265
|
+
rb_scan_args(argc, argv, "11", &src, &flush);
|
266
|
+
rb_check_type(src, RUBY_T_STRING);
|
267
|
+
dec_update(dec, src, RTEST(flush) ? 1 : 0);
|
268
|
+
return dec;
|
269
|
+
}
|
270
|
+
|
271
|
+
static VALUE
|
272
|
+
ext_dec_finish(VALUE dec)
|
273
|
+
{
|
274
|
+
dec_update(dec, Qnil, 1);
|
275
|
+
return dec;
|
276
|
+
}
|
277
|
+
|
278
|
+
static VALUE
|
279
|
+
ext_dec_op_lshift(VALUE dec, VALUE src)
|
280
|
+
{
|
281
|
+
rb_check_type(src, RUBY_T_STRING);
|
282
|
+
dec_update(dec, src, 0);
|
283
|
+
return dec;
|
284
|
+
}
|
285
|
+
|
286
|
+
static VALUE
|
287
|
+
ext_dec_get_outport(VALUE dec)
|
288
|
+
{
|
289
|
+
struct decoder *p = aux_decoder_ref(dec);
|
290
|
+
return p->outport;
|
291
|
+
}
|
292
|
+
|
293
|
+
static VALUE
|
294
|
+
ext_dec_set_outport(VALUE dec, VALUE outport)
|
295
|
+
{
|
296
|
+
struct decoder *p = aux_decoder_ref(dec);
|
297
|
+
p->outport = outport;
|
298
|
+
return outport;
|
299
|
+
}
|
300
|
+
|
301
|
+
void
|
302
|
+
init_decoder(void)
|
303
|
+
{
|
304
|
+
cDecoder = rb_define_class_under(mLZHAM, "Decoder", rb_cObject);
|
305
|
+
rb_include_module(cDecoder, mConsts);
|
306
|
+
rb_define_alloc_func(cDecoder, ext_dec_alloc);
|
307
|
+
rb_define_singleton_method(cDecoder, "decode", RUBY_METHOD_FUNC(ext_s_decode), -1);
|
308
|
+
rb_define_method(cDecoder, "initialize", RUBY_METHOD_FUNC(ext_dec_init), -1);
|
309
|
+
rb_define_method(cDecoder, "update", RUBY_METHOD_FUNC(ext_dec_update), -1);
|
310
|
+
rb_define_method(cDecoder, "finish", RUBY_METHOD_FUNC(ext_dec_finish), 0);
|
311
|
+
rb_define_method(cDecoder, "<<", RUBY_METHOD_FUNC(ext_dec_op_lshift), 1);
|
312
|
+
rb_define_method(cDecoder, "outport", RUBY_METHOD_FUNC(ext_dec_get_outport), 0);
|
313
|
+
rb_define_method(cDecoder, "outport=", RUBY_METHOD_FUNC(ext_dec_set_outport), 1);
|
314
|
+
|
315
|
+
}
|