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.
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")