libbin 1.0.7 → 1.0.8
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/ext/libbin/data_types.c +466 -0
- data/ext/libbin/data_types.h +15 -0
- data/ext/libbin/libbin_c.c +1450 -41
- data/ext/libbin/libbin_c.h +12 -0
- data/ext/libbin/libbin_endian.h +126 -0
- data/lib/libbin/data_types.rb +56 -353
- data/lib/libbin.rb +7 -351
- data/libbin.gemspec +1 -1
- metadata +6 -2
data/ext/libbin/libbin_c.c
CHANGED
@@ -1,65 +1,1474 @@
|
|
1
1
|
#include "ruby.h"
|
2
|
-
#include "./
|
3
|
-
#include "./pghalf.h"
|
2
|
+
#include "./libbin_c.h"
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
VALUE cField;
|
5
|
+
VALUE mLibBin;
|
6
|
+
VALUE cDataConverter;
|
7
|
+
|
8
|
+
static VALUE rb_str_dot_dot;
|
9
|
+
static VALUE rb_str___parent;
|
10
|
+
static VALUE rb_str_backslash;
|
11
|
+
static VALUE rb_str_dot;
|
12
|
+
|
13
|
+
struct cField_data {
|
14
|
+
VALUE name;
|
15
|
+
VALUE type;
|
16
|
+
VALUE length;
|
17
|
+
VALUE count;
|
18
|
+
VALUE offset;
|
19
|
+
VALUE sequence;
|
20
|
+
VALUE condition;
|
21
|
+
VALUE relative_offset;
|
22
|
+
ID getter;
|
23
|
+
ID setter;
|
24
|
+
};
|
25
|
+
|
26
|
+
static void cField_mark(void* data) {
|
27
|
+
void *start = data;
|
28
|
+
void *end = &((struct cField_data*)data)->getter;
|
29
|
+
rb_gc_mark_locations((VALUE *)start, (VALUE *)end);
|
30
|
+
}
|
31
|
+
|
32
|
+
static size_t cField_size(const void* data) {
|
33
|
+
(void)data;
|
34
|
+
return sizeof(struct cField_data);
|
35
|
+
}
|
36
|
+
|
37
|
+
static const rb_data_type_t cField_type = {
|
38
|
+
.wrap_struct_name = "cField_data",
|
39
|
+
.function = {
|
40
|
+
.dmark = cField_mark,
|
41
|
+
.dfree = RUBY_DEFAULT_FREE,
|
42
|
+
.dsize = cField_size,
|
43
|
+
},
|
44
|
+
.data = NULL,
|
45
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
8
46
|
};
|
9
47
|
|
48
|
+
static VALUE cField_alloc(VALUE self) {
|
49
|
+
struct cField_data *data;
|
50
|
+
VALUE res = TypedData_Make_Struct(self, struct cField_data, &cField_type, data);
|
51
|
+
return res;
|
52
|
+
}
|
53
|
+
|
54
|
+
static ID id_gsub;
|
55
|
+
|
56
|
+
static inline VALUE cField_preprocess_expression(VALUE self, VALUE expression) {
|
57
|
+
if (T_STRING == TYPE(expression)) {
|
58
|
+
VALUE proc = rb_str_new_cstr("proc {");
|
59
|
+
rb_str_buf_append(proc, rb_funcall(rb_funcall(expression, id_gsub, 2, rb_str_dot_dot, rb_str___parent), id_gsub, 2, rb_str_backslash, rb_str_dot));
|
60
|
+
rb_str_cat_cstr(proc, "}");
|
61
|
+
return rb_obj_instance_eval(1, &proc, self);
|
62
|
+
} else
|
63
|
+
return expression;
|
64
|
+
}
|
65
|
+
|
66
|
+
static VALUE cField_initialize(
|
67
|
+
VALUE self,
|
68
|
+
VALUE name,
|
69
|
+
VALUE type,
|
70
|
+
VALUE length,
|
71
|
+
VALUE count,
|
72
|
+
VALUE offset,
|
73
|
+
VALUE sequence,
|
74
|
+
VALUE condition,
|
75
|
+
VALUE relative_offset) {
|
76
|
+
VALUE tmp;
|
77
|
+
struct cField_data *data;
|
78
|
+
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
79
|
+
data->name = name;
|
80
|
+
tmp = rb_str_dup(rb_obj_as_string(name));
|
81
|
+
data->getter = rb_intern_str(tmp);
|
82
|
+
data->setter = rb_intern_str(rb_str_cat(tmp, "=", 1));
|
83
|
+
data->type = cField_preprocess_expression(self, type);
|
84
|
+
data->length = cField_preprocess_expression(self, length);
|
85
|
+
data->count = cField_preprocess_expression(self, count);
|
86
|
+
data->offset = cField_preprocess_expression(self, offset);
|
87
|
+
data->sequence = sequence;
|
88
|
+
data->condition = cField_preprocess_expression(self, condition);
|
89
|
+
data->relative_offset = relative_offset;
|
90
|
+
return self;
|
91
|
+
}
|
92
|
+
|
93
|
+
static VALUE cField_name(VALUE self) {
|
94
|
+
struct cField_data *data;
|
95
|
+
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
96
|
+
return data->name;
|
97
|
+
}
|
98
|
+
|
99
|
+
static VALUE cField_get_type(VALUE self) {
|
100
|
+
struct cField_data *data;
|
101
|
+
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
102
|
+
return data->type;
|
103
|
+
}
|
104
|
+
|
105
|
+
static VALUE cField_length(VALUE self) {
|
106
|
+
struct cField_data *data;
|
107
|
+
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
108
|
+
return data->length;
|
109
|
+
}
|
110
|
+
|
111
|
+
static VALUE cField_count(VALUE self) {
|
112
|
+
struct cField_data *data;
|
113
|
+
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
114
|
+
return data->count;
|
115
|
+
}
|
116
|
+
|
117
|
+
static VALUE cField_offset(VALUE self) {
|
118
|
+
struct cField_data *data;
|
119
|
+
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
120
|
+
return data->offset;
|
121
|
+
}
|
122
|
+
|
123
|
+
static VALUE cField_sequence(VALUE self) {
|
124
|
+
struct cField_data *data;
|
125
|
+
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
126
|
+
return data->sequence;
|
127
|
+
}
|
128
|
+
|
129
|
+
static VALUE cField_condition(VALUE self) {
|
130
|
+
struct cField_data *data;
|
131
|
+
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
132
|
+
return data->condition;
|
133
|
+
}
|
134
|
+
|
135
|
+
static VALUE cField_relative_offset(VALUE self) {
|
136
|
+
struct cField_data *data;
|
137
|
+
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
138
|
+
return data->relative_offset;
|
139
|
+
}
|
140
|
+
|
141
|
+
static void define_cField() {
|
142
|
+
VALUE ary = rb_ary_new_capa(4);
|
143
|
+
id_gsub = rb_intern("gsub");
|
144
|
+
|
145
|
+
rb_str_dot_dot = rb_str_new_cstr("..");
|
146
|
+
rb_ary_store(ary, 0, rb_str_dot_dot);
|
147
|
+
rb_str___parent = rb_str_new_cstr("__parent");
|
148
|
+
rb_ary_store(ary, 1, rb_str___parent);
|
149
|
+
rb_str_backslash = rb_str_new_cstr("\\");
|
150
|
+
rb_ary_store(ary, 2, rb_str_backslash);
|
151
|
+
rb_str_dot = rb_str_new_cstr(".");
|
152
|
+
rb_ary_store(ary, 3, rb_str_dot);
|
153
|
+
|
154
|
+
cField = rb_define_class_under(mLibBin, "Field", rb_cObject);
|
155
|
+
rb_define_alloc_func(cField, cField_alloc);
|
156
|
+
rb_const_set(cField, rb_intern("STRINGS"), ary);
|
157
|
+
rb_define_method(cField, "initialize", cField_initialize, 8);
|
158
|
+
rb_define_method(cField, "name", cField_name, 0);
|
159
|
+
rb_define_method(cField, "type", cField_get_type, 0);
|
160
|
+
rb_define_method(cField, "length", cField_length, 0);
|
161
|
+
rb_define_method(cField, "count", cField_count, 0);
|
162
|
+
rb_define_method(cField, "offset", cField_offset, 0);
|
163
|
+
rb_define_method(cField, "sequence", cField_sequence, 0);
|
164
|
+
rb_define_method(cField, "sequence?", cField_sequence, 0);
|
165
|
+
rb_define_method(cField, "condition", cField_condition, 0);
|
166
|
+
rb_define_method(cField, "relative_offset?", cField_relative_offset, 0);
|
167
|
+
}
|
168
|
+
|
169
|
+
struct cDataConverter_data {
|
170
|
+
VALUE __input;
|
171
|
+
VALUE __output;
|
172
|
+
VALUE __input_big;
|
173
|
+
VALUE __output_big;
|
174
|
+
VALUE __parent;
|
175
|
+
VALUE __index;
|
176
|
+
VALUE __position;
|
177
|
+
VALUE __cur_position;
|
178
|
+
// field specific data
|
179
|
+
VALUE __offset;
|
180
|
+
VALUE __condition;
|
181
|
+
VALUE __type;
|
182
|
+
VALUE __length;
|
183
|
+
VALUE __count;
|
184
|
+
VALUE __iterator;
|
185
|
+
};
|
186
|
+
|
187
|
+
static void cDataConverter_mark(void* data) {
|
188
|
+
void *start = data;
|
189
|
+
void *end = (char *)data + sizeof(struct cDataConverter_data);
|
190
|
+
rb_gc_mark_locations((VALUE *)start, (VALUE *)end);
|
191
|
+
}
|
192
|
+
|
193
|
+
static size_t cDataConverter_size(const void* data) {
|
194
|
+
(void)data;
|
195
|
+
return sizeof(struct cDataConverter_data);
|
196
|
+
}
|
197
|
+
|
198
|
+
static const rb_data_type_t cDataConverter_type = {
|
199
|
+
.wrap_struct_name = "cDataConverter_data",
|
200
|
+
.function = {
|
201
|
+
.dmark = cDataConverter_mark,
|
202
|
+
.dfree = RUBY_DEFAULT_FREE,
|
203
|
+
.dsize = cDataConverter_size,
|
204
|
+
},
|
205
|
+
.data = NULL,
|
206
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
207
|
+
};
|
208
|
+
|
209
|
+
static VALUE cDataConverter_alloc(VALUE self) {
|
210
|
+
struct cDataConverter_data *data;
|
211
|
+
VALUE res = TypedData_Make_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
212
|
+
return res;
|
213
|
+
}
|
214
|
+
|
215
|
+
static VALUE cDataConverter_initialize(VALUE self) {
|
216
|
+
struct cDataConverter_data *data;
|
217
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
218
|
+
data->__input = Qnil;
|
219
|
+
data->__output = Qnil;
|
220
|
+
data->__input_big = Qnil;
|
221
|
+
data->__output_big = Qnil;
|
222
|
+
data->__parent = Qnil;
|
223
|
+
data->__index = Qnil;
|
224
|
+
data->__position = Qnil;
|
225
|
+
data->__cur_position = Qnil;
|
226
|
+
data->__offset = Qnil;
|
227
|
+
data->__condition = Qnil;
|
228
|
+
data->__type = Qnil;
|
229
|
+
data->__length = Qnil;
|
230
|
+
data->__count = Qnil;
|
231
|
+
data->__iterator = Qnil;
|
232
|
+
return self;
|
233
|
+
}
|
234
|
+
|
235
|
+
/* attr_reader :__parent
|
236
|
+
attr_reader :__index
|
237
|
+
attr_reader :__iterator
|
238
|
+
attr_reader :__position */
|
239
|
+
|
240
|
+
static VALUE cDataConverter_parent(VALUE self) {
|
241
|
+
struct cDataConverter_data *data;
|
242
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
243
|
+
return data->__parent;
|
244
|
+
}
|
245
|
+
|
246
|
+
static VALUE cDataConverter_index(VALUE self) {
|
247
|
+
struct cDataConverter_data *data;
|
248
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
249
|
+
return data->__index;
|
250
|
+
}
|
251
|
+
|
252
|
+
static VALUE cDataConverter_iterator(VALUE self) {
|
253
|
+
struct cDataConverter_data *data;
|
254
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
255
|
+
return data->__iterator;
|
256
|
+
}
|
257
|
+
|
258
|
+
static VALUE cDataConverter_position(VALUE self) {
|
259
|
+
struct cDataConverter_data *data;
|
260
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
261
|
+
return data->__position;
|
262
|
+
}
|
263
|
+
|
264
|
+
/* attr_reader :__input
|
265
|
+
attr_reader :__output
|
266
|
+
attr_reader :__input_big
|
267
|
+
attr_reader :__output_big */
|
268
|
+
|
269
|
+
static VALUE cDataConverter_input(VALUE self) {
|
270
|
+
struct cDataConverter_data *data;
|
271
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
272
|
+
return data->__input;
|
273
|
+
}
|
274
|
+
|
275
|
+
static VALUE cDataConverter_output(VALUE self) {
|
276
|
+
struct cDataConverter_data *data;
|
277
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
278
|
+
return data->__output;
|
279
|
+
}
|
280
|
+
|
281
|
+
static VALUE cDataConverter_input_big(VALUE self) {
|
282
|
+
struct cDataConverter_data *data;
|
283
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
284
|
+
return data->__input_big;
|
285
|
+
}
|
286
|
+
|
287
|
+
static VALUE cDataConverter_output_big(VALUE self) {
|
288
|
+
struct cDataConverter_data *data;
|
289
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
290
|
+
return data->__output_big;
|
291
|
+
}
|
292
|
+
|
293
|
+
ID id_tell;
|
294
|
+
|
295
|
+
/* def __set_convert_type(input, output, input_big, output_big, parent, index)
|
296
|
+
@__input_big = input_big
|
297
|
+
@__output_big = output_big
|
298
|
+
@__input = input
|
299
|
+
@__output = output
|
300
|
+
@__parent = parent
|
301
|
+
@__index = index
|
302
|
+
@__position = input.tell
|
303
|
+
@__cur_position = @__position
|
304
|
+
end */
|
305
|
+
|
306
|
+
static inline VALUE cDataConverter_set_convert_type(
|
307
|
+
VALUE self,
|
308
|
+
VALUE input,
|
309
|
+
VALUE output,
|
310
|
+
VALUE input_big,
|
311
|
+
VALUE output_big,
|
312
|
+
VALUE parent,
|
313
|
+
VALUE index)
|
314
|
+
{
|
315
|
+
struct cDataConverter_data *data;
|
316
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
317
|
+
data->__input = input;
|
318
|
+
data->__output = output;
|
319
|
+
data->__input_big = input_big;
|
320
|
+
data->__output_big = output_big;
|
321
|
+
data->__parent = parent;
|
322
|
+
data->__index = index;
|
323
|
+
data->__position = rb_funcall(input, id_tell, 0);
|
324
|
+
data->__cur_position = data->__position;
|
325
|
+
return Qnil;
|
326
|
+
}
|
327
|
+
|
328
|
+
/* def __unset_convert_type
|
329
|
+
@__input_big = nil
|
330
|
+
@__output_big = nil
|
331
|
+
@__input = nil
|
332
|
+
@__output = nil
|
333
|
+
@__parent = nil
|
334
|
+
@__index = nil
|
335
|
+
@__position = nil
|
336
|
+
@__cur_position = nil
|
337
|
+
end */
|
338
|
+
|
339
|
+
static inline VALUE cDataConverter_unset_convert_type(VALUE self) {
|
340
|
+
struct cDataConverter_data *data;
|
341
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
342
|
+
data->__input = Qnil;
|
343
|
+
data->__output = Qnil;
|
344
|
+
data->__input_big = Qnil;
|
345
|
+
data->__output_big = Qnil;
|
346
|
+
data->__parent = Qnil;
|
347
|
+
data->__index = Qnil;
|
348
|
+
data->__position = Qnil;
|
349
|
+
data->__cur_position = Qnil;
|
350
|
+
return Qnil;
|
351
|
+
}
|
352
|
+
|
353
|
+
/* def __set_size_type(position, parent, index)
|
354
|
+
@__parent = parent
|
355
|
+
@__index = index
|
356
|
+
@__position = position
|
357
|
+
@__cur_position = @__position
|
358
|
+
end */
|
359
|
+
|
360
|
+
static inline VALUE cDataConverter_set_size_type(
|
361
|
+
VALUE self,
|
362
|
+
VALUE position,
|
363
|
+
VALUE parent,
|
364
|
+
VALUE index)
|
365
|
+
{
|
366
|
+
struct cDataConverter_data *data;
|
367
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
368
|
+
data->__parent = parent;
|
369
|
+
data->__index = index;
|
370
|
+
data->__position = position;
|
371
|
+
data->__cur_position = data->__position;
|
372
|
+
return Qnil;
|
373
|
+
}
|
374
|
+
|
375
|
+
/* def __unset_size_type
|
376
|
+
@__parent = nil
|
377
|
+
@__index = nil
|
378
|
+
@__position = nil
|
379
|
+
@__cur_position = nil
|
380
|
+
end */
|
381
|
+
|
382
|
+
static inline VALUE cDataConverter_unset_size_type(VALUE self) {
|
383
|
+
struct cDataConverter_data *data;
|
384
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
385
|
+
data->__parent = Qnil;
|
386
|
+
data->__index = Qnil;
|
387
|
+
data->__position = Qnil;
|
388
|
+
data->__cur_position = Qnil;
|
389
|
+
return Qnil;
|
390
|
+
}
|
391
|
+
|
392
|
+
/* def __set_load_type(input, input_big, parent, index)
|
393
|
+
@__input_big = input_big
|
394
|
+
@__input = input
|
395
|
+
@__parent = parent
|
396
|
+
@__index = index
|
397
|
+
@__position = input.tell
|
398
|
+
@__cur_position = @__position
|
399
|
+
end */
|
400
|
+
|
401
|
+
static inline VALUE cDataConverter_set_load_type(
|
402
|
+
VALUE self,
|
403
|
+
VALUE input,
|
404
|
+
VALUE input_big,
|
405
|
+
VALUE parent,
|
406
|
+
VALUE index)
|
407
|
+
{
|
408
|
+
struct cDataConverter_data *data;
|
409
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
410
|
+
data->__input = input;
|
411
|
+
data->__input_big = input_big;
|
412
|
+
data->__parent = parent;
|
413
|
+
data->__index = index;
|
414
|
+
data->__position = rb_funcall(input, id_tell, 0);
|
415
|
+
data->__cur_position = data->__position;
|
416
|
+
return Qnil;
|
417
|
+
}
|
418
|
+
|
419
|
+
/* def __unset_load_type
|
420
|
+
@__input_big = nil
|
421
|
+
@__input = nil
|
422
|
+
@__parent = nil
|
423
|
+
@__index = nil
|
424
|
+
@__position = nil
|
425
|
+
@__cur_position = nil
|
426
|
+
end */
|
427
|
+
|
428
|
+
static inline VALUE cDataConverter_unset_load_type(VALUE self) {
|
429
|
+
struct cDataConverter_data *data;
|
430
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
431
|
+
data->__input = Qnil;
|
432
|
+
data->__input_big = Qnil;
|
433
|
+
data->__parent = Qnil;
|
434
|
+
data->__index = Qnil;
|
435
|
+
data->__position = Qnil;
|
436
|
+
data->__cur_position = Qnil;
|
437
|
+
return Qnil;
|
438
|
+
}
|
439
|
+
|
440
|
+
/* def __set_dump_type(output, output_big, parent, index)
|
441
|
+
@__output_big = output_big
|
442
|
+
@__output = output
|
443
|
+
@__parent = parent
|
444
|
+
@__index = index
|
445
|
+
@__position = output.tell
|
446
|
+
@__cur_position = @__position
|
447
|
+
end */
|
448
|
+
|
449
|
+
static inline VALUE cDataConverter_set_dump_type(
|
450
|
+
VALUE self,
|
451
|
+
VALUE output,
|
452
|
+
VALUE output_big,
|
453
|
+
VALUE parent,
|
454
|
+
VALUE index)
|
455
|
+
{
|
456
|
+
struct cDataConverter_data *data;
|
457
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
458
|
+
data->__output = output;
|
459
|
+
data->__output_big = output_big;
|
460
|
+
data->__parent = parent;
|
461
|
+
data->__index = index;
|
462
|
+
data->__position = rb_funcall(output, id_tell, 0);
|
463
|
+
data->__cur_position = data->__position;
|
464
|
+
return Qnil;
|
465
|
+
}
|
466
|
+
|
467
|
+
/* def __unset_dump_type
|
468
|
+
@__output_big = nil
|
469
|
+
@__output = nil
|
470
|
+
@__parent = nil
|
471
|
+
@__index = nil
|
472
|
+
@__position = nil
|
473
|
+
@__cur_position = nil
|
474
|
+
end */
|
475
|
+
|
476
|
+
static inline VALUE cDataConverter_unset_dump_type(VALUE self) {
|
477
|
+
struct cDataConverter_data *data;
|
478
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
479
|
+
data->__output = Qnil;
|
480
|
+
data->__output_big = Qnil;
|
481
|
+
data->__parent = Qnil;
|
482
|
+
data->__index = Qnil;
|
483
|
+
data->__position = Qnil;
|
484
|
+
data->__cur_position = Qnil;
|
485
|
+
return Qnil;
|
486
|
+
}
|
487
|
+
|
488
|
+
/* def __decode_expression(sym)
|
489
|
+
case sym
|
490
|
+
when Proc
|
491
|
+
return sym.call
|
492
|
+
else
|
493
|
+
return sym
|
494
|
+
end
|
495
|
+
end */
|
496
|
+
|
497
|
+
static ID id_instance_exec;
|
498
|
+
|
499
|
+
static inline VALUE cDataConverter_decode_expression(VALUE self, VALUE expression) {
|
500
|
+
if (rb_obj_is_proc(expression))
|
501
|
+
return rb_funcall_with_block(self, id_instance_exec, 0, NULL, expression);
|
502
|
+
else
|
503
|
+
return expression;
|
504
|
+
}
|
505
|
+
|
506
|
+
/* def __decode_seek_offset(offset, relative_offset)
|
507
|
+
return nil unless offset
|
508
|
+
offset = __decode_expression(offset)
|
509
|
+
return false if offset == 0x0
|
510
|
+
offset += @__position if relative_offset
|
511
|
+
@__cur_position = offset
|
512
|
+
@__input.seek(offset) if @__input
|
513
|
+
@__output.seek(offset) if @__output
|
514
|
+
offset
|
515
|
+
end */
|
516
|
+
|
517
|
+
ID id_seek;
|
518
|
+
|
519
|
+
static inline VALUE cDataConverter_decode_seek_offset(VALUE self, VALUE offset, VALUE relative_offset) {
|
520
|
+
struct cDataConverter_data *data;
|
521
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
522
|
+
if (!RTEST(offset))
|
523
|
+
return Qnil;
|
524
|
+
ptrdiff_t off = NUM2LL(cDataConverter_decode_expression(self, offset));
|
525
|
+
if (off == 0)
|
526
|
+
return Qfalse;
|
527
|
+
if (RTEST(relative_offset))
|
528
|
+
off += NUM2LL(data->__position);
|
529
|
+
data->__cur_position = LL2NUM(off);
|
530
|
+
if (RTEST(data->__input))
|
531
|
+
rb_funcall(data->__input, id_seek, 1, data->__cur_position);
|
532
|
+
if (RTEST(data->__output))
|
533
|
+
rb_funcall(data->__output, id_seek, 1, data->__cur_position);
|
534
|
+
return data->__cur_position;
|
535
|
+
}
|
536
|
+
|
537
|
+
/* def __decode_condition(condition)
|
538
|
+
return true unless condition
|
539
|
+
__decode_expression(condition)
|
540
|
+
end */
|
541
|
+
|
542
|
+
static inline VALUE cDataConverter_decode_condition(VALUE self, VALUE condition) {
|
543
|
+
if (!RTEST(condition))
|
544
|
+
return Qtrue;
|
545
|
+
return cDataConverter_decode_expression(self, condition);
|
546
|
+
}
|
547
|
+
|
548
|
+
/* def __decode_count(count)
|
549
|
+
return 1 unless count
|
550
|
+
__decode_expression(count)
|
551
|
+
end */
|
552
|
+
|
553
|
+
static inline VALUE cDataConverter_decode_count(VALUE self, VALUE count) {
|
554
|
+
if (!RTEST(count))
|
555
|
+
return INT2FIX(1);
|
556
|
+
return cDataConverter_decode_expression(self, count);
|
557
|
+
}
|
558
|
+
|
559
|
+
/* def __decode_type(type)
|
560
|
+
__decode_expression(type)
|
561
|
+
end */
|
562
|
+
|
563
|
+
static inline VALUE cDataConverter_decode_type(VALUE self, VALUE type) {
|
564
|
+
return cDataConverter_decode_expression(self, type);
|
565
|
+
}
|
566
|
+
|
567
|
+
/* def __decode_length(length)
|
568
|
+
__decode_expression(length)
|
569
|
+
end */
|
570
|
+
|
571
|
+
static inline VALUE cDataConverter_decode_length(VALUE self, VALUE length) {
|
572
|
+
if (NIL_P(length))
|
573
|
+
return Qnil;
|
574
|
+
return cDataConverter_decode_expression(self, length);
|
575
|
+
}
|
576
|
+
|
577
|
+
/* def __decode_static_conditions(field)
|
578
|
+
@__offset = nil
|
579
|
+
@__condition = nil
|
580
|
+
@__type = nil
|
581
|
+
@__length = nil
|
582
|
+
@__count = nil
|
583
|
+
unless field.sequence?
|
584
|
+
@__offset = __decode_seek_offset(field.offset, field.relative_offset?)
|
585
|
+
throw :ignored, nil if @__offset == false
|
586
|
+
@__condition = __decode_condition(field.condition)
|
587
|
+
throw :ignored, nil unless @__condition
|
588
|
+
@__type = __decode_type(field.type)
|
589
|
+
@__length = __decode_length(field.length)
|
590
|
+
end
|
591
|
+
@__count = __decode_count(field.count)
|
592
|
+
end */
|
593
|
+
|
594
|
+
static inline VALUE cDataConverter_decode_static_conditions(VALUE self, VALUE field) {
|
595
|
+
struct cDataConverter_data *data;
|
596
|
+
struct cField_data *field_data;
|
597
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
598
|
+
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
599
|
+
data->__offset = Qnil;
|
600
|
+
data->__condition = Qnil;
|
601
|
+
data->__type = Qnil;
|
602
|
+
data->__length = Qnil;
|
603
|
+
data->__count = Qnil;
|
604
|
+
if (!RTEST(field_data->sequence)) {
|
605
|
+
data->__offset = cDataConverter_decode_seek_offset(self, field_data->offset, field_data->relative_offset);
|
606
|
+
if (!data->__offset)
|
607
|
+
return Qnil;
|
608
|
+
data->__condition = cDataConverter_decode_condition(self, field_data->condition);
|
609
|
+
if (!RTEST(data->__condition))
|
610
|
+
return Qnil;
|
611
|
+
data->__type = cDataConverter_decode_type(self, field_data->type);
|
612
|
+
data->__length = cDataConverter_decode_length(self, field_data->length);
|
613
|
+
}
|
614
|
+
data->__count = cDataConverter_decode_count(self, field_data->count);
|
615
|
+
return Qtrue;
|
616
|
+
}
|
617
|
+
|
618
|
+
/* def __decode_dynamic_conditions(field)
|
619
|
+
return true unless field.sequence?
|
620
|
+
@__offset = nil
|
621
|
+
@__condition = nil
|
622
|
+
@__type = nil
|
623
|
+
@__length = nil
|
624
|
+
@__offset = __decode_seek_offset(field.offset, field.relative_offset?)
|
625
|
+
return false if @__offset == false
|
626
|
+
@__condition = __decode_condition(field.condition)
|
627
|
+
return false unless @__condition
|
628
|
+
@__type = __decode_type(field.type)
|
629
|
+
@__length = __decode_length(field.length)
|
630
|
+
return true
|
631
|
+
end */
|
632
|
+
|
633
|
+
static inline VALUE cDataConverter_decode_dynamic_conditions(VALUE self, VALUE field) {
|
634
|
+
struct cDataConverter_data *data;
|
635
|
+
struct cField_data *field_data;
|
636
|
+
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
637
|
+
if (!RTEST(field_data->sequence))
|
638
|
+
return Qtrue;
|
639
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
640
|
+
data->__offset = Qnil;
|
641
|
+
data->__condition = Qnil;
|
642
|
+
data->__type = Qnil;
|
643
|
+
data->__length = Qnil;
|
644
|
+
data->__offset = cDataConverter_decode_seek_offset(self, field_data->offset, field_data->relative_offset);
|
645
|
+
if (!data->__offset)
|
646
|
+
return Qfalse;
|
647
|
+
data->__condition = cDataConverter_decode_condition(self, field_data->condition);
|
648
|
+
if (!RTEST(data->__condition))
|
649
|
+
return Qfalse;
|
650
|
+
data->__type = cDataConverter_decode_type(self, field_data->type);
|
651
|
+
data->__length = cDataConverter_decode_length(self, field_data->length);
|
652
|
+
return Qtrue;
|
653
|
+
}
|
654
|
+
|
655
|
+
/* def __restore_context
|
656
|
+
@__iterator = nil
|
657
|
+
@__type = nil
|
658
|
+
@__length = nil
|
659
|
+
@__count = nil
|
660
|
+
@__offset = nil
|
661
|
+
@__condition = nil
|
662
|
+
end */
|
663
|
+
|
664
|
+
static inline VALUE cDataConverter_restore_context(VALUE self) {
|
665
|
+
struct cDataConverter_data *data;
|
666
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
667
|
+
data->__iterator = Qnil;
|
668
|
+
data->__type = Qnil;
|
669
|
+
data->__length = Qnil;
|
670
|
+
data->__count = Qnil;
|
671
|
+
data->__offset = Qnil;
|
672
|
+
data->__condition = Qnil;
|
673
|
+
return Qnil;
|
674
|
+
}
|
675
|
+
|
676
|
+
/* def __convert_field(field)
|
677
|
+
__decode_static_conditions(field)
|
678
|
+
vs = @__count.times.collect do |it|
|
679
|
+
@__iterator = it
|
680
|
+
if __decode_dynamic_conditions(field)
|
681
|
+
@__type::convert(@__input, @__output, @__input_big, @__output_big, self, it, @__length)
|
682
|
+
else
|
683
|
+
nil
|
684
|
+
end
|
685
|
+
end
|
686
|
+
__restore_context
|
687
|
+
vs = vs.first unless field.count
|
688
|
+
vs
|
689
|
+
end */
|
690
|
+
|
691
|
+
static ID id_convert;
|
692
|
+
|
693
|
+
static inline VALUE cDataConverter_convert_field(VALUE self, VALUE field) {
|
694
|
+
VALUE res;
|
695
|
+
struct cDataConverter_data *data;
|
696
|
+
struct cField_data *field_data;
|
697
|
+
if (NIL_P(cDataConverter_decode_static_conditions(self, field)))
|
698
|
+
return Qnil;
|
699
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
700
|
+
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
701
|
+
|
702
|
+
if (RTEST(field_data->count)) {
|
703
|
+
long count = NUM2LONG(data->__count);
|
704
|
+
res = rb_ary_new_capa(count);
|
705
|
+
|
706
|
+
for (long i = 0; i < count; i++) {
|
707
|
+
data->__iterator = LONG2NUM(i);
|
708
|
+
if (RTEST(cDataConverter_decode_dynamic_conditions(self, field)))
|
709
|
+
rb_ary_store(res, i, rb_funcall(data->__type, id_convert, 7,
|
710
|
+
data->__input,
|
711
|
+
data->__output,
|
712
|
+
data->__input_big,
|
713
|
+
data->__output_big,
|
714
|
+
self,
|
715
|
+
data->__iterator,
|
716
|
+
data->__length));
|
717
|
+
else
|
718
|
+
rb_ary_store(res, i, Qnil);
|
719
|
+
}
|
720
|
+
} else {
|
721
|
+
data->__iterator = INT2FIX(0);
|
722
|
+
if (RTEST(cDataConverter_decode_dynamic_conditions(self, field)))
|
723
|
+
res = rb_funcall(data->__type, id_convert, 7,
|
724
|
+
data->__input,
|
725
|
+
data->__output,
|
726
|
+
data->__input_big,
|
727
|
+
data->__output_big,
|
728
|
+
self,
|
729
|
+
data->__iterator,
|
730
|
+
data->__length);
|
731
|
+
else
|
732
|
+
res = Qnil;
|
733
|
+
}
|
734
|
+
|
735
|
+
cDataConverter_restore_context(self);
|
736
|
+
return res;
|
737
|
+
}
|
738
|
+
|
739
|
+
/* def __load_field(field)
|
740
|
+
__decode_static_conditions(field)
|
741
|
+
vs = @__count.times.collect do |it|
|
742
|
+
@__iterator = it
|
743
|
+
if __decode_dynamic_conditions(field)
|
744
|
+
@__type::load(@__input, @__input_big, self, it, @__length)
|
745
|
+
else
|
746
|
+
nil
|
747
|
+
end
|
748
|
+
end
|
749
|
+
__restore_context
|
750
|
+
vs = vs.first unless field.count
|
751
|
+
vs
|
752
|
+
end */
|
753
|
+
|
754
|
+
static ID id_load;
|
755
|
+
|
756
|
+
static inline VALUE cDataConverter_load_field(VALUE self, VALUE field) {
|
757
|
+
VALUE res;
|
758
|
+
struct cDataConverter_data *data;
|
759
|
+
struct cField_data *field_data;
|
760
|
+
if (NIL_P(cDataConverter_decode_static_conditions(self, field)))
|
761
|
+
return Qnil;
|
762
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
763
|
+
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
764
|
+
|
765
|
+
if (RTEST(field_data->count)) {
|
766
|
+
long count = NUM2LONG(data->__count);
|
767
|
+
res = rb_ary_new_capa(count);
|
768
|
+
|
769
|
+
for (long i = 0; i < count; i++) {
|
770
|
+
data->__iterator = LONG2NUM(i);
|
771
|
+
if (RTEST(cDataConverter_decode_dynamic_conditions(self, field)))
|
772
|
+
rb_ary_store(res, i, rb_funcall(data->__type, id_load, 5,
|
773
|
+
data->__input,
|
774
|
+
data->__input_big,
|
775
|
+
self,
|
776
|
+
data->__iterator,
|
777
|
+
data->__length));
|
778
|
+
else
|
779
|
+
rb_ary_store(res, i, Qnil);
|
780
|
+
}
|
781
|
+
} else {
|
782
|
+
data->__iterator = INT2FIX(0);
|
783
|
+
if (RTEST(cDataConverter_decode_dynamic_conditions(self, field)))
|
784
|
+
res = rb_funcall(data->__type, id_load, 5,
|
785
|
+
data->__input,
|
786
|
+
data->__input_big,
|
787
|
+
self,
|
788
|
+
data->__iterator,
|
789
|
+
data->__length);
|
790
|
+
else
|
791
|
+
res = Qnil;
|
792
|
+
}
|
793
|
+
cDataConverter_restore_context(self);
|
794
|
+
return res;
|
795
|
+
}
|
796
|
+
|
797
|
+
/* def __dump_field(vs, field)
|
798
|
+
__decode_static_conditions(field)
|
799
|
+
vs = [vs] unless field.count
|
800
|
+
vs.each_with_index do |v, it|
|
801
|
+
@__iterator = it
|
802
|
+
if __decode_dynamic_conditions(field)
|
803
|
+
@__type::dump(v, @__output, @__output_big, self, it, @__length)
|
804
|
+
end
|
805
|
+
end
|
806
|
+
__restore_context
|
807
|
+
end */
|
808
|
+
|
809
|
+
static ID id_dump;
|
810
|
+
|
811
|
+
static inline VALUE cDataConverter_dump_field(VALUE self, VALUE values, VALUE field) {
|
812
|
+
struct cDataConverter_data *data;
|
813
|
+
struct cField_data *field_data;
|
814
|
+
if (NIL_P(cDataConverter_decode_static_conditions(self, field)))
|
815
|
+
return Qnil;
|
816
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
817
|
+
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
818
|
+
|
819
|
+
if (RTEST(field_data->count)) {
|
820
|
+
long count = RARRAY_LEN(values);
|
821
|
+
|
822
|
+
for (long i = 0; i < count; i++) {
|
823
|
+
data->__iterator = LONG2NUM(i);
|
824
|
+
if (RTEST(cDataConverter_decode_dynamic_conditions(self, field)))
|
825
|
+
rb_funcall(data->__type, id_dump, 6,
|
826
|
+
rb_ary_entry(values, i),
|
827
|
+
data->__output,
|
828
|
+
data->__output_big,
|
829
|
+
self,
|
830
|
+
data->__iterator,
|
831
|
+
data->__length);
|
832
|
+
}
|
833
|
+
} else {
|
834
|
+
data->__iterator = INT2FIX(0);
|
835
|
+
if (RTEST(cDataConverter_decode_dynamic_conditions(self, field)))
|
836
|
+
rb_funcall(data->__type, id_dump, 6,
|
837
|
+
values,
|
838
|
+
data->__output,
|
839
|
+
data->__output_big,
|
840
|
+
self,
|
841
|
+
data->__iterator,
|
842
|
+
data->__length);
|
843
|
+
}
|
844
|
+
cDataConverter_restore_context(self);
|
845
|
+
return Qnil;
|
846
|
+
}
|
847
|
+
|
848
|
+
/* def __shape_field(vs, kind, field)
|
849
|
+
__decode_static_conditions(field)
|
850
|
+
vs = [vs] unless field.count
|
851
|
+
vs = vs.each_with_index.collect do |v, it|
|
852
|
+
@__iterator = it
|
853
|
+
if __decode_dynamic_conditions(field)
|
854
|
+
sh = @__type::shape(v, @__cur_position, self, it, kind, @__length)
|
855
|
+
@__cur_position = sh.last + 1 if sh.last && sh.last >= 0
|
856
|
+
sh
|
857
|
+
end
|
858
|
+
end
|
859
|
+
__restore_context
|
860
|
+
vs = field.count ? kind.new(vs) : vs.first
|
861
|
+
vs
|
862
|
+
end */
|
863
|
+
|
864
|
+
static ID id_shape;
|
865
|
+
|
866
|
+
static inline VALUE cDataConverter_shape_field(
|
867
|
+
VALUE self,
|
868
|
+
VALUE values,
|
869
|
+
VALUE kind,
|
870
|
+
VALUE field)
|
871
|
+
{
|
872
|
+
VALUE res = Qnil;
|
873
|
+
struct cDataConverter_data *data;
|
874
|
+
struct cField_data *field_data;
|
875
|
+
if (NIL_P(cDataConverter_decode_static_conditions(self, field)))
|
876
|
+
return Qnil;
|
877
|
+
TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
|
878
|
+
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
879
|
+
|
880
|
+
if (RTEST(field_data->count)) {
|
881
|
+
long count = RARRAY_LEN(values);
|
882
|
+
res = rb_ary_new_capa(count);
|
883
|
+
|
884
|
+
for (long i = 0; i < count; i++) {
|
885
|
+
data->__iterator = LONG2NUM(i);
|
886
|
+
if (RTEST(cDataConverter_decode_dynamic_conditions(self, field))) {
|
887
|
+
VALUE shape = rb_funcall(data->__type, id_shape, 6,
|
888
|
+
rb_ary_entry(values, i),
|
889
|
+
data->__cur_position,
|
890
|
+
self,
|
891
|
+
data->__iterator,
|
892
|
+
kind,
|
893
|
+
data->__length);
|
894
|
+
rb_ary_store(res, i, shape);
|
895
|
+
VALUE last = rb_funcall(shape, rb_intern("last"), 0);
|
896
|
+
if (RTEST(last)) {
|
897
|
+
ptrdiff_t pos = NUM2LL(last);
|
898
|
+
if (pos >= 0)
|
899
|
+
data->__cur_position = LL2NUM(pos + 1);
|
900
|
+
}
|
901
|
+
}
|
902
|
+
}
|
903
|
+
res = rb_class_new_instance(1, &res, kind);
|
904
|
+
} else {
|
905
|
+
data->__iterator = INT2FIX(0);
|
906
|
+
if (RTEST(cDataConverter_decode_dynamic_conditions(self, field))) {
|
907
|
+
res = rb_funcall(data->__type, id_shape, 6,
|
908
|
+
values,
|
909
|
+
data->__cur_position,
|
910
|
+
self,
|
911
|
+
data->__iterator,
|
912
|
+
kind,
|
913
|
+
data->__length);
|
914
|
+
VALUE last = rb_funcall(res, rb_intern("last"), 0);
|
915
|
+
if (RTEST(last)) {
|
916
|
+
ptrdiff_t pos = NUM2LL(last);
|
917
|
+
if (pos >= 0)
|
918
|
+
data->__cur_position = LL2NUM(pos + 1);
|
919
|
+
}
|
920
|
+
}
|
921
|
+
}
|
922
|
+
cDataConverter_restore_context(self);
|
923
|
+
return res;
|
924
|
+
}
|
925
|
+
|
926
|
+
/* def __load_fields
|
927
|
+
self.class.instance_variable_get(:@fields).each { |field|
|
928
|
+
begin
|
929
|
+
send("#{field.name}=", __load_field(field))
|
930
|
+
rescue
|
931
|
+
STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
|
932
|
+
raise
|
933
|
+
end
|
934
|
+
}
|
935
|
+
self
|
936
|
+
end */
|
937
|
+
|
938
|
+
static ID id_fields;
|
939
|
+
|
940
|
+
struct fields_state {
|
941
|
+
VALUE self;
|
942
|
+
VALUE fields;
|
943
|
+
VALUE field;
|
944
|
+
};
|
945
|
+
|
946
|
+
static inline VALUE cDataConverter_fields_rescue(VALUE state_p, VALUE exception) {
|
947
|
+
struct fields_state *state = (struct fields_state *)state_p;
|
948
|
+
if (NIL_P(state->field)) {
|
949
|
+
struct cDataConverter_data *data;
|
950
|
+
TypedData_Get_Struct(state->self, struct cDataConverter_data, &cDataConverter_type, data);
|
951
|
+
if (!NIL_P(rb_ivar_get(mLibBin, rb_intern("@__output"))))
|
952
|
+
rb_funcall(rb_ivar_get(mLibBin, rb_intern("@__output")), rb_intern("print"), 6,
|
953
|
+
rb_obj_class(state->self),
|
954
|
+
rb_str_new_cstr(": could not load fields, index: "),
|
955
|
+
data->__index,
|
956
|
+
rb_str_new_cstr(", current position: "),
|
957
|
+
data->__cur_position,
|
958
|
+
rb_str_new_cstr("\n"));
|
959
|
+
} else {
|
960
|
+
struct cField_data *field_data;
|
961
|
+
TypedData_Get_Struct(state->field, struct cField_data, &cField_type, field_data);
|
962
|
+
if (!NIL_P(rb_ivar_get(mLibBin, rb_intern("@__output"))))
|
963
|
+
rb_funcall(rb_ivar_get(mLibBin, rb_intern("@__output")), rb_intern("print"), 6,
|
964
|
+
rb_obj_class(state->self),
|
965
|
+
rb_str_new_cstr(": "),
|
966
|
+
field_data->name,
|
967
|
+
rb_str_new_cstr("("),
|
968
|
+
field_data->type,
|
969
|
+
rb_str_new_cstr(")\n"));
|
970
|
+
}
|
971
|
+
rb_exc_raise(exception);
|
972
|
+
return state->self;
|
973
|
+
}
|
974
|
+
|
975
|
+
static inline VALUE cDataConverter_load_fields_wrapper(VALUE state_p) {
|
976
|
+
struct fields_state *state = (struct fields_state *)state_p;
|
977
|
+
state->fields = rb_ivar_get(rb_obj_class(state->self), id_fields);
|
978
|
+
for (long i = 0; i < RARRAY_LEN(state->fields); i++) {
|
979
|
+
state->field = rb_ary_entry(state->fields, i);
|
980
|
+
struct cField_data *field_data;
|
981
|
+
TypedData_Get_Struct(state->field, struct cField_data, &cField_type, field_data);
|
982
|
+
rb_funcall(state->self, field_data->setter, 1, cDataConverter_load_field(state->self, state->field));
|
983
|
+
}
|
984
|
+
return state->self;
|
985
|
+
}
|
986
|
+
|
987
|
+
static ID id___load_fields;
|
988
|
+
|
989
|
+
static inline VALUE cDataConverter_load_fields(VALUE self) {
|
990
|
+
struct fields_state state = {self, Qnil, Qnil};
|
991
|
+
rb_rescue(&cDataConverter_load_fields_wrapper, (VALUE)&state,
|
992
|
+
&cDataConverter_fields_rescue, (VALUE)&state);
|
993
|
+
return self;
|
994
|
+
}
|
995
|
+
|
996
|
+
/* def __dump_fields
|
997
|
+
self.class.instance_variable_get(:@fields).each { |field|
|
998
|
+
begin
|
999
|
+
__dump_field(send(field.name), field)
|
1000
|
+
rescue
|
1001
|
+
STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
|
1002
|
+
raise
|
1003
|
+
end
|
1004
|
+
}
|
1005
|
+
self
|
1006
|
+
end */
|
1007
|
+
|
1008
|
+
static inline VALUE cDataConverter_dump_fields_wrapper(VALUE state_p) {
|
1009
|
+
struct fields_state *state = (struct fields_state *)state_p;
|
1010
|
+
state->fields = rb_ivar_get(rb_obj_class(state->self), id_fields);
|
1011
|
+
for (long i = 0; i < RARRAY_LEN(state->fields); i++) {
|
1012
|
+
state->field = rb_ary_entry(state->fields, i);
|
1013
|
+
struct cField_data *field_data;
|
1014
|
+
TypedData_Get_Struct(state->field, struct cField_data, &cField_type, field_data);
|
1015
|
+
cDataConverter_dump_field(state->self, rb_funcall(state->self, field_data->getter, 0), state->field);
|
1016
|
+
}
|
1017
|
+
return state->self;
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
static ID id___dump_fields;
|
1021
|
+
|
1022
|
+
static inline VALUE cDataConverter_dump_fields(VALUE self) {
|
1023
|
+
struct fields_state state = {self, Qnil, Qnil};
|
1024
|
+
rb_rescue(&cDataConverter_dump_fields_wrapper, (VALUE)&state,
|
1025
|
+
&cDataConverter_fields_rescue, (VALUE)&state);
|
1026
|
+
return self;
|
1027
|
+
}
|
1028
|
+
|
1029
|
+
/* def __convert_fields
|
1030
|
+
self.class.instance_variable_get(:@fields).each { |field|
|
1031
|
+
begin
|
1032
|
+
send("#{field.name}=", __convert_field(field))
|
1033
|
+
rescue
|
1034
|
+
STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
|
1035
|
+
raise
|
1036
|
+
end
|
1037
|
+
}
|
1038
|
+
self
|
1039
|
+
end */
|
1040
|
+
|
1041
|
+
static inline VALUE cDataConverter_convert_fields_wrapper(VALUE state_p) {
|
1042
|
+
struct fields_state *state = (struct fields_state *)state_p;
|
1043
|
+
state->fields = rb_ivar_get(rb_obj_class(state->self), id_fields);
|
1044
|
+
for (long i = 0; i < RARRAY_LEN(state->fields); i++) {
|
1045
|
+
state->field = rb_ary_entry(state->fields, i);
|
1046
|
+
struct cField_data *field_data;
|
1047
|
+
TypedData_Get_Struct(state->field, struct cField_data, &cField_type, field_data);
|
1048
|
+
rb_funcall(state->self, field_data->setter, 1, cDataConverter_convert_field(state->self, state->field));
|
1049
|
+
}
|
1050
|
+
return state->self;
|
1051
|
+
}
|
1052
|
+
|
1053
|
+
static ID id___convert_fields;
|
1054
|
+
|
1055
|
+
static inline VALUE cDataConverter_convert_fields(VALUE self) {
|
1056
|
+
struct fields_state state = {self, Qnil, Qnil};
|
1057
|
+
rb_rescue(&cDataConverter_convert_fields_wrapper, (VALUE)&state,
|
1058
|
+
&cDataConverter_fields_rescue, (VALUE)&state);
|
1059
|
+
return self;
|
1060
|
+
}
|
1061
|
+
|
1062
|
+
/* def __shape_fields
|
1063
|
+
members = {}
|
1064
|
+
self.class.instance_variable_get(:@fields).each { |field|
|
1065
|
+
begin
|
1066
|
+
members[field.name] = __shape_field(send(field.name), kind, field)
|
1067
|
+
rescue
|
1068
|
+
STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
|
1069
|
+
raise
|
1070
|
+
end
|
1071
|
+
}
|
1072
|
+
return members
|
1073
|
+
end */
|
1074
|
+
|
1075
|
+
struct shape_fields_state {
|
1076
|
+
VALUE self;
|
1077
|
+
VALUE fields;
|
1078
|
+
VALUE field;
|
1079
|
+
VALUE kind;
|
1080
|
+
};
|
1081
|
+
|
1082
|
+
static inline VALUE cDataConverter_shape_fields_wrapper(VALUE state_p) {
|
1083
|
+
struct shape_fields_state *state = (struct shape_fields_state *)state_p;
|
1084
|
+
state->fields = rb_ivar_get(rb_obj_class(state->self), id_fields);
|
1085
|
+
VALUE members = rb_hash_new();
|
1086
|
+
for (long i = 0; i < RARRAY_LEN(state->fields); i++) {
|
1087
|
+
state->field = rb_ary_entry(state->fields, i);
|
1088
|
+
struct cField_data *field_data;
|
1089
|
+
TypedData_Get_Struct(state->field, struct cField_data, &cField_type, field_data);
|
1090
|
+
rb_hash_aset(members, ID2SYM(field_data->getter), cDataConverter_shape_field(state->self, rb_funcall(state->self, field_data->getter, 0), state->kind, state->field));
|
1091
|
+
}
|
1092
|
+
return members;
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
static ID id___shape_fields;
|
1096
|
+
|
1097
|
+
static inline VALUE cDataConverter_shape_fields(VALUE self, VALUE kind) {
|
1098
|
+
struct shape_fields_state state = {self, Qnil, Qnil, kind};
|
1099
|
+
return rb_rescue(&cDataConverter_shape_fields_wrapper, (VALUE)&state,
|
1100
|
+
&cDataConverter_fields_rescue, (VALUE)&state);
|
1101
|
+
}
|
1102
|
+
|
1103
|
+
/* def __load(input, input_big, parent = nil, index = nil)
|
1104
|
+
__set_load_type(input, input_big, parent, index)
|
1105
|
+
__load_fields
|
1106
|
+
__unset_load_type
|
1107
|
+
self
|
1108
|
+
end */
|
1109
|
+
|
1110
|
+
static ID id___load;
|
1111
|
+
|
1112
|
+
static inline VALUE cDataConverter_load(int argc, VALUE *argv, VALUE self) {
|
1113
|
+
VALUE input;
|
1114
|
+
VALUE input_big;
|
1115
|
+
VALUE parent;
|
1116
|
+
VALUE index;
|
1117
|
+
rb_scan_args(argc, argv, "22", &input, &input_big, &parent, &index);
|
1118
|
+
cDataConverter_set_load_type(self, input, input_big, parent, index);
|
1119
|
+
rb_funcall(self, id___load_fields, 0);
|
1120
|
+
cDataConverter_unset_load_type(self);
|
1121
|
+
return self;
|
1122
|
+
}
|
1123
|
+
|
1124
|
+
/* def __dump(output, output_big, parent = nil, index = nil)
|
1125
|
+
__set_dump_type(output, output_big, parent, index)
|
1126
|
+
__dump_fields
|
1127
|
+
__unset_dump_type
|
1128
|
+
self
|
1129
|
+
end */
|
1130
|
+
|
1131
|
+
static ID id___dump;
|
1132
|
+
|
1133
|
+
static inline VALUE cDataConverter_dump(int argc, VALUE *argv, VALUE self) {
|
1134
|
+
VALUE output;
|
1135
|
+
VALUE output_big;
|
1136
|
+
VALUE parent;
|
1137
|
+
VALUE index;
|
1138
|
+
rb_scan_args(argc, argv, "22", &output, &output_big, &parent, &index);
|
1139
|
+
cDataConverter_set_dump_type(self, output, output_big, parent, index);
|
1140
|
+
rb_funcall(self, id___dump_fields, 0);
|
1141
|
+
cDataConverter_unset_dump_type(self);
|
1142
|
+
return self;
|
1143
|
+
}
|
1144
|
+
|
1145
|
+
/* def __convert(input, output, input_big, output_big, parent = nil, index = nil)
|
1146
|
+
__set_convert_type(input, output, input_big, output_big, parent, index)
|
1147
|
+
__convert_fields
|
1148
|
+
__unset_convert_type
|
1149
|
+
self
|
1150
|
+
end */
|
1151
|
+
|
1152
|
+
static ID id___convert;
|
1153
|
+
|
1154
|
+
static inline VALUE cDataConverter_convert(int argc, VALUE *argv, VALUE self) {
|
1155
|
+
VALUE input;
|
1156
|
+
VALUE output;
|
1157
|
+
VALUE input_big;
|
1158
|
+
VALUE output_big;
|
1159
|
+
VALUE parent;
|
1160
|
+
VALUE index;
|
1161
|
+
rb_scan_args(argc, argv, "42", &input, &output, &input_big, &output_big, &parent, &index);
|
1162
|
+
cDataConverter_set_convert_type(self, input, output, input_big, output_big, parent, index);
|
1163
|
+
rb_funcall(self, id___convert_fields, 0);
|
1164
|
+
cDataConverter_unset_convert_type(self);
|
1165
|
+
return self;
|
1166
|
+
}
|
1167
|
+
|
1168
|
+
/* def __shape(previous_offset = 0, parent = nil, index = nil, kind = DataShape)
|
1169
|
+
__set_size_type(previous_offset, parent, index)
|
1170
|
+
members = __shape_fields(kind)
|
1171
|
+
__unset_size_type
|
1172
|
+
return nil if members.values.compact.size <= 0
|
1173
|
+
kind::new(members)
|
1174
|
+
end */
|
1175
|
+
|
1176
|
+
static ID id___shape;
|
1177
|
+
|
1178
|
+
static inline VALUE cDataConverter_shape(int argc, VALUE *argv, VALUE self) {
|
1179
|
+
VALUE previous_offset;
|
1180
|
+
VALUE parent;
|
1181
|
+
VALUE index;
|
1182
|
+
VALUE kind;
|
1183
|
+
rb_scan_args(argc, argv, "04", &previous_offset, &parent, &index, &kind);
|
1184
|
+
if (NIL_P(previous_offset))
|
1185
|
+
previous_offset = INT2FIX(0);
|
1186
|
+
if (NIL_P(kind))
|
1187
|
+
kind = cDataShape;
|
1188
|
+
cDataConverter_set_size_type(self, previous_offset, parent, index);
|
1189
|
+
VALUE members = rb_funcall(self, id___shape_fields, 1, kind);
|
1190
|
+
cDataConverter_unset_size_type(self);
|
1191
|
+
if (RARRAY_LEN(rb_funcall(rb_funcall(members, rb_intern("values"), 0), rb_intern("compact"), 0)) <= 0)
|
1192
|
+
return Qnil;
|
1193
|
+
return rb_class_new_instance(1, &members, kind);
|
1194
|
+
}
|
1195
|
+
|
1196
|
+
/* def self.load(input, input_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
|
1197
|
+
if length
|
1198
|
+
length.times.collect {
|
1199
|
+
h = self::new
|
1200
|
+
h.__load(input, input_big, parent, index)
|
1201
|
+
}
|
1202
|
+
else
|
1203
|
+
h = self::new
|
1204
|
+
h.__load(input, input_big, parent, index)
|
1205
|
+
end
|
1206
|
+
end */
|
1207
|
+
|
1208
|
+
static inline VALUE cDataConverter_singl_load(int argc, VALUE *argv, VALUE self) {
|
1209
|
+
VALUE input;
|
1210
|
+
VALUE input_big;
|
1211
|
+
VALUE parent;
|
1212
|
+
VALUE index;
|
1213
|
+
VALUE length;
|
1214
|
+
rb_scan_args(argc, argv, "14", &input, &input_big, &parent, &index, &length);
|
1215
|
+
if (NIL_P(input_big))
|
1216
|
+
input_big = rb_funcall(mLibBin, rb_intern("default_big?"), 0);
|
1217
|
+
VALUE res;
|
1218
|
+
if (!NIL_P(length)) {
|
1219
|
+
long l = NUM2LONG(length);
|
1220
|
+
res = rb_ary_new_capa(l);
|
1221
|
+
for (long i = 0; i < l; i++) {
|
1222
|
+
VALUE obj = rb_class_new_instance(0, NULL, self);
|
1223
|
+
rb_funcall(obj, id___load, 4, input, input_big, parent, index);
|
1224
|
+
rb_ary_store(res, i, obj);
|
1225
|
+
}
|
1226
|
+
return res;
|
1227
|
+
} else {
|
1228
|
+
res = rb_class_new_instance(0, NULL, self);
|
1229
|
+
rb_funcall(res, id___load, 4, input, input_big, parent, index);
|
1230
|
+
}
|
1231
|
+
return res;
|
1232
|
+
}
|
1233
|
+
|
1234
|
+
/* def self.dump(value, output, output_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
|
1235
|
+
if length
|
1236
|
+
length.times.each { |i|
|
1237
|
+
value[i].__dump(output, output_big, parent, index)
|
1238
|
+
}
|
1239
|
+
value
|
1240
|
+
else
|
1241
|
+
value.__dump(output, output_big, parent, index)
|
1242
|
+
end
|
1243
|
+
end */
|
1244
|
+
|
1245
|
+
static inline VALUE cDataConverter_singl_dump(int argc, VALUE *argv, VALUE self) {
|
1246
|
+
VALUE value;
|
1247
|
+
VALUE output;
|
1248
|
+
VALUE output_big;
|
1249
|
+
VALUE parent;
|
1250
|
+
VALUE index;
|
1251
|
+
VALUE length;
|
1252
|
+
rb_scan_args(argc, argv, "24", &value, &output, &output_big, &parent, &index, &length);
|
1253
|
+
if (NIL_P(output_big))
|
1254
|
+
output_big = rb_funcall(mLibBin, rb_intern("default_big?"), 0);
|
1255
|
+
if (!NIL_P(length)) {
|
1256
|
+
long l = NUM2LONG(length);
|
1257
|
+
for (long i = 0; i < l; i++)
|
1258
|
+
rb_funcall(rb_ary_entry(value, i), id___dump, 4, output, output_big, parent, index);
|
1259
|
+
} else
|
1260
|
+
rb_funcall(value, id___dump, 4, output, output_big, parent, index);
|
1261
|
+
return value;
|
1262
|
+
}
|
1263
|
+
|
1264
|
+
/* def self.convert(input, output, input_big = LibBin::default_big?, output_big = !input_big, parent = nil, index = nil, length = nil)
|
1265
|
+
if length
|
1266
|
+
length.times.collect {
|
1267
|
+
h = self::new
|
1268
|
+
h.__convert(input, output, input_big, output_big, parent, index)
|
1269
|
+
}
|
1270
|
+
else
|
1271
|
+
h = self::new
|
1272
|
+
h.__convert(input, output, input_big, output_big, parent, index)
|
1273
|
+
end
|
1274
|
+
end */
|
1275
|
+
|
1276
|
+
static inline VALUE cDataConverter_singl_convert(int argc, VALUE *argv, VALUE self) {
|
1277
|
+
VALUE input;
|
1278
|
+
VALUE output;
|
1279
|
+
VALUE input_big;
|
1280
|
+
VALUE output_big;
|
1281
|
+
VALUE parent;
|
1282
|
+
VALUE index;
|
1283
|
+
VALUE length;
|
1284
|
+
rb_scan_args(argc, argv, "25", &input, &output, &input_big, &output_big, &parent, &index, &length);
|
1285
|
+
if (NIL_P(input_big))
|
1286
|
+
input_big = rb_funcall(mLibBin, rb_intern("default_big?"), 0);
|
1287
|
+
if (NIL_P(output_big))
|
1288
|
+
output_big = RTEST(input_big) ? Qfalse : Qtrue;
|
1289
|
+
VALUE res;
|
1290
|
+
if (!NIL_P(length)) {
|
1291
|
+
long l = NUM2LONG(length);
|
1292
|
+
res = rb_ary_new_capa(l);
|
1293
|
+
for (long i = 0; i < l; i++) {
|
1294
|
+
VALUE obj = rb_class_new_instance(0, NULL, self);
|
1295
|
+
rb_funcall(obj, id___convert, 6, input, output, input_big, output_big, parent, index);
|
1296
|
+
rb_ary_store(res, i, obj);
|
1297
|
+
}
|
1298
|
+
} else {
|
1299
|
+
res = rb_class_new_instance(0, NULL, self);
|
1300
|
+
rb_funcall(res, id___convert, 6, input, output, input_big, output_big, parent, index);
|
1301
|
+
}
|
1302
|
+
return res;
|
1303
|
+
}
|
1304
|
+
|
1305
|
+
/* def self.shape(value, previous_offset = 0, parent = nil, index = nil, kind = DataShape, length = nil)
|
1306
|
+
if length
|
1307
|
+
kind::new(length.times.collect { |i|
|
1308
|
+
value[i].__shape(previous_offset, parent, index, kind)
|
1309
|
+
})
|
1310
|
+
else
|
1311
|
+
value.__shape(previous_offset, parent, index, kind)
|
1312
|
+
end
|
1313
|
+
end */
|
1314
|
+
|
1315
|
+
static inline VALUE cDataConverter_singl_shape(int argc, VALUE *argv, VALUE self) {
|
1316
|
+
VALUE value;
|
1317
|
+
VALUE previous_offset;
|
1318
|
+
VALUE parent;
|
1319
|
+
VALUE index;
|
1320
|
+
VALUE kind;
|
1321
|
+
VALUE length;
|
1322
|
+
rb_scan_args(argc, argv, "15", &value, &previous_offset, &parent, &index, &kind, &length);
|
1323
|
+
if (NIL_P(previous_offset))
|
1324
|
+
previous_offset = INT2FIX(0);
|
1325
|
+
if (NIL_P(kind))
|
1326
|
+
kind = cDataShape;
|
1327
|
+
VALUE res;
|
1328
|
+
if (!NIL_P(length)) {
|
1329
|
+
long l = NUM2LONG(length);
|
1330
|
+
res = rb_ary_new_capa(l);
|
1331
|
+
for (long i = 0; i < l; i++)
|
1332
|
+
rb_ary_store(res, i, rb_funcall(rb_ary_entry(value, i), id___shape, 4, previous_offset, parent, index, kind));
|
1333
|
+
res = rb_class_new_instance(1, &res, kind);
|
1334
|
+
} else
|
1335
|
+
res = rb_funcall(value, id___shape, 4, previous_offset, parent, index, kind);
|
1336
|
+
return res;
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
static void define_cDataConverter() {
|
1340
|
+
id_tell = rb_intern("tell");
|
1341
|
+
id_seek = rb_intern("seek");
|
1342
|
+
id_fields = rb_intern("@fields");
|
1343
|
+
id_instance_exec = rb_intern("instance_exec");
|
1344
|
+
|
1345
|
+
id___load_fields = rb_intern("__load_fields");
|
1346
|
+
id_load = rb_intern("load");
|
1347
|
+
id___load = rb_intern("__load");
|
1348
|
+
|
1349
|
+
id___dump_fields = rb_intern("__dump_fields");
|
1350
|
+
id_dump = rb_intern("dump");
|
1351
|
+
id___dump = rb_intern("__dump");
|
1352
|
+
|
1353
|
+
id___convert_fields = rb_intern("__convert_fields");
|
1354
|
+
id_convert = rb_intern("convert");
|
1355
|
+
id___convert = rb_intern("__convert");
|
1356
|
+
|
1357
|
+
id___shape_fields = rb_intern("__shape_fields");
|
1358
|
+
id_shape = rb_intern("shape");
|
1359
|
+
id___shape = rb_intern("__shape");
|
1360
|
+
|
1361
|
+
cDataConverter = rb_define_class_under(mLibBin, "DataConverter", rb_cObject);
|
1362
|
+
rb_define_alloc_func(cDataConverter, cDataConverter_alloc);
|
1363
|
+
rb_define_method(cDataConverter, "initialize", cDataConverter_initialize, 0);
|
1364
|
+
rb_define_method(cDataConverter, "__parent", cDataConverter_parent, 0);
|
1365
|
+
rb_define_method(cDataConverter, "__index", cDataConverter_index, 0);
|
1366
|
+
rb_define_method(cDataConverter, "__iterator", cDataConverter_iterator, 0);
|
1367
|
+
rb_define_method(cDataConverter, "__position", cDataConverter_position, 0);
|
1368
|
+
rb_define_method(cDataConverter, "__input", cDataConverter_input, 0);
|
1369
|
+
rb_define_method(cDataConverter, "__output", cDataConverter_output, 0);
|
1370
|
+
rb_define_method(cDataConverter, "__input_big", cDataConverter_input_big, 0);
|
1371
|
+
rb_define_method(cDataConverter, "__output_big", cDataConverter_output_big, 0);
|
1372
|
+
|
1373
|
+
rb_define_method(cDataConverter, "__set_convert_type", cDataConverter_set_convert_type, 6);
|
1374
|
+
rb_define_method(cDataConverter, "__unset_convert_type", cDataConverter_unset_convert_type, 0);
|
1375
|
+
rb_define_method(cDataConverter, "__set_size_type", cDataConverter_set_size_type, 3);
|
1376
|
+
rb_define_method(cDataConverter, "__unset_size_type", cDataConverter_unset_size_type, 0);
|
1377
|
+
rb_define_method(cDataConverter, "__set_load_type", cDataConverter_set_load_type, 4);
|
1378
|
+
rb_define_method(cDataConverter, "__unset_load_type", cDataConverter_unset_load_type, 0);
|
1379
|
+
rb_define_method(cDataConverter, "__set_dump_type", cDataConverter_set_dump_type, 4);
|
1380
|
+
rb_define_method(cDataConverter, "__unset_dump_type", cDataConverter_unset_dump_type, 0);
|
1381
|
+
|
1382
|
+
rb_define_method(cDataConverter, "__decode_expression", cDataConverter_decode_expression, 1);
|
1383
|
+
rb_define_method(cDataConverter, "__decode_seek_offset", cDataConverter_decode_seek_offset, 2);
|
1384
|
+
rb_define_method(cDataConverter, "__decode_condition", cDataConverter_decode_condition, 1);
|
1385
|
+
rb_define_method(cDataConverter, "__decode_count", cDataConverter_decode_count, 1);
|
1386
|
+
rb_define_method(cDataConverter, "__decode_type", cDataConverter_decode_type, 1);
|
1387
|
+
rb_define_method(cDataConverter, "__decode_length", cDataConverter_decode_length, 1);
|
1388
|
+
rb_define_method(cDataConverter, "__decode_static_conditions", cDataConverter_decode_static_conditions, 1);
|
1389
|
+
rb_define_method(cDataConverter, "__decode_dynamic_conditions", cDataConverter_decode_dynamic_conditions, 1);
|
1390
|
+
|
1391
|
+
rb_define_method(cDataConverter, "__restore_context", cDataConverter_restore_context, 0);
|
1392
|
+
|
1393
|
+
rb_define_method(cDataConverter, "__convert_field", cDataConverter_convert_field, 1);
|
1394
|
+
rb_define_method(cDataConverter, "__load_field", cDataConverter_load_field, 1);
|
1395
|
+
rb_define_method(cDataConverter, "__dump_field", cDataConverter_dump_field, 2);
|
1396
|
+
rb_define_method(cDataConverter, "__shape_field", cDataConverter_shape_field, 3);
|
1397
|
+
|
1398
|
+
rb_define_method(cDataConverter, "__load_fields", cDataConverter_load_fields, 0);
|
1399
|
+
rb_define_method(cDataConverter, "__dump_fields", cDataConverter_dump_fields, 0);
|
1400
|
+
rb_define_method(cDataConverter, "__convert_fields", cDataConverter_convert_fields, 0);
|
1401
|
+
rb_define_method(cDataConverter, "__shape_fields", cDataConverter_shape_fields, 1);
|
1402
|
+
|
1403
|
+
rb_define_method(cDataConverter, "__load", cDataConverter_load, -1);
|
1404
|
+
rb_define_method(cDataConverter, "__dump", cDataConverter_dump, -1);
|
1405
|
+
rb_define_method(cDataConverter, "__convert", cDataConverter_convert, -1);
|
1406
|
+
rb_define_method(cDataConverter, "__shape", cDataConverter_shape, -1);
|
1407
|
+
|
1408
|
+
rb_define_singleton_method(cDataConverter, "load", cDataConverter_singl_load, -1);
|
1409
|
+
rb_define_singleton_method(cDataConverter, "dump", cDataConverter_singl_dump, -1);
|
1410
|
+
rb_define_singleton_method(cDataConverter, "convert", cDataConverter_singl_convert, -1);
|
1411
|
+
rb_define_singleton_method(cDataConverter, "shape", cDataConverter_singl_shape, -1);
|
1412
|
+
}
|
1413
|
+
|
10
1414
|
static VALUE pghalf_from_string_p(VALUE self, VALUE str, VALUE pack_str) {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
1415
|
+
(void)self;
|
1416
|
+
Check_Type(str, T_STRING);
|
1417
|
+
Check_Type(pack_str, T_STRING);
|
1418
|
+
VALUE arr = rb_funcall(str, rb_intern("unpack"), 1, pack_str);
|
1419
|
+
uint16_t val = NUM2USHORT(rb_funcall(arr, rb_intern("first"), 0));
|
1420
|
+
union float_u res;
|
16
1421
|
|
17
|
-
|
18
|
-
|
1422
|
+
res.i = pghalf_to_float(val);
|
1423
|
+
return DBL2NUM(res.f);
|
19
1424
|
}
|
20
1425
|
|
21
1426
|
static VALUE half_from_string_p(VALUE self, VALUE str, VALUE pack_str) {
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
1427
|
+
(void)self;
|
1428
|
+
Check_Type(str, T_STRING);
|
1429
|
+
Check_Type(pack_str, T_STRING);
|
1430
|
+
VALUE arr = rb_funcall(str, rb_intern("unpack"), 1, pack_str);
|
1431
|
+
uint16_t val = NUM2USHORT(rb_funcall(arr, rb_intern("first"), 0));
|
1432
|
+
union float_u res;
|
27
1433
|
|
28
|
-
|
29
|
-
|
1434
|
+
res.i = half_to_float(val);
|
1435
|
+
return DBL2NUM(res.f);
|
30
1436
|
}
|
31
1437
|
|
32
1438
|
static VALUE pghalf_to_string_p(VALUE self, VALUE number, VALUE pack_str) {
|
33
|
-
|
34
|
-
|
35
|
-
|
1439
|
+
(void)self;
|
1440
|
+
Check_Type(number, T_FLOAT);
|
1441
|
+
union float_u val;
|
1442
|
+
uint16_t res;
|
36
1443
|
|
37
|
-
|
38
|
-
|
39
|
-
|
1444
|
+
val.f = NUM2DBL(number);
|
1445
|
+
res = pghalf_from_float(val.i);
|
1446
|
+
VALUE arr = rb_ary_new3(1, UINT2NUM(res) );
|
40
1447
|
|
41
|
-
|
1448
|
+
return rb_funcall(arr, rb_intern("pack"), 1, pack_str);
|
42
1449
|
}
|
43
1450
|
|
44
1451
|
static VALUE half_to_string_p(VALUE self, VALUE number, VALUE pack_str) {
|
45
|
-
|
46
|
-
|
47
|
-
|
1452
|
+
(void)self;
|
1453
|
+
Check_Type(number, T_FLOAT);
|
1454
|
+
union float_u val;
|
1455
|
+
uint16_t res;
|
48
1456
|
|
49
|
-
|
50
|
-
|
51
|
-
|
1457
|
+
val.f = NUM2DBL(number);
|
1458
|
+
res = half_from_float(val.i);
|
1459
|
+
VALUE arr = rb_ary_new3(1, UINT2NUM(res) );
|
52
1460
|
|
53
|
-
|
1461
|
+
return rb_funcall(arr, rb_intern("pack"), 1, pack_str);
|
54
1462
|
}
|
55
1463
|
|
56
1464
|
void Init_libbin_c() {
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
1465
|
+
mLibBin = rb_define_module("LibBin");
|
1466
|
+
rb_define_module_function(mLibBin, "half_from_string", half_from_string_p, 2);
|
1467
|
+
rb_define_module_function(mLibBin, "half_to_string", half_to_string_p, 2);
|
1468
|
+
rb_define_module_function(mLibBin, "pghalf_from_string", pghalf_from_string_p, 2);
|
1469
|
+
rb_define_module_function(mLibBin, "pghalf_to_string", pghalf_to_string_p, 2);
|
1470
|
+
cDataShape = rb_define_class_under(mLibBin, "DataShape", rb_cObject);
|
1471
|
+
define_cField();
|
1472
|
+
define_cDataConverter();
|
1473
|
+
define_cScalar();
|
65
1474
|
}
|