extlzham 0.0.1.PROTOTYPE → 0.0.1.PROTOTYPE2

Sign up to get free protection for your applications and to get access to all the features.
data/ext/encoder.c ADDED
@@ -0,0 +1,338 @@
1
+ #include "extlzham.h"
2
+
3
+ VALUE cEncoder;
4
+
5
+ static inline lzham_compress_params
6
+ scan_encode_params(VALUE opts)
7
+ {
8
+ lzham_compress_params p;
9
+ memset(&p, 0, sizeof(p));
10
+ p.m_struct_size = sizeof(p);
11
+ if (NIL_P(opts)) {
12
+ p.m_dict_size_log2 = LZHAM_MIN_DICT_SIZE_LOG2;
13
+ p.m_level = LZHAM_COMP_LEVEL_DEFAULT;
14
+ p.m_table_update_rate = 0;
15
+ p.m_max_helper_threads = -1;
16
+ p.m_compress_flags = 0; // (see lzham_compress_flags enum)
17
+ p.m_num_seed_bytes = 0;
18
+ p.m_pSeed_bytes = NULL;
19
+ p.m_table_max_update_interval = 0;
20
+ p.m_table_update_interval_slow_rate = 0;
21
+ } else {
22
+ p.m_dict_size_log2 = aux_hash_lookup_to_u32(opts, IDdictsize, LZHAM_MIN_DICT_SIZE_LOG2);
23
+ p.m_level = aux_hash_lookup_to_u32(opts, IDlevel, LZHAM_COMP_LEVEL_DEFAULT);
24
+ p.m_table_update_rate = aux_hash_lookup_to_u32(opts, IDtable_update_rate, 0);
25
+ p.m_max_helper_threads = aux_hash_lookup_to_u32(opts, IDthreads, -1);
26
+ p.m_compress_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
+ return p;
33
+ }
34
+
35
+ static void
36
+ scan_encode_args(int argc, VALUE argv[], VALUE *src, size_t *srcsize, VALUE *dest, size_t *destsize, lzham_compress_params *params)
37
+ {
38
+ VALUE opts;
39
+ rb_scan_args(argc, argv, "11:", src, dest, &opts);
40
+ rb_check_type(*src, RUBY_T_STRING);
41
+ //rb_str_locktmp(src);
42
+ *srcsize = RSTRING_LEN(*src);
43
+ *destsize = lzham_z_compressBound(*srcsize);
44
+ if (NIL_P(*dest)) {
45
+ *dest = rb_str_buf_new(*destsize);
46
+ } else {
47
+ rb_check_type(*dest, RUBY_T_STRING);
48
+ rb_str_modify(*dest);
49
+ rb_str_set_len(*dest, 0);
50
+ rb_str_modify_expand(*dest, *destsize);
51
+ }
52
+ *params = scan_encode_params(opts);
53
+ }
54
+
55
+ /*
56
+ * call-seq:
57
+ * encode(src, opts = {}) -> encoded string
58
+ * encode(src, dest, opts = {}) -> encoded string
59
+ */
60
+ static VALUE
61
+ ext_s_encode(int argc, VALUE argv[], VALUE mod)
62
+ {
63
+ VALUE src, dest;
64
+ size_t srcsize, destsize;
65
+ lzham_compress_params params;
66
+ scan_encode_args(argc, argv, &src, &srcsize, &dest, &destsize, &params);
67
+ lzham_compress_status_t s;
68
+ s = lzham_compress_memory(&params,
69
+ (lzham_uint8 *)RSTRING_PTR(dest), &destsize,
70
+ (lzham_uint8 *)RSTRING_PTR(src), srcsize, NULL);
71
+ //rb_str_unlocktmp(src);
72
+
73
+ if (s != LZHAM_COMP_STATUS_SUCCESS) {
74
+ rb_str_resize(dest, 0);
75
+ aux_encode_error(s);
76
+ }
77
+
78
+ rb_str_resize(dest, destsize);
79
+ rb_str_set_len(dest, destsize);
80
+
81
+ return dest;
82
+ }
83
+
84
+ struct encoder
85
+ {
86
+ lzham_compress_state_ptr encoder;
87
+ VALUE outport;
88
+ VALUE outbuf;
89
+ };
90
+
91
+ static void
92
+ ext_enc_mark(struct encoder *p)
93
+ {
94
+ if (p) {
95
+ rb_gc_mark(p->outport);
96
+ rb_gc_mark(p->outbuf);
97
+ }
98
+ }
99
+
100
+ static void
101
+ ext_enc_free(struct encoder *p)
102
+ {
103
+ if (p) {
104
+ if (p->encoder) {
105
+ lzham_compress_deinit(p->encoder);
106
+ }
107
+ }
108
+ }
109
+
110
+ static VALUE
111
+ ext_enc_alloc(VALUE klass)
112
+ {
113
+ struct encoder *p;
114
+ VALUE obj = Data_Make_Struct(klass, struct encoder, ext_enc_mark, ext_enc_free, p);
115
+ return obj;
116
+ }
117
+
118
+ static inline struct encoder *
119
+ aux_encoder_refp(VALUE obj)
120
+ {
121
+ struct encoder *p;
122
+ Data_Get_Struct(obj, struct encoder, p);
123
+ return p;
124
+ }
125
+
126
+ static inline struct encoder *
127
+ aux_encoder_ref(VALUE obj)
128
+ {
129
+ struct encoder *p = aux_encoder_refp(obj);
130
+ if (!p || !p->encoder) {
131
+ rb_raise(eError,
132
+ "not initialized - #<%s:%p>",
133
+ rb_obj_classname(obj), (void *)obj);
134
+ }
135
+ return p;
136
+ }
137
+
138
+ /*
139
+ * call-seq:
140
+ * initialize(outport = nil, opts = {})
141
+ */
142
+ static VALUE
143
+ ext_enc_init(int argc, VALUE argv[], VALUE enc)
144
+ {
145
+ struct encoder *p = DATA_PTR(enc);
146
+ if (p->encoder) {
147
+ rb_raise(eError,
148
+ "already initialized - #<%s:%p>",
149
+ rb_obj_classname(enc), (void *)enc);
150
+ }
151
+
152
+ VALUE outport, opts;
153
+ rb_scan_args(argc, argv, "01:", &outport, &opts);
154
+ if (NIL_P(outport)) { outport = rb_str_buf_new(0); }
155
+ lzham_compress_params params = scan_encode_params(opts);
156
+ p->encoder = lzham_compress_init(&params);
157
+ if (!p->encoder) {
158
+ rb_raise(eError,
159
+ "failed lzham_compress_init - #<%s:%p>",
160
+ rb_obj_classname(enc), (void *)enc);
161
+ }
162
+
163
+ p->outbuf = rb_str_buf_new(WORKBUF_SIZE);
164
+ p->outport = outport;
165
+
166
+ return enc;
167
+ }
168
+
169
+ struct enc_update_args
170
+ {
171
+ VALUE encoder;
172
+ VALUE src;
173
+ int flush;
174
+ };
175
+
176
+ struct aux_lzham_compress2_nogvl
177
+ {
178
+ lzham_compress_state_ptr state;
179
+ const lzham_uint8 *inbuf;
180
+ size_t *insize;
181
+ lzham_uint8 *outbuf;
182
+ size_t *outsize;
183
+ lzham_flush_t flush;
184
+ };
185
+
186
+ static void *
187
+ aux_lzham_compress2_nogvl(void *px)
188
+ {
189
+ struct aux_lzham_compress2_nogvl *p = px;
190
+ return (void *)lzham_compress2(p->state,
191
+ p->inbuf, p->insize, p->outbuf, p->outsize, p->flush);
192
+ }
193
+
194
+ static inline lzham_compress_status_t
195
+ aux_lzham_compress2(lzham_compress_state_ptr state,
196
+ const lzham_uint8 *inbuf, size_t *insize,
197
+ lzham_uint8 *outbuf, size_t *outsize,
198
+ lzham_flush_t flush)
199
+ {
200
+ struct aux_lzham_compress2_nogvl p = {
201
+ .state = state,
202
+ .inbuf = inbuf,
203
+ .insize = insize,
204
+ .outbuf = outbuf,
205
+ .outsize = outsize,
206
+ .flush = flush,
207
+ };
208
+
209
+ return (lzham_compress_status_t)rb_thread_call_without_gvl(aux_lzham_compress2_nogvl, &p, 0, 0);
210
+ }
211
+
212
+ static VALUE
213
+ enc_update_protected(struct enc_update_args *args)
214
+ {
215
+ struct encoder *p = aux_encoder_ref(args->encoder);
216
+ const char *inbuf, *intail;
217
+
218
+ if (NIL_P(args->src)) {
219
+ inbuf = NULL;
220
+ intail = NULL;
221
+ } else {
222
+ inbuf = RSTRING_PTR(args->src);
223
+ intail = inbuf + RSTRING_LEN(args->src);
224
+ }
225
+
226
+ lzham_compress_status_t s;
227
+ do {
228
+ size_t insize = intail - inbuf;
229
+ aux_str_reserve(p->outbuf, WORKBUF_SIZE);
230
+ rb_str_locktmp(p->outbuf);
231
+ size_t outsize = rb_str_capacity(p->outbuf);
232
+ s = aux_lzham_compress2(p->encoder,
233
+ (lzham_uint8 *)inbuf, &insize,
234
+ (lzham_uint8 *)RSTRING_PTR(p->outbuf), &outsize, args->flush);
235
+ rb_str_unlocktmp(p->outbuf);
236
+ if (!NIL_P(args->src)) {
237
+ inbuf += insize;
238
+ }
239
+ //fprintf(stderr, "%s:%d:%s: status=%s (%d), insize=%zu, outsize=%zu\n", __FILE__, __LINE__, __func__, aux_encode_status_str(s), s, insize, outsize);
240
+ if (s != LZHAM_COMP_STATUS_SUCCESS &&
241
+ s != LZHAM_COMP_STATUS_NEEDS_MORE_INPUT &&
242
+ s != LZHAM_COMP_STATUS_NOT_FINISHED &&
243
+ s != LZHAM_COMP_STATUS_HAS_MORE_OUTPUT) {
244
+
245
+ aux_encode_error(s);
246
+ }
247
+ if (outsize > 0) {
248
+ rb_str_set_len(p->outbuf, outsize);
249
+ rb_funcall2(p->outport, ID_op_lshift, 1, &p->outbuf);
250
+ }
251
+ } while (inbuf < intail || s == LZHAM_COMP_STATUS_HAS_MORE_OUTPUT);
252
+
253
+ return 0;
254
+ }
255
+
256
+ static inline void
257
+ enc_update(VALUE enc, VALUE src, int flush)
258
+ {
259
+ struct enc_update_args args = { enc, src, flush };
260
+ if (NIL_P(src)) {
261
+ enc_update_protected(&args);
262
+ } else {
263
+ rb_str_locktmp(src);
264
+ int state;
265
+ rb_protect((VALUE (*)(VALUE))enc_update_protected, (VALUE)&args, &state);
266
+ rb_str_unlocktmp(src);
267
+ if (state) {
268
+ rb_jump_tag(state);
269
+ }
270
+ }
271
+ }
272
+
273
+ /*
274
+ * call-seq:
275
+ * update(src, flush = LZHAM::NO_FLUSH) -> self
276
+ */
277
+ static VALUE
278
+ ext_enc_update(int argc, VALUE argv[], VALUE enc)
279
+ {
280
+ VALUE src, flush;
281
+ rb_scan_args(argc, argv, "11", &src, &flush);
282
+ rb_check_type(src, RUBY_T_STRING);
283
+ if (NIL_P(flush)) {
284
+ enc_update(enc, src, LZHAM_NO_FLUSH);
285
+ } else {
286
+ enc_update(enc, src, NUM2INT(flush));
287
+ }
288
+ return enc;
289
+ }
290
+
291
+ static VALUE
292
+ ext_enc_finish(VALUE enc)
293
+ {
294
+ enc_update(enc, Qnil, LZHAM_FINISH);
295
+ return enc;
296
+ }
297
+
298
+ /*
299
+ * same as <tt>enc.update(src)</tt>
300
+ */
301
+ static VALUE
302
+ ext_enc_op_lshift(VALUE enc, VALUE src)
303
+ {
304
+ rb_check_type(src, RUBY_T_STRING);
305
+ enc_update(enc, src, LZHAM_NO_FLUSH);
306
+ return enc;
307
+ }
308
+
309
+
310
+ static VALUE
311
+ ext_enc_get_outport(VALUE enc)
312
+ {
313
+ struct encoder *p = aux_encoder_ref(enc);
314
+ return p->outport;
315
+ }
316
+
317
+ static VALUE
318
+ ext_enc_set_outport(VALUE enc, VALUE outport)
319
+ {
320
+ struct encoder *p = aux_encoder_ref(enc);
321
+ p->outport = outport;
322
+ return outport;
323
+ }
324
+
325
+ void
326
+ init_encoder(void)
327
+ {
328
+ cEncoder = rb_define_class_under(mLZHAM, "Encoder", rb_cObject);
329
+ rb_include_module(cEncoder, mConsts);
330
+ rb_define_alloc_func(cEncoder, ext_enc_alloc);
331
+ rb_define_singleton_method(cEncoder, "encode", RUBY_METHOD_FUNC(ext_s_encode), -1);
332
+ rb_define_method(cEncoder, "initialize", RUBY_METHOD_FUNC(ext_enc_init), -1);
333
+ rb_define_method(cEncoder, "update", RUBY_METHOD_FUNC(ext_enc_update), -1);
334
+ rb_define_method(cEncoder, "finish", RUBY_METHOD_FUNC(ext_enc_finish), 0);
335
+ rb_define_method(cEncoder, "<<", RUBY_METHOD_FUNC(ext_enc_op_lshift), 1);
336
+ rb_define_method(cEncoder, "outport", RUBY_METHOD_FUNC(ext_enc_get_outport), 0);
337
+ rb_define_method(cEncoder, "outport=", RUBY_METHOD_FUNC(ext_enc_set_outport), 1);
338
+ }
data/ext/error.c ADDED
@@ -0,0 +1,80 @@
1
+ #include "extlzham.h"
2
+
3
+ VALUE eError;
4
+
5
+ #define SET_MESSAGE(MESG, CONST) \
6
+ case CONST: \
7
+ MESG = #CONST; \
8
+ break \
9
+
10
+ const char *
11
+ aux_encode_status_str(lzham_compress_status_t status)
12
+ {
13
+ const char *mesg;
14
+ switch (status) {
15
+ SET_MESSAGE(mesg, LZHAM_COMP_STATUS_NOT_FINISHED);
16
+ SET_MESSAGE(mesg, LZHAM_COMP_STATUS_NEEDS_MORE_INPUT);
17
+ SET_MESSAGE(mesg, LZHAM_COMP_STATUS_HAS_MORE_OUTPUT);
18
+ SET_MESSAGE(mesg, LZHAM_COMP_STATUS_FIRST_SUCCESS_OR_FAILURE_CODE);
19
+ SET_MESSAGE(mesg, LZHAM_COMP_STATUS_FIRST_FAILURE_CODE);
20
+ SET_MESSAGE(mesg, LZHAM_COMP_STATUS_FAILED_INITIALIZING);
21
+ SET_MESSAGE(mesg, LZHAM_COMP_STATUS_INVALID_PARAMETER);
22
+ SET_MESSAGE(mesg, LZHAM_COMP_STATUS_OUTPUT_BUF_TOO_SMALL);
23
+ default:
24
+ mesg = "unknown code";
25
+ break;
26
+ }
27
+
28
+ return mesg;
29
+ }
30
+
31
+ void
32
+ aux_encode_error(lzham_compress_status_t status)
33
+ {
34
+ rb_raise(eError,
35
+ "LZHAM encode error - %s (0x%04X)",
36
+ aux_encode_status_str(status), status);
37
+ }
38
+
39
+ const char *
40
+ aux_decode_status_str(lzham_decompress_status_t status)
41
+ {
42
+ const char *mesg;
43
+ switch (status) {
44
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_NOT_FINISHED);
45
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT);
46
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_NEEDS_MORE_INPUT);
47
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FIRST_SUCCESS_OR_FAILURE_CODE);
48
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FIRST_FAILURE_CODE);
49
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FAILED_DEST_BUF_TOO_SMALL);
50
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FAILED_EXPECTED_MORE_RAW_BYTES);
51
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FAILED_BAD_CODE);
52
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FAILED_ADLER32);
53
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FAILED_BAD_RAW_BLOCK);
54
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FAILED_BAD_COMP_BLOCK_SYNC_CHECK);
55
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FAILED_BAD_ZLIB_HEADER);
56
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FAILED_NEED_SEED_BYTES);
57
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FAILED_BAD_SEED_BYTES);
58
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_FAILED_BAD_SYNC_BLOCK);
59
+ SET_MESSAGE(mesg, LZHAM_DECOMP_STATUS_INVALID_PARAMETER);
60
+ default:
61
+ mesg = "unknown code";
62
+ break;
63
+ }
64
+
65
+ return mesg;
66
+ }
67
+
68
+ void
69
+ aux_decode_error(lzham_decompress_status_t status)
70
+ {
71
+ rb_raise(eError,
72
+ "LZHAM decode error - %s (0x%04X)",
73
+ aux_decode_status_str(status), status);
74
+ }
75
+
76
+ void
77
+ init_error(void)
78
+ {
79
+ eError = rb_define_class_under(mLZHAM, "Error", rb_eRuntimeError);
80
+ }
data/ext/extconf.rb CHANGED
@@ -15,12 +15,14 @@ $VPATH.push "$(srcdir)/../contrib/lzham/lzhamcomp",
15
15
  "$(srcdir)/../contrib/lzham/lzhamdecomp",
16
16
  "$(srcdir)/../contrib/lzham/lzhamlib"
17
17
 
18
- find_header "lzham.h", "$(srcdir)/../contrib/lzham/include"
19
- find_header "lzham_comp.h", "$(srcdir)/../contrib/lzham/lzhamcomp"
20
- find_header "lzham_decomp.h", "$(srcdir)/../contrib/lzham/lzhamdecomp"
18
+ find_header "lzham.h", "$(srcdir)/../contrib/lzham/include" or abort 1
19
+ find_header "lzham_comp.h", "$(srcdir)/../contrib/lzham/lzhamcomp" or abort 1
20
+ find_header "lzham_decomp.h", "$(srcdir)/../contrib/lzham/lzhamdecomp" or abort 1
21
21
 
22
22
  if RbConfig::CONFIG["arch"] =~ /mingw/
23
23
  $CPPFLAGS << " -D__forceinline=__attribute__\\(\\(always_inline\\)\\)"
24
24
  end
25
25
 
26
+ try_link "void main(void){}", " -Wl,-Bsymbolic " and $LDFLAGS << " -Wl,-Bsymbolic "
27
+
26
28
  create_makefile("extlzham")