libbin 1.0.8 → 2.0.0
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 +107 -16
- data/ext/libbin/data_types.h +2 -1
- data/ext/libbin/libbin_c.c +1145 -679
- data/lib/libbin/data_types.rb +655 -132
- data/lib/libbin.rb +83 -17
- data/libbin.gemspec +1 -1
- metadata +2 -3
- data/lib/libbin/alignment.rb +0 -14
data/ext/libbin/libbin_c.c
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
VALUE cField;
|
5
5
|
VALUE mLibBin;
|
6
|
-
VALUE
|
6
|
+
VALUE cStructure;
|
7
7
|
|
8
8
|
static VALUE rb_str_dot_dot;
|
9
9
|
static VALUE rb_str___parent;
|
@@ -19,6 +19,8 @@ struct cField_data {
|
|
19
19
|
VALUE sequence;
|
20
20
|
VALUE condition;
|
21
21
|
VALUE relative_offset;
|
22
|
+
VALUE align;
|
23
|
+
VALUE expect;
|
22
24
|
ID getter;
|
23
25
|
ID setter;
|
24
26
|
};
|
@@ -72,10 +74,17 @@ static VALUE cField_initialize(
|
|
72
74
|
VALUE offset,
|
73
75
|
VALUE sequence,
|
74
76
|
VALUE condition,
|
75
|
-
VALUE relative_offset
|
77
|
+
VALUE relative_offset,
|
78
|
+
VALUE align,
|
79
|
+
VALUE expect) {
|
76
80
|
VALUE tmp;
|
77
81
|
struct cField_data *data;
|
78
82
|
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
83
|
+
if (RTEST(align)) {
|
84
|
+
size_t a = NUM2LL(align);
|
85
|
+
if (a & (a-1))
|
86
|
+
rb_raise(rb_eRuntimeError, "alignment is not a power of 2: %zu", a);
|
87
|
+
}
|
79
88
|
data->name = name;
|
80
89
|
tmp = rb_str_dup(rb_obj_as_string(name));
|
81
90
|
data->getter = rb_intern_str(tmp);
|
@@ -87,86 +96,38 @@ static VALUE cField_initialize(
|
|
87
96
|
data->sequence = sequence;
|
88
97
|
data->condition = cField_preprocess_expression(self, condition);
|
89
98
|
data->relative_offset = relative_offset;
|
99
|
+
data->align = align;
|
100
|
+
data->expect = expect;
|
90
101
|
return self;
|
91
102
|
}
|
92
103
|
|
93
|
-
|
94
|
-
struct cField_data *data;
|
95
|
-
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
96
|
-
return data->name;
|
97
|
-
}
|
104
|
+
#define FIELD_STATE_GETTER(propname) cField_get_ ## propname
|
98
105
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
106
|
+
#define CREATE_FIELD_STATE_GETTER(propname) \
|
107
|
+
static VALUE FIELD_STATE_GETTER(propname) (VALUE self) { \
|
108
|
+
struct cField_data *data; \
|
109
|
+
TypedData_Get_Struct(self, struct cField_data, &cField_type, data); \
|
110
|
+
return data->propname ; \
|
103
111
|
}
|
104
112
|
|
105
|
-
|
106
|
-
|
107
|
-
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
108
|
-
return data->length;
|
109
|
-
}
|
113
|
+
#define DEFINE_FIELD_STATE_GETTER(propname) \
|
114
|
+
rb_define_method(cField, #propname, FIELD_STATE_GETTER(propname), 0)
|
110
115
|
|
111
|
-
|
112
|
-
|
113
|
-
TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
|
114
|
-
return data->count;
|
115
|
-
}
|
116
|
+
#define DEFINE_FIELD_STATE_GETTER_BOOL(propname) \
|
117
|
+
rb_define_method(cField, #propname "?", FIELD_STATE_GETTER(propname), 0)
|
116
118
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
119
|
+
CREATE_FIELD_STATE_GETTER(name)
|
120
|
+
CREATE_FIELD_STATE_GETTER(type)
|
121
|
+
CREATE_FIELD_STATE_GETTER(length)
|
122
|
+
CREATE_FIELD_STATE_GETTER(count)
|
123
|
+
CREATE_FIELD_STATE_GETTER(offset)
|
124
|
+
CREATE_FIELD_STATE_GETTER(sequence)
|
125
|
+
CREATE_FIELD_STATE_GETTER(condition)
|
126
|
+
CREATE_FIELD_STATE_GETTER(relative_offset)
|
127
|
+
CREATE_FIELD_STATE_GETTER(align)
|
128
|
+
CREATE_FIELD_STATE_GETTER(expect)
|
122
129
|
|
123
|
-
|
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 {
|
130
|
+
struct cStructure_data {
|
170
131
|
VALUE __input;
|
171
132
|
VALUE __output;
|
172
133
|
VALUE __input_big;
|
@@ -182,39 +143,40 @@ struct cDataConverter_data {
|
|
182
143
|
VALUE __length;
|
183
144
|
VALUE __count;
|
184
145
|
VALUE __iterator;
|
146
|
+
VALUE __value;
|
185
147
|
};
|
186
148
|
|
187
|
-
static void
|
149
|
+
static void cStructure_mark(void* data) {
|
188
150
|
void *start = data;
|
189
|
-
void *end = (char *)data + sizeof(struct
|
151
|
+
void *end = (char *)data + sizeof(struct cStructure_data);
|
190
152
|
rb_gc_mark_locations((VALUE *)start, (VALUE *)end);
|
191
153
|
}
|
192
154
|
|
193
|
-
static size_t
|
155
|
+
static size_t cStructure_size(const void* data) {
|
194
156
|
(void)data;
|
195
|
-
return sizeof(struct
|
157
|
+
return sizeof(struct cStructure_data);
|
196
158
|
}
|
197
159
|
|
198
|
-
static const rb_data_type_t
|
199
|
-
.wrap_struct_name = "
|
160
|
+
static const rb_data_type_t cStructure_type = {
|
161
|
+
.wrap_struct_name = "cStructure_data",
|
200
162
|
.function = {
|
201
|
-
.dmark =
|
163
|
+
.dmark = cStructure_mark,
|
202
164
|
.dfree = RUBY_DEFAULT_FREE,
|
203
|
-
.dsize =
|
165
|
+
.dsize = cStructure_size,
|
204
166
|
},
|
205
167
|
.data = NULL,
|
206
168
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
207
169
|
};
|
208
170
|
|
209
|
-
static VALUE
|
210
|
-
struct
|
211
|
-
VALUE res = TypedData_Make_Struct(self, struct
|
171
|
+
static VALUE cStructure_alloc(VALUE self) {
|
172
|
+
struct cStructure_data *data;
|
173
|
+
VALUE res = TypedData_Make_Struct(self, struct cStructure_data, &cStructure_type, data);
|
212
174
|
return res;
|
213
175
|
}
|
214
176
|
|
215
|
-
static VALUE
|
216
|
-
struct
|
217
|
-
TypedData_Get_Struct(self, struct
|
177
|
+
static VALUE cStructure_initialize(VALUE self) {
|
178
|
+
struct cStructure_data *data;
|
179
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
218
180
|
data->__input = Qnil;
|
219
181
|
data->__output = Qnil;
|
220
182
|
data->__input_big = Qnil;
|
@@ -232,78 +194,49 @@ static VALUE cDataConverter_initialize(VALUE self) {
|
|
232
194
|
return self;
|
233
195
|
}
|
234
196
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
struct
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
static
|
276
|
-
|
277
|
-
|
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(
|
197
|
+
#define STRUCT_STATE_GETTER(propname) cStructure_get_ ## propname
|
198
|
+
#define STRUCT_STATE_SETTER(propname) cStructure_set_ ## propname
|
199
|
+
|
200
|
+
#define CREATE_STRUCT_STATE_ACCESSORS(propname) \
|
201
|
+
static VALUE STRUCT_STATE_GETTER(propname) (VALUE self) { \
|
202
|
+
struct cStructure_data *data; \
|
203
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data); \
|
204
|
+
return data->__ ## propname ; \
|
205
|
+
} \
|
206
|
+
static VALUE STRUCT_STATE_SETTER(propname) (VALUE self, VALUE propname) { \
|
207
|
+
struct cStructure_data *data; \
|
208
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data); \
|
209
|
+
return data->__ ## propname = propname; \
|
210
|
+
}
|
211
|
+
|
212
|
+
#define DEFINE_STRUCT_STATE_ACCESSORS(propname) \
|
213
|
+
do { \
|
214
|
+
rb_define_method(cStructure, "__" #propname, STRUCT_STATE_GETTER(propname), 0); \
|
215
|
+
rb_define_method(cStructure, "__" #propname "=", STRUCT_STATE_SETTER(propname), 1); \
|
216
|
+
} while(0)
|
217
|
+
|
218
|
+
CREATE_STRUCT_STATE_ACCESSORS(parent)
|
219
|
+
CREATE_STRUCT_STATE_ACCESSORS(index)
|
220
|
+
CREATE_STRUCT_STATE_ACCESSORS(position)
|
221
|
+
CREATE_STRUCT_STATE_ACCESSORS(cur_position)
|
222
|
+
CREATE_STRUCT_STATE_ACCESSORS(input)
|
223
|
+
CREATE_STRUCT_STATE_ACCESSORS(output)
|
224
|
+
CREATE_STRUCT_STATE_ACCESSORS(input_big)
|
225
|
+
CREATE_STRUCT_STATE_ACCESSORS(output_big)
|
226
|
+
|
227
|
+
CREATE_STRUCT_STATE_ACCESSORS(offset)
|
228
|
+
CREATE_STRUCT_STATE_ACCESSORS(condition)
|
229
|
+
CREATE_STRUCT_STATE_ACCESSORS(type)
|
230
|
+
CREATE_STRUCT_STATE_ACCESSORS(length)
|
231
|
+
CREATE_STRUCT_STATE_ACCESSORS(count)
|
232
|
+
CREATE_STRUCT_STATE_ACCESSORS(iterator)
|
233
|
+
CREATE_STRUCT_STATE_ACCESSORS(value)
|
234
|
+
|
235
|
+
static ID id_tell;
|
236
|
+
|
237
|
+
static ID id___set_convert_state;
|
238
|
+
|
239
|
+
static VALUE cStructure_set_convert_state(
|
307
240
|
VALUE self,
|
308
241
|
VALUE input,
|
309
242
|
VALUE output,
|
@@ -312,8 +245,8 @@ static inline VALUE cDataConverter_set_convert_type(
|
|
312
245
|
VALUE parent,
|
313
246
|
VALUE index)
|
314
247
|
{
|
315
|
-
struct
|
316
|
-
TypedData_Get_Struct(self, struct
|
248
|
+
struct cStructure_data *data;
|
249
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
317
250
|
data->__input = input;
|
318
251
|
data->__output = output;
|
319
252
|
data->__input_big = input_big;
|
@@ -325,20 +258,11 @@ static inline VALUE cDataConverter_set_convert_type(
|
|
325
258
|
return Qnil;
|
326
259
|
}
|
327
260
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
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);
|
261
|
+
static ID id___unset_convert_state;
|
262
|
+
|
263
|
+
static VALUE cStructure_unset_convert_state(VALUE self) {
|
264
|
+
struct cStructure_data *data;
|
265
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
342
266
|
data->__input = Qnil;
|
343
267
|
data->__output = Qnil;
|
344
268
|
data->__input_big = Qnil;
|
@@ -350,21 +274,16 @@ static inline VALUE cDataConverter_unset_convert_type(VALUE self) {
|
|
350
274
|
return Qnil;
|
351
275
|
}
|
352
276
|
|
353
|
-
|
354
|
-
@__parent = parent
|
355
|
-
@__index = index
|
356
|
-
@__position = position
|
357
|
-
@__cur_position = @__position
|
358
|
-
end */
|
277
|
+
static ID id___set_size_state;
|
359
278
|
|
360
|
-
static
|
279
|
+
static VALUE cStructure_set_size_state(
|
361
280
|
VALUE self,
|
362
281
|
VALUE position,
|
363
282
|
VALUE parent,
|
364
283
|
VALUE index)
|
365
284
|
{
|
366
|
-
struct
|
367
|
-
TypedData_Get_Struct(self, struct
|
285
|
+
struct cStructure_data *data;
|
286
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
368
287
|
data->__parent = parent;
|
369
288
|
data->__index = index;
|
370
289
|
data->__position = position;
|
@@ -372,16 +291,11 @@ static inline VALUE cDataConverter_set_size_type(
|
|
372
291
|
return Qnil;
|
373
292
|
}
|
374
293
|
|
375
|
-
|
376
|
-
@__parent = nil
|
377
|
-
@__index = nil
|
378
|
-
@__position = nil
|
379
|
-
@__cur_position = nil
|
380
|
-
end */
|
294
|
+
static ID id___unset_size_state;
|
381
295
|
|
382
|
-
static
|
383
|
-
struct
|
384
|
-
TypedData_Get_Struct(self, struct
|
296
|
+
static VALUE cStructure_unset_size_state(VALUE self) {
|
297
|
+
struct cStructure_data *data;
|
298
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
385
299
|
data->__parent = Qnil;
|
386
300
|
data->__index = Qnil;
|
387
301
|
data->__position = Qnil;
|
@@ -389,24 +303,17 @@ static inline VALUE cDataConverter_unset_size_type(VALUE self) {
|
|
389
303
|
return Qnil;
|
390
304
|
}
|
391
305
|
|
392
|
-
|
393
|
-
@__input_big = input_big
|
394
|
-
@__input = input
|
395
|
-
@__parent = parent
|
396
|
-
@__index = index
|
397
|
-
@__position = input.tell
|
398
|
-
@__cur_position = @__position
|
399
|
-
end */
|
306
|
+
static ID id___set_load_state;
|
400
307
|
|
401
|
-
static
|
308
|
+
static VALUE cStructure_set_load_state(
|
402
309
|
VALUE self,
|
403
310
|
VALUE input,
|
404
311
|
VALUE input_big,
|
405
312
|
VALUE parent,
|
406
313
|
VALUE index)
|
407
314
|
{
|
408
|
-
struct
|
409
|
-
TypedData_Get_Struct(self, struct
|
315
|
+
struct cStructure_data *data;
|
316
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
410
317
|
data->__input = input;
|
411
318
|
data->__input_big = input_big;
|
412
319
|
data->__parent = parent;
|
@@ -416,18 +323,11 @@ static inline VALUE cDataConverter_set_load_type(
|
|
416
323
|
return Qnil;
|
417
324
|
}
|
418
325
|
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
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);
|
326
|
+
static ID id___unset_load_state;
|
327
|
+
|
328
|
+
static VALUE cStructure_unset_load_state(VALUE self) {
|
329
|
+
struct cStructure_data *data;
|
330
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
431
331
|
data->__input = Qnil;
|
432
332
|
data->__input_big = Qnil;
|
433
333
|
data->__parent = Qnil;
|
@@ -437,24 +337,17 @@ static inline VALUE cDataConverter_unset_load_type(VALUE self) {
|
|
437
337
|
return Qnil;
|
438
338
|
}
|
439
339
|
|
440
|
-
|
441
|
-
@__output_big = output_big
|
442
|
-
@__output = output
|
443
|
-
@__parent = parent
|
444
|
-
@__index = index
|
445
|
-
@__position = output.tell
|
446
|
-
@__cur_position = @__position
|
447
|
-
end */
|
340
|
+
static ID id___set_dump_state;
|
448
341
|
|
449
|
-
static
|
342
|
+
static VALUE cStructure_set_dump_state(
|
450
343
|
VALUE self,
|
451
344
|
VALUE output,
|
452
345
|
VALUE output_big,
|
453
346
|
VALUE parent,
|
454
347
|
VALUE index)
|
455
348
|
{
|
456
|
-
struct
|
457
|
-
TypedData_Get_Struct(self, struct
|
349
|
+
struct cStructure_data *data;
|
350
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
458
351
|
data->__output = output;
|
459
352
|
data->__output_big = output_big;
|
460
353
|
data->__parent = parent;
|
@@ -464,18 +357,11 @@ static inline VALUE cDataConverter_set_dump_type(
|
|
464
357
|
return Qnil;
|
465
358
|
}
|
466
359
|
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
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);
|
360
|
+
static ID id___unset_dump_state;
|
361
|
+
|
362
|
+
static VALUE cStructure_unset_dump_state(VALUE self) {
|
363
|
+
struct cStructure_data *data;
|
364
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
479
365
|
data->__output = Qnil;
|
480
366
|
data->__output_big = Qnil;
|
481
367
|
data->__parent = Qnil;
|
@@ -485,48 +371,59 @@ static inline VALUE cDataConverter_unset_dump_type(VALUE self) {
|
|
485
371
|
return Qnil;
|
486
372
|
}
|
487
373
|
|
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
374
|
static ID id_instance_exec;
|
498
375
|
|
499
|
-
static inline VALUE
|
376
|
+
static inline VALUE cStructure_decode_expression(VALUE self, VALUE expression) {
|
500
377
|
if (rb_obj_is_proc(expression))
|
501
378
|
return rb_funcall_with_block(self, id_instance_exec, 0, NULL, expression);
|
502
379
|
else
|
503
380
|
return expression;
|
504
381
|
}
|
505
382
|
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
383
|
+
static inline VALUE cStructure_decode_expect(VALUE self, VALUE expect, VALUE val) {
|
384
|
+
if (NIL_P(expect))
|
385
|
+
return val;
|
386
|
+
if (rb_obj_is_proc(expect)) {
|
387
|
+
if (!RTEST(rb_funcall_with_block(self, id_instance_exec, 1, &val, expect)))
|
388
|
+
rb_raise(rb_eRuntimeError, "could not validate field value: %"PRIsVALUE, val);
|
389
|
+
} else
|
390
|
+
if (!RTEST(rb_equal(expect, val)))
|
391
|
+
rb_raise(rb_eRuntimeError, "could not validate field value: %"PRIsVALUE" expected: %"PRIsVALUE, val, expect);
|
392
|
+
return val;
|
393
|
+
}
|
516
394
|
|
517
395
|
ID id_seek;
|
518
396
|
|
519
|
-
static inline VALUE
|
520
|
-
struct
|
521
|
-
TypedData_Get_Struct(self, struct
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
397
|
+
static inline VALUE cStructure_decode_seek_offset(VALUE self, VALUE offset, VALUE relative_offset, VALUE align) {
|
398
|
+
struct cStructure_data *data;
|
399
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
400
|
+
ptrdiff_t cur_pos;
|
401
|
+
if (!RTEST(offset)) {
|
402
|
+
if (!RTEST(align))
|
403
|
+
return Qnil;
|
404
|
+
if (RTEST(data->__input))
|
405
|
+
cur_pos = NUM2LL(rb_funcall(data->__input, id_tell, 0));
|
406
|
+
else if (RTEST(data->__output))
|
407
|
+
cur_pos = NUM2LL(rb_funcall(data->__output, id_tell, 0));
|
408
|
+
else
|
409
|
+
cur_pos = NUM2LL(data->__cur_position);
|
410
|
+
ptrdiff_t al = NUM2LL(align);
|
411
|
+
ptrdiff_t pad;
|
412
|
+
if ((pad = ((-cur_pos) & (al - 1))) == 0)
|
413
|
+
return Qnil;
|
414
|
+
cur_pos += pad;
|
415
|
+
} else {
|
416
|
+
cur_pos = NUM2LL(cStructure_decode_expression(self, offset));
|
417
|
+
if (cur_pos == 0)
|
418
|
+
return Qfalse;
|
419
|
+
if (RTEST(relative_offset))
|
420
|
+
cur_pos += NUM2LL(data->__position);
|
421
|
+
if (RTEST(align)) {
|
422
|
+
ptrdiff_t al = NUM2LL(align);
|
423
|
+
cur_pos += (-cur_pos) & (al - 1);
|
424
|
+
}
|
425
|
+
}
|
426
|
+
data->__cur_position = LL2NUM(cur_pos);
|
530
427
|
if (RTEST(data->__input))
|
531
428
|
rb_funcall(data->__input, id_seek, 1, data->__cur_position);
|
532
429
|
if (RTEST(data->__output))
|
@@ -534,67 +431,32 @@ static inline VALUE cDataConverter_decode_seek_offset(VALUE self, VALUE offset,
|
|
534
431
|
return data->__cur_position;
|
535
432
|
}
|
536
433
|
|
537
|
-
|
538
|
-
return true unless condition
|
539
|
-
__decode_expression(condition)
|
540
|
-
end */
|
541
|
-
|
542
|
-
static inline VALUE cDataConverter_decode_condition(VALUE self, VALUE condition) {
|
434
|
+
static inline VALUE cStructure_decode_condition(VALUE self, VALUE condition) {
|
543
435
|
if (!RTEST(condition))
|
544
436
|
return Qtrue;
|
545
|
-
return
|
437
|
+
return cStructure_decode_expression(self, condition);
|
546
438
|
}
|
547
439
|
|
548
|
-
|
549
|
-
return 1 unless count
|
550
|
-
__decode_expression(count)
|
551
|
-
end */
|
552
|
-
|
553
|
-
static inline VALUE cDataConverter_decode_count(VALUE self, VALUE count) {
|
440
|
+
static inline VALUE cStructure_decode_count(VALUE self, VALUE count) {
|
554
441
|
if (!RTEST(count))
|
555
442
|
return INT2FIX(1);
|
556
|
-
return
|
443
|
+
return cStructure_decode_expression(self, count);
|
557
444
|
}
|
558
445
|
|
559
|
-
|
560
|
-
|
561
|
-
end */
|
562
|
-
|
563
|
-
static inline VALUE cDataConverter_decode_type(VALUE self, VALUE type) {
|
564
|
-
return cDataConverter_decode_expression(self, type);
|
446
|
+
static inline VALUE cStructure_decode_type(VALUE self, VALUE type) {
|
447
|
+
return cStructure_decode_expression(self, type);
|
565
448
|
}
|
566
449
|
|
567
|
-
|
568
|
-
__decode_expression(length)
|
569
|
-
end */
|
570
|
-
|
571
|
-
static inline VALUE cDataConverter_decode_length(VALUE self, VALUE length) {
|
450
|
+
static inline VALUE cStructure_decode_length(VALUE self, VALUE length) {
|
572
451
|
if (NIL_P(length))
|
573
452
|
return Qnil;
|
574
|
-
return
|
453
|
+
return cStructure_decode_expression(self, length);
|
575
454
|
}
|
576
455
|
|
577
|
-
|
578
|
-
|
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;
|
456
|
+
static inline VALUE cStructure_decode_static_conditions(VALUE self, VALUE field) {
|
457
|
+
struct cStructure_data *data;
|
596
458
|
struct cField_data *field_data;
|
597
|
-
TypedData_Get_Struct(self, struct
|
459
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
598
460
|
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
599
461
|
data->__offset = Qnil;
|
600
462
|
data->__condition = Qnil;
|
@@ -602,101 +464,64 @@ static inline VALUE cDataConverter_decode_static_conditions(VALUE self, VALUE fi
|
|
602
464
|
data->__length = Qnil;
|
603
465
|
data->__count = Qnil;
|
604
466
|
if (!RTEST(field_data->sequence)) {
|
605
|
-
data->__offset =
|
467
|
+
data->__offset = cStructure_decode_seek_offset(self, field_data->offset, field_data->relative_offset, field_data->align);
|
606
468
|
if (!data->__offset)
|
607
469
|
return Qnil;
|
608
|
-
data->__condition =
|
470
|
+
data->__condition = cStructure_decode_condition(self, field_data->condition);
|
609
471
|
if (!RTEST(data->__condition))
|
610
472
|
return Qnil;
|
611
|
-
data->__type =
|
612
|
-
data->__length =
|
473
|
+
data->__type = cStructure_decode_type(self, field_data->type);
|
474
|
+
data->__length = cStructure_decode_length(self, field_data->length);
|
613
475
|
}
|
614
|
-
data->__count =
|
476
|
+
data->__count = cStructure_decode_count(self, field_data->count);
|
615
477
|
return Qtrue;
|
616
478
|
}
|
617
479
|
|
618
|
-
|
619
|
-
|
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;
|
480
|
+
static inline VALUE cStructure_decode_dynamic_conditions(VALUE self, VALUE field) {
|
481
|
+
struct cStructure_data *data;
|
635
482
|
struct cField_data *field_data;
|
636
483
|
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
637
484
|
if (!RTEST(field_data->sequence))
|
638
485
|
return Qtrue;
|
639
|
-
TypedData_Get_Struct(self, struct
|
486
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
640
487
|
data->__offset = Qnil;
|
641
488
|
data->__condition = Qnil;
|
642
489
|
data->__type = Qnil;
|
643
490
|
data->__length = Qnil;
|
644
|
-
data->__offset =
|
491
|
+
data->__offset = cStructure_decode_seek_offset(self, field_data->offset, field_data->relative_offset, field_data->align);
|
645
492
|
if (!data->__offset)
|
646
493
|
return Qfalse;
|
647
|
-
data->__condition =
|
494
|
+
data->__condition = cStructure_decode_condition(self, field_data->condition);
|
648
495
|
if (!RTEST(data->__condition))
|
649
496
|
return Qfalse;
|
650
|
-
data->__type =
|
651
|
-
data->__length =
|
497
|
+
data->__type = cStructure_decode_type(self, field_data->type);
|
498
|
+
data->__length = cStructure_decode_length(self, field_data->length);
|
652
499
|
return Qtrue;
|
653
500
|
}
|
654
501
|
|
655
|
-
|
656
|
-
|
657
|
-
|
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);
|
502
|
+
static inline VALUE cStructure_restore_context(VALUE self) {
|
503
|
+
struct cStructure_data *data;
|
504
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
667
505
|
data->__iterator = Qnil;
|
668
506
|
data->__type = Qnil;
|
669
507
|
data->__length = Qnil;
|
670
508
|
data->__count = Qnil;
|
671
509
|
data->__offset = Qnil;
|
672
510
|
data->__condition = Qnil;
|
511
|
+
data->__value = Qnil;
|
673
512
|
return Qnil;
|
674
513
|
}
|
675
514
|
|
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
515
|
static ID id_convert;
|
516
|
+
static ID id___convert_field;
|
692
517
|
|
693
|
-
static inline VALUE
|
518
|
+
static inline VALUE cStructure_convert_field(VALUE self, VALUE field) {
|
694
519
|
VALUE res;
|
695
|
-
struct
|
520
|
+
struct cStructure_data *data;
|
696
521
|
struct cField_data *field_data;
|
697
|
-
if (NIL_P(
|
522
|
+
if (NIL_P(cStructure_decode_static_conditions(self, field)))
|
698
523
|
return Qnil;
|
699
|
-
TypedData_Get_Struct(self, struct
|
524
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
700
525
|
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
701
526
|
|
702
527
|
if (RTEST(field_data->count)) {
|
@@ -705,22 +530,24 @@ static inline VALUE cDataConverter_convert_field(VALUE self, VALUE field) {
|
|
705
530
|
|
706
531
|
for (long i = 0; i < count; i++) {
|
707
532
|
data->__iterator = LONG2NUM(i);
|
708
|
-
if (RTEST(
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
533
|
+
if (RTEST(cStructure_decode_dynamic_conditions(self, field))) {
|
534
|
+
data->__value = rb_funcall(data->__type, id_convert, 7,
|
535
|
+
data->__input,
|
536
|
+
data->__output,
|
537
|
+
data->__input_big,
|
538
|
+
data->__output_big,
|
539
|
+
self,
|
540
|
+
data->__iterator,
|
541
|
+
data->__length);
|
542
|
+
rb_ary_store(res, i,
|
543
|
+
cStructure_decode_expect(self, field_data->expect, data->__value));
|
544
|
+
} else
|
718
545
|
rb_ary_store(res, i, Qnil);
|
719
546
|
}
|
720
547
|
} else {
|
721
548
|
data->__iterator = INT2FIX(0);
|
722
|
-
if (RTEST(
|
723
|
-
|
549
|
+
if (RTEST(cStructure_decode_dynamic_conditions(self, field))) {
|
550
|
+
data->__value = rb_funcall(data->__type, id_convert, 7,
|
724
551
|
data->__input,
|
725
552
|
data->__output,
|
726
553
|
data->__input_big,
|
@@ -728,38 +555,25 @@ static inline VALUE cDataConverter_convert_field(VALUE self, VALUE field) {
|
|
728
555
|
self,
|
729
556
|
data->__iterator,
|
730
557
|
data->__length);
|
731
|
-
|
558
|
+
res = cStructure_decode_expect(self, field_data->expect, data->__value);
|
559
|
+
} else
|
732
560
|
res = Qnil;
|
733
561
|
}
|
734
562
|
|
735
|
-
|
563
|
+
cStructure_restore_context(self);
|
736
564
|
return res;
|
737
565
|
}
|
738
566
|
|
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
567
|
static ID id_load;
|
568
|
+
static ID id___load_field;
|
755
569
|
|
756
|
-
static inline VALUE
|
570
|
+
static inline VALUE cStructure_load_field(VALUE self, VALUE field) {
|
757
571
|
VALUE res;
|
758
|
-
struct
|
572
|
+
struct cStructure_data *data;
|
759
573
|
struct cField_data *field_data;
|
760
|
-
if (NIL_P(
|
574
|
+
if (NIL_P(cStructure_decode_static_conditions(self, field)))
|
761
575
|
return Qnil;
|
762
|
-
TypedData_Get_Struct(self, struct
|
576
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
763
577
|
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
764
578
|
|
765
579
|
if (RTEST(field_data->count)) {
|
@@ -768,52 +582,44 @@ static inline VALUE cDataConverter_load_field(VALUE self, VALUE field) {
|
|
768
582
|
|
769
583
|
for (long i = 0; i < count; i++) {
|
770
584
|
data->__iterator = LONG2NUM(i);
|
771
|
-
if (RTEST(
|
772
|
-
|
585
|
+
if (RTEST(cStructure_decode_dynamic_conditions(self, field))) {
|
586
|
+
data->__value = rb_funcall(data->__type, id_load, 5,
|
773
587
|
data->__input,
|
774
588
|
data->__input_big,
|
775
589
|
self,
|
776
590
|
data->__iterator,
|
777
|
-
data->__length)
|
778
|
-
|
591
|
+
data->__length);
|
592
|
+
rb_ary_store(res, i,
|
593
|
+
cStructure_decode_expect(self, field_data->expect, data->__value));
|
594
|
+
} else
|
779
595
|
rb_ary_store(res, i, Qnil);
|
780
596
|
}
|
781
597
|
} else {
|
782
598
|
data->__iterator = INT2FIX(0);
|
783
|
-
if (RTEST(
|
784
|
-
|
599
|
+
if (RTEST(cStructure_decode_dynamic_conditions(self, field))) {
|
600
|
+
data->__value = rb_funcall(data->__type, id_load, 5,
|
785
601
|
data->__input,
|
786
602
|
data->__input_big,
|
787
603
|
self,
|
788
604
|
data->__iterator,
|
789
605
|
data->__length);
|
790
|
-
|
606
|
+
res = cStructure_decode_expect(self, field_data->expect, data->__value);
|
607
|
+
} else
|
791
608
|
res = Qnil;
|
792
609
|
}
|
793
|
-
|
610
|
+
cStructure_restore_context(self);
|
794
611
|
return res;
|
795
612
|
}
|
796
613
|
|
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
614
|
static ID id_dump;
|
615
|
+
static ID id___dump_field;
|
810
616
|
|
811
|
-
static inline VALUE
|
812
|
-
struct
|
617
|
+
static inline VALUE cStructure_dump_field(VALUE self, VALUE values, VALUE field) {
|
618
|
+
struct cStructure_data *data;
|
813
619
|
struct cField_data *field_data;
|
814
|
-
if (NIL_P(
|
620
|
+
if (NIL_P(cStructure_decode_static_conditions(self, field)))
|
815
621
|
return Qnil;
|
816
|
-
TypedData_Get_Struct(self, struct
|
622
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
817
623
|
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
818
624
|
|
819
625
|
if (RTEST(field_data->count)) {
|
@@ -821,60 +627,51 @@ static inline VALUE cDataConverter_dump_field(VALUE self, VALUE values, VALUE fi
|
|
821
627
|
|
822
628
|
for (long i = 0; i < count; i++) {
|
823
629
|
data->__iterator = LONG2NUM(i);
|
824
|
-
if (RTEST(
|
630
|
+
if (RTEST(cStructure_decode_dynamic_conditions(self, field))) {
|
631
|
+
data->__value = rb_ary_entry(values, i);
|
632
|
+
cStructure_decode_expect(self, field_data->expect, data->__value);
|
825
633
|
rb_funcall(data->__type, id_dump, 6,
|
826
|
-
|
634
|
+
data->__value,
|
827
635
|
data->__output,
|
828
636
|
data->__output_big,
|
829
637
|
self,
|
830
638
|
data->__iterator,
|
831
639
|
data->__length);
|
640
|
+
}
|
832
641
|
}
|
833
642
|
} else {
|
834
643
|
data->__iterator = INT2FIX(0);
|
835
|
-
if (RTEST(
|
644
|
+
if (RTEST(cStructure_decode_dynamic_conditions(self, field))) {
|
645
|
+
data->__value = values;
|
646
|
+
cStructure_decode_expect(self, field_data->expect, data->__value);
|
836
647
|
rb_funcall(data->__type, id_dump, 6,
|
837
|
-
|
648
|
+
data->__value,
|
838
649
|
data->__output,
|
839
650
|
data->__output_big,
|
840
651
|
self,
|
841
652
|
data->__iterator,
|
842
653
|
data->__length);
|
654
|
+
}
|
843
655
|
}
|
844
|
-
|
656
|
+
cStructure_restore_context(self);
|
845
657
|
return Qnil;
|
846
658
|
}
|
847
659
|
|
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
660
|
static ID id_shape;
|
661
|
+
static ID id___shape_field;
|
865
662
|
|
866
|
-
static inline VALUE
|
663
|
+
static inline VALUE cStructure_shape_field(
|
867
664
|
VALUE self,
|
868
665
|
VALUE values,
|
869
666
|
VALUE kind,
|
870
667
|
VALUE field)
|
871
668
|
{
|
872
669
|
VALUE res = Qnil;
|
873
|
-
struct
|
670
|
+
struct cStructure_data *data;
|
874
671
|
struct cField_data *field_data;
|
875
|
-
if (NIL_P(
|
672
|
+
if (NIL_P(cStructure_decode_static_conditions(self, field)))
|
876
673
|
return Qnil;
|
877
|
-
TypedData_Get_Struct(self, struct
|
674
|
+
TypedData_Get_Struct(self, struct cStructure_data, &cStructure_type, data);
|
878
675
|
TypedData_Get_Struct(field, struct cField_data, &cField_type, field_data);
|
879
676
|
|
880
677
|
if (RTEST(field_data->count)) {
|
@@ -883,7 +680,7 @@ static inline VALUE cDataConverter_shape_field(
|
|
883
680
|
|
884
681
|
for (long i = 0; i < count; i++) {
|
885
682
|
data->__iterator = LONG2NUM(i);
|
886
|
-
if (RTEST(
|
683
|
+
if (RTEST(cStructure_decode_dynamic_conditions(self, field))) {
|
887
684
|
VALUE shape = rb_funcall(data->__type, id_shape, 6,
|
888
685
|
rb_ary_entry(values, i),
|
889
686
|
data->__cur_position,
|
@@ -903,7 +700,7 @@ static inline VALUE cDataConverter_shape_field(
|
|
903
700
|
res = rb_class_new_instance(1, &res, kind);
|
904
701
|
} else {
|
905
702
|
data->__iterator = INT2FIX(0);
|
906
|
-
if (RTEST(
|
703
|
+
if (RTEST(cStructure_decode_dynamic_conditions(self, field))) {
|
907
704
|
res = rb_funcall(data->__type, id_shape, 6,
|
908
705
|
values,
|
909
706
|
data->__cur_position,
|
@@ -919,22 +716,10 @@ static inline VALUE cDataConverter_shape_field(
|
|
919
716
|
}
|
920
717
|
}
|
921
718
|
}
|
922
|
-
|
719
|
+
cStructure_restore_context(self);
|
923
720
|
return res;
|
924
721
|
}
|
925
722
|
|
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
723
|
static ID id_fields;
|
939
724
|
|
940
725
|
struct fields_state {
|
@@ -943,13 +728,13 @@ struct fields_state {
|
|
943
728
|
VALUE field;
|
944
729
|
};
|
945
730
|
|
946
|
-
static inline VALUE
|
731
|
+
static inline VALUE cStructure_fields_rescue(VALUE state_p, VALUE exception) {
|
947
732
|
struct fields_state *state = (struct fields_state *)state_p;
|
948
733
|
if (NIL_P(state->field)) {
|
949
|
-
struct
|
950
|
-
TypedData_Get_Struct(state->self, struct
|
951
|
-
if (!NIL_P(
|
952
|
-
rb_funcall(
|
734
|
+
struct cStructure_data *data;
|
735
|
+
TypedData_Get_Struct(state->self, struct cStructure_data, &cStructure_type, data);
|
736
|
+
if (!NIL_P(rb_funcall(mLibBin, rb_intern("output"), 0)))
|
737
|
+
rb_funcall(rb_funcall(mLibBin, rb_intern("output"), 0), rb_intern("print"), 6,
|
953
738
|
rb_obj_class(state->self),
|
954
739
|
rb_str_new_cstr(": could not load fields, index: "),
|
955
740
|
data->__index,
|
@@ -959,8 +744,8 @@ static inline VALUE cDataConverter_fields_rescue(VALUE state_p, VALUE exception)
|
|
959
744
|
} else {
|
960
745
|
struct cField_data *field_data;
|
961
746
|
TypedData_Get_Struct(state->field, struct cField_data, &cField_type, field_data);
|
962
|
-
if (!NIL_P(
|
963
|
-
rb_funcall(
|
747
|
+
if (!NIL_P(rb_funcall(mLibBin, rb_intern("output"), 0)))
|
748
|
+
rb_funcall(rb_funcall(mLibBin, rb_intern("output"), 0), rb_intern("print"), 6,
|
964
749
|
rb_obj_class(state->self),
|
965
750
|
rb_str_new_cstr(": "),
|
966
751
|
field_data->name,
|
@@ -972,106 +757,69 @@ static inline VALUE cDataConverter_fields_rescue(VALUE state_p, VALUE exception)
|
|
972
757
|
return state->self;
|
973
758
|
}
|
974
759
|
|
975
|
-
static inline VALUE
|
760
|
+
static inline VALUE cStructure_load_fields_wrapper(VALUE state_p) {
|
976
761
|
struct fields_state *state = (struct fields_state *)state_p;
|
977
762
|
state->fields = rb_ivar_get(rb_obj_class(state->self), id_fields);
|
978
763
|
for (long i = 0; i < RARRAY_LEN(state->fields); i++) {
|
979
764
|
state->field = rb_ary_entry(state->fields, i);
|
980
765
|
struct cField_data *field_data;
|
981
766
|
TypedData_Get_Struct(state->field, struct cField_data, &cField_type, field_data);
|
982
|
-
rb_funcall(state->self, field_data->setter, 1,
|
767
|
+
rb_funcall(state->self, field_data->setter, 1, rb_funcall(state->self, id___load_field, 1, state->field));
|
983
768
|
}
|
984
769
|
return state->self;
|
985
770
|
}
|
986
771
|
|
987
772
|
static ID id___load_fields;
|
988
773
|
|
989
|
-
static
|
774
|
+
static VALUE cStructure_load_fields(VALUE self) {
|
990
775
|
struct fields_state state = {self, Qnil, Qnil};
|
991
|
-
rb_rescue(&
|
992
|
-
&
|
776
|
+
rb_rescue(&cStructure_load_fields_wrapper, (VALUE)&state,
|
777
|
+
&cStructure_fields_rescue, (VALUE)&state);
|
993
778
|
return self;
|
994
779
|
}
|
995
780
|
|
996
|
-
|
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) {
|
781
|
+
static inline VALUE cStructure_dump_fields_wrapper(VALUE state_p) {
|
1009
782
|
struct fields_state *state = (struct fields_state *)state_p;
|
1010
783
|
state->fields = rb_ivar_get(rb_obj_class(state->self), id_fields);
|
1011
784
|
for (long i = 0; i < RARRAY_LEN(state->fields); i++) {
|
1012
785
|
state->field = rb_ary_entry(state->fields, i);
|
1013
786
|
struct cField_data *field_data;
|
1014
787
|
TypedData_Get_Struct(state->field, struct cField_data, &cField_type, field_data);
|
1015
|
-
|
788
|
+
rb_funcall(state->self, id___dump_field, 2, rb_funcall(state->self, field_data->getter, 0), state->field);
|
1016
789
|
}
|
1017
790
|
return state->self;
|
1018
791
|
}
|
1019
792
|
|
1020
793
|
static ID id___dump_fields;
|
1021
794
|
|
1022
|
-
static
|
795
|
+
static VALUE cStructure_dump_fields(VALUE self) {
|
1023
796
|
struct fields_state state = {self, Qnil, Qnil};
|
1024
|
-
rb_rescue(&
|
1025
|
-
&
|
797
|
+
rb_rescue(&cStructure_dump_fields_wrapper, (VALUE)&state,
|
798
|
+
&cStructure_fields_rescue, (VALUE)&state);
|
1026
799
|
return self;
|
1027
800
|
}
|
1028
801
|
|
1029
|
-
|
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) {
|
802
|
+
static inline VALUE cStructure_convert_fields_wrapper(VALUE state_p) {
|
1042
803
|
struct fields_state *state = (struct fields_state *)state_p;
|
1043
804
|
state->fields = rb_ivar_get(rb_obj_class(state->self), id_fields);
|
1044
805
|
for (long i = 0; i < RARRAY_LEN(state->fields); i++) {
|
1045
806
|
state->field = rb_ary_entry(state->fields, i);
|
1046
807
|
struct cField_data *field_data;
|
1047
808
|
TypedData_Get_Struct(state->field, struct cField_data, &cField_type, field_data);
|
1048
|
-
rb_funcall(state->self, field_data->setter, 1,
|
809
|
+
rb_funcall(state->self, field_data->setter, 1, rb_funcall(state->self, id___convert_field, 1, state->field));
|
1049
810
|
}
|
1050
811
|
return state->self;
|
1051
812
|
}
|
1052
813
|
|
1053
814
|
static ID id___convert_fields;
|
1054
815
|
|
1055
|
-
static
|
816
|
+
static VALUE cStructure_convert_fields(VALUE self) {
|
1056
817
|
struct fields_state state = {self, Qnil, Qnil};
|
1057
|
-
rb_rescue(&
|
1058
|
-
&
|
818
|
+
rb_rescue(&cStructure_convert_fields_wrapper, (VALUE)&state,
|
819
|
+
&cStructure_fields_rescue, (VALUE)&state);
|
1059
820
|
return self;
|
1060
821
|
}
|
1061
822
|
|
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
823
|
struct shape_fields_state {
|
1076
824
|
VALUE self;
|
1077
825
|
VALUE fields;
|
@@ -1079,7 +827,7 @@ struct shape_fields_state {
|
|
1079
827
|
VALUE kind;
|
1080
828
|
};
|
1081
829
|
|
1082
|
-
static inline VALUE
|
830
|
+
static inline VALUE cStructure_shape_fields_wrapper(VALUE state_p) {
|
1083
831
|
struct shape_fields_state *state = (struct shape_fields_state *)state_p;
|
1084
832
|
state->fields = rb_ivar_get(rb_obj_class(state->self), id_fields);
|
1085
833
|
VALUE members = rb_hash_new();
|
@@ -1087,71 +835,51 @@ static inline VALUE cDataConverter_shape_fields_wrapper(VALUE state_p) {
|
|
1087
835
|
state->field = rb_ary_entry(state->fields, i);
|
1088
836
|
struct cField_data *field_data;
|
1089
837
|
TypedData_Get_Struct(state->field, struct cField_data, &cField_type, field_data);
|
1090
|
-
rb_hash_aset(members, ID2SYM(field_data->getter),
|
838
|
+
rb_hash_aset(members, ID2SYM(field_data->getter),
|
839
|
+
rb_funcall(state->self, id___shape_field, 3, rb_funcall(state->self, field_data->getter, 0), state->kind, state->field));
|
1091
840
|
}
|
1092
841
|
return members;
|
1093
842
|
}
|
1094
843
|
|
1095
844
|
static ID id___shape_fields;
|
1096
845
|
|
1097
|
-
static
|
846
|
+
static VALUE cStructure_shape_fields(VALUE self, VALUE kind) {
|
1098
847
|
struct shape_fields_state state = {self, Qnil, Qnil, kind};
|
1099
|
-
return rb_rescue(&
|
1100
|
-
&
|
848
|
+
return rb_rescue(&cStructure_shape_fields_wrapper, (VALUE)&state,
|
849
|
+
&cStructure_fields_rescue, (VALUE)&state);
|
1101
850
|
}
|
1102
851
|
|
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
852
|
static ID id___load;
|
1111
853
|
|
1112
|
-
static inline VALUE
|
854
|
+
static inline VALUE cStructure_load(int argc, VALUE *argv, VALUE self) {
|
1113
855
|
VALUE input;
|
1114
856
|
VALUE input_big;
|
1115
857
|
VALUE parent;
|
1116
858
|
VALUE index;
|
1117
859
|
rb_scan_args(argc, argv, "22", &input, &input_big, &parent, &index);
|
1118
|
-
|
860
|
+
rb_funcall(self, id___set_load_state, 4, input, input_big, parent, index);
|
1119
861
|
rb_funcall(self, id___load_fields, 0);
|
1120
|
-
|
862
|
+
rb_funcall(self, id___unset_load_state, 0);
|
1121
863
|
return self;
|
1122
864
|
}
|
1123
865
|
|
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
866
|
static ID id___dump;
|
1132
867
|
|
1133
|
-
static inline VALUE
|
868
|
+
static inline VALUE cStructure_dump(int argc, VALUE *argv, VALUE self) {
|
1134
869
|
VALUE output;
|
1135
870
|
VALUE output_big;
|
1136
871
|
VALUE parent;
|
1137
872
|
VALUE index;
|
1138
873
|
rb_scan_args(argc, argv, "22", &output, &output_big, &parent, &index);
|
1139
|
-
|
874
|
+
rb_funcall(self, id___set_dump_state, 4, output, output_big, parent, index);
|
1140
875
|
rb_funcall(self, id___dump_fields, 0);
|
1141
|
-
|
876
|
+
rb_funcall(self, id___unset_dump_state, 0);
|
1142
877
|
return self;
|
1143
878
|
}
|
1144
879
|
|
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
880
|
static ID id___convert;
|
1153
881
|
|
1154
|
-
static
|
882
|
+
static VALUE cStructure_convert(int argc, VALUE *argv, VALUE self) {
|
1155
883
|
VALUE input;
|
1156
884
|
VALUE output;
|
1157
885
|
VALUE input_big;
|
@@ -1159,23 +887,15 @@ static inline VALUE cDataConverter_convert(int argc, VALUE *argv, VALUE self) {
|
|
1159
887
|
VALUE parent;
|
1160
888
|
VALUE index;
|
1161
889
|
rb_scan_args(argc, argv, "42", &input, &output, &input_big, &output_big, &parent, &index);
|
1162
|
-
|
890
|
+
rb_funcall(self, id___set_convert_state, 6, input, output, input_big, output_big, parent, index);
|
1163
891
|
rb_funcall(self, id___convert_fields, 0);
|
1164
|
-
|
892
|
+
rb_funcall(self, id___unset_convert_state, 0);
|
1165
893
|
return self;
|
1166
894
|
}
|
1167
895
|
|
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
896
|
static ID id___shape;
|
1177
897
|
|
1178
|
-
static
|
898
|
+
static VALUE cStructure_shape(int argc, VALUE *argv, VALUE self) {
|
1179
899
|
VALUE previous_offset;
|
1180
900
|
VALUE parent;
|
1181
901
|
VALUE index;
|
@@ -1185,27 +905,15 @@ static inline VALUE cDataConverter_shape(int argc, VALUE *argv, VALUE self) {
|
|
1185
905
|
previous_offset = INT2FIX(0);
|
1186
906
|
if (NIL_P(kind))
|
1187
907
|
kind = cDataShape;
|
1188
|
-
|
908
|
+
rb_funcall(self, id___set_size_state, 3, previous_offset, parent, index);
|
1189
909
|
VALUE members = rb_funcall(self, id___shape_fields, 1, kind);
|
1190
|
-
|
910
|
+
rb_funcall(self, id___unset_size_state, 0);
|
1191
911
|
if (RARRAY_LEN(rb_funcall(rb_funcall(members, rb_intern("values"), 0), rb_intern("compact"), 0)) <= 0)
|
1192
912
|
return Qnil;
|
1193
913
|
return rb_class_new_instance(1, &members, kind);
|
1194
914
|
}
|
1195
915
|
|
1196
|
-
|
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) {
|
916
|
+
static VALUE cStructure_singl_load(int argc, VALUE *argv, VALUE self) {
|
1209
917
|
VALUE input;
|
1210
918
|
VALUE input_big;
|
1211
919
|
VALUE parent;
|
@@ -1231,18 +939,7 @@ static inline VALUE cDataConverter_singl_load(int argc, VALUE *argv, VALUE self)
|
|
1231
939
|
return res;
|
1232
940
|
}
|
1233
941
|
|
1234
|
-
|
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) {
|
942
|
+
static VALUE cStructure_singl_dump(int argc, VALUE *argv, VALUE self) {
|
1246
943
|
VALUE value;
|
1247
944
|
VALUE output;
|
1248
945
|
VALUE output_big;
|
@@ -1261,19 +958,7 @@ static inline VALUE cDataConverter_singl_dump(int argc, VALUE *argv, VALUE self)
|
|
1261
958
|
return value;
|
1262
959
|
}
|
1263
960
|
|
1264
|
-
|
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) {
|
961
|
+
static VALUE cStructure_singl_convert(int argc, VALUE *argv, VALUE self) {
|
1277
962
|
VALUE input;
|
1278
963
|
VALUE output;
|
1279
964
|
VALUE input_big;
|
@@ -1302,17 +987,7 @@ static inline VALUE cDataConverter_singl_convert(int argc, VALUE *argv, VALUE se
|
|
1302
987
|
return res;
|
1303
988
|
}
|
1304
989
|
|
1305
|
-
|
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) {
|
990
|
+
static VALUE cStructure_singl_shape(int argc, VALUE *argv, VALUE self) {
|
1316
991
|
VALUE value;
|
1317
992
|
VALUE previous_offset;
|
1318
993
|
VALUE parent;
|
@@ -1336,79 +1011,766 @@ static inline VALUE cDataConverter_singl_shape(int argc, VALUE *argv, VALUE self
|
|
1336
1011
|
return res;
|
1337
1012
|
}
|
1338
1013
|
|
1339
|
-
static void
|
1014
|
+
static void define_cStructure() {
|
1340
1015
|
id_tell = rb_intern("tell");
|
1341
1016
|
id_seek = rb_intern("seek");
|
1342
1017
|
id_fields = rb_intern("@fields");
|
1343
1018
|
id_instance_exec = rb_intern("instance_exec");
|
1344
1019
|
|
1020
|
+
id___set_load_state = rb_intern("__set_load_state");
|
1021
|
+
id___unset_load_state = rb_intern("__unset_load_state");
|
1022
|
+
id___load_field = rb_intern("__load_field");
|
1345
1023
|
id___load_fields = rb_intern("__load_fields");
|
1346
1024
|
id_load = rb_intern("load");
|
1347
1025
|
id___load = rb_intern("__load");
|
1348
1026
|
|
1027
|
+
id___set_dump_state = rb_intern("__set_dump_state");
|
1028
|
+
id___unset_dump_state = rb_intern("__unset_dump_state");
|
1029
|
+
id___dump_field = rb_intern("__dump_field");
|
1349
1030
|
id___dump_fields = rb_intern("__dump_fields");
|
1350
1031
|
id_dump = rb_intern("dump");
|
1351
1032
|
id___dump = rb_intern("__dump");
|
1352
1033
|
|
1034
|
+
id___set_convert_state = rb_intern("__set_convert_state");
|
1035
|
+
id___unset_convert_state = rb_intern("__unset_convert_state");
|
1036
|
+
id___convert_field = rb_intern("__convert_field");
|
1353
1037
|
id___convert_fields = rb_intern("__convert_fields");
|
1354
1038
|
id_convert = rb_intern("convert");
|
1355
1039
|
id___convert = rb_intern("__convert");
|
1356
1040
|
|
1041
|
+
id___set_size_state = rb_intern("__set_size_state");
|
1042
|
+
id___unset_size_state = rb_intern("__unset_size_state");
|
1043
|
+
id___shape_field = rb_intern("__shape_field");
|
1357
1044
|
id___shape_fields = rb_intern("__shape_fields");
|
1358
1045
|
id_shape = rb_intern("shape");
|
1359
1046
|
id___shape = rb_intern("__shape");
|
1360
1047
|
|
1361
|
-
|
1362
|
-
rb_define_alloc_func(
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
rb_define_method(
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1048
|
+
cStructure = rb_define_class_under(mLibBin, "Structure", rb_cObject);
|
1049
|
+
rb_define_alloc_func(cStructure, cStructure_alloc);
|
1050
|
+
/**
|
1051
|
+
* Create new Structure object.
|
1052
|
+
* @return [Structure] a new Structure instance with state set to nil.
|
1053
|
+
*/
|
1054
|
+
rb_define_method(cStructure, "initialize", cStructure_initialize, 0);
|
1055
|
+
|
1056
|
+
DEFINE_STRUCT_STATE_ACCESSORS(parent);
|
1057
|
+
DEFINE_STRUCT_STATE_ACCESSORS(index);
|
1058
|
+
DEFINE_STRUCT_STATE_ACCESSORS(position);
|
1059
|
+
DEFINE_STRUCT_STATE_ACCESSORS(cur_position);
|
1060
|
+
DEFINE_STRUCT_STATE_ACCESSORS(input);
|
1061
|
+
DEFINE_STRUCT_STATE_ACCESSORS(output);
|
1062
|
+
DEFINE_STRUCT_STATE_ACCESSORS(input_big);
|
1063
|
+
DEFINE_STRUCT_STATE_ACCESSORS(output_big);
|
1064
|
+
|
1065
|
+
DEFINE_STRUCT_STATE_ACCESSORS(offset);
|
1066
|
+
DEFINE_STRUCT_STATE_ACCESSORS(condition);
|
1067
|
+
DEFINE_STRUCT_STATE_ACCESSORS(type);
|
1068
|
+
DEFINE_STRUCT_STATE_ACCESSORS(length);
|
1069
|
+
DEFINE_STRUCT_STATE_ACCESSORS(iterator);
|
1070
|
+
DEFINE_STRUCT_STATE_ACCESSORS(count);
|
1071
|
+
DEFINE_STRUCT_STATE_ACCESSORS(value);
|
1072
|
+
|
1073
|
+
/**
|
1074
|
+
* @overload __set_convert_state(input, output, input_big, output_big, parent, index)
|
1075
|
+
* Set attributes for conversion
|
1076
|
+
* @param input [IO] the stream to read data from
|
1077
|
+
* @param output [IO] the stream to write data to
|
1078
|
+
* @param input_big [Boolean] str endianness of +input+
|
1079
|
+
* @param output_big [Boolean] str endianness of +output+
|
1080
|
+
* @param parent [nil,Structure] the parent if it exists, nil otherwise
|
1081
|
+
* @param index [nil,Integer] the index if the structure is repeated, nil otherwise
|
1082
|
+
* @return [nil]
|
1083
|
+
* @example
|
1084
|
+
* # Orignal Ruby implementation
|
1085
|
+
* def __set_convert_state(input, output, input_big, output_big, parent, index)
|
1086
|
+
* __input_big = input_big
|
1087
|
+
* __output_big = output_big
|
1088
|
+
* __input = input
|
1089
|
+
* __output = output
|
1090
|
+
* __parent = parent
|
1091
|
+
* __index = index
|
1092
|
+
* __position = input.tell
|
1093
|
+
* __cur_position = __position
|
1094
|
+
* end
|
1095
|
+
*/
|
1096
|
+
rb_define_method(cStructure, "__set_convert_state", cStructure_set_convert_state, 6);
|
1097
|
+
/**
|
1098
|
+
* Unset attributes after conversion.
|
1099
|
+
* @return [nil]
|
1100
|
+
* @example
|
1101
|
+
* # Orignal Ruby implementation
|
1102
|
+
* def __unset_convert_state
|
1103
|
+
* __input_big = nil
|
1104
|
+
* __output_big = nil
|
1105
|
+
* __input = nil
|
1106
|
+
* __output = nil
|
1107
|
+
* __parent = nil
|
1108
|
+
* __index = nil
|
1109
|
+
* __position = nil
|
1110
|
+
* __cur_position = nil
|
1111
|
+
* end
|
1112
|
+
*/
|
1113
|
+
rb_define_method(cStructure, "__unset_convert_state", cStructure_unset_convert_state, 0);
|
1114
|
+
/**
|
1115
|
+
* @overload __set_size_state(position, parent, index)
|
1116
|
+
* Set attributes for computing size or shape
|
1117
|
+
* @param position [Integer] The position of the field
|
1118
|
+
* @param parent [nil,Structure] the parent if it exists, nil otherwise
|
1119
|
+
* @param index [nil,Integer] the index if the structure is repeated, nil otherwise
|
1120
|
+
* @return [nil]
|
1121
|
+
* @example
|
1122
|
+
* # Orignal Ruby implementation
|
1123
|
+
* def __set_size_state(position, parent, index)
|
1124
|
+
* __parent = parent
|
1125
|
+
* __index = index
|
1126
|
+
* __position = position
|
1127
|
+
* __cur_position = __position
|
1128
|
+
* end
|
1129
|
+
*/
|
1130
|
+
rb_define_method(cStructure, "__set_size_state", cStructure_set_size_state, 3);
|
1131
|
+
/**
|
1132
|
+
* Unset attributes after size or shape computation
|
1133
|
+
* @return [nil]
|
1134
|
+
* @example
|
1135
|
+
* # Orignal Ruby implementation
|
1136
|
+
* def __unset_size_state
|
1137
|
+
* __parent = nil
|
1138
|
+
* __index = nil
|
1139
|
+
* __position = nil
|
1140
|
+
* __cur_position = nil
|
1141
|
+
* end
|
1142
|
+
*/
|
1143
|
+
rb_define_method(cStructure, "__unset_size_state", cStructure_unset_size_state, 0);
|
1144
|
+
/**
|
1145
|
+
* @overload __set_load_state(input, input_big, parent, index)
|
1146
|
+
* Set attributes for loading
|
1147
|
+
* @param input [IO] the stream to read data from
|
1148
|
+
* @param input_big [Boolean] str endianness of +input+
|
1149
|
+
* @param parent [nil,Structure] the parent if it exists, nil otherwise
|
1150
|
+
* @param index [nil,Integer] the index if the structure is repeated, nil otherwise
|
1151
|
+
* @return [nil]
|
1152
|
+
* @example
|
1153
|
+
* # Orignal Ruby implementation
|
1154
|
+
* def __set_load_state(input, input_big, parent, index)
|
1155
|
+
* __input_big = input_big
|
1156
|
+
* __input = input
|
1157
|
+
* __parent = parent
|
1158
|
+
* __index = index
|
1159
|
+
* __position = input.tell
|
1160
|
+
* __cur_position = __position
|
1161
|
+
* end
|
1162
|
+
*/
|
1163
|
+
rb_define_method(cStructure, "__set_load_state", cStructure_set_load_state, 4);
|
1164
|
+
/**
|
1165
|
+
* Unset attributes after loading
|
1166
|
+
* @return [nil]
|
1167
|
+
* @example
|
1168
|
+
* # Orignal Ruby implementation
|
1169
|
+
* def __unset_load_state
|
1170
|
+
* __input_big = nil
|
1171
|
+
* __input = nil
|
1172
|
+
* __parent = nil
|
1173
|
+
* __index = nil
|
1174
|
+
* __position = nil
|
1175
|
+
* __cur_position = nil
|
1176
|
+
* end
|
1177
|
+
*/
|
1178
|
+
rb_define_method(cStructure, "__unset_load_state", cStructure_unset_load_state, 0);
|
1179
|
+
/**
|
1180
|
+
* @overload __set_dump_state(output, output_big, parent, index)
|
1181
|
+
* Set attributes for dumping
|
1182
|
+
* @param output [IO] the stream to write data to
|
1183
|
+
* @param output_big [Boolean] str endianness of +output+
|
1184
|
+
* @param parent [nil,Structure] the parent if it exists, nil otherwise
|
1185
|
+
* @param index [nil,Integer] the index if the structure is repeated, nil otherwise
|
1186
|
+
* @return [nil]
|
1187
|
+
* @example
|
1188
|
+
* # Orignal Ruby implementation
|
1189
|
+
* def __set_dump_state(output, output_big, parent, index)
|
1190
|
+
* __output_big = output_big
|
1191
|
+
* __output = output
|
1192
|
+
* __parent = parent
|
1193
|
+
* __index = index
|
1194
|
+
* __position = output.tell
|
1195
|
+
* __cur_position = __position
|
1196
|
+
* end
|
1197
|
+
*/
|
1198
|
+
rb_define_method(cStructure, "__set_dump_state", cStructure_set_dump_state, 4);
|
1199
|
+
/**
|
1200
|
+
* Unset attributes after dumping
|
1201
|
+
* @return [nil]
|
1202
|
+
* @example
|
1203
|
+
* # Orignal Ruby implementation
|
1204
|
+
* def __unset_dump_state
|
1205
|
+
* __output_big = nil
|
1206
|
+
* __output = nil
|
1207
|
+
* __parent = nil
|
1208
|
+
* __index = nil
|
1209
|
+
* __position = nil
|
1210
|
+
* __cur_position = nil
|
1211
|
+
* end
|
1212
|
+
*/
|
1213
|
+
rb_define_method(cStructure, "__unset_dump_state", cStructure_unset_dump_state, 0);
|
1214
|
+
|
1215
|
+
/**
|
1216
|
+
* @overload __decode_expression(expression)
|
1217
|
+
* Decode the given expression in the context of the receiver.
|
1218
|
+
* @param expression [Proc,Object] the expression to decode
|
1219
|
+
* @return [Object] the decoded value
|
1220
|
+
* @note Do not overload, this is not called through the usual ruby dispatch for performance reasons
|
1221
|
+
* @example
|
1222
|
+
* # Original Ruby implementation
|
1223
|
+
* def __decode_expression(expression)
|
1224
|
+
* if expression.is_a?(Proc)
|
1225
|
+
* instance_exec &expression
|
1226
|
+
* else
|
1227
|
+
* expression
|
1228
|
+
* end
|
1229
|
+
* end
|
1230
|
+
*/
|
1231
|
+
rb_define_method(cStructure, "__decode_expression", cStructure_decode_expression, 1);
|
1232
|
+
/**
|
1233
|
+
* @overload __decode_expect(expect, value)
|
1234
|
+
* Decode the given expect expression, given the field value.
|
1235
|
+
* @param expect [Proc,Object,nil] the expression to decode
|
1236
|
+
* @param value [Object] the field value to validate
|
1237
|
+
* @return [Object] returns +value+ if validated. If expect is a Proc, the proc will be passed +value+
|
1238
|
+
* as an argument and be evaluated. If expect is a scalar, +expect+ and +value+ will be tested for equality.
|
1239
|
+
* If the result of the evaluation or the test is truthy, value is validate. Else an exception is raised.
|
1240
|
+
* @example
|
1241
|
+
* # Original Ruby implementation
|
1242
|
+
* def __decode_expect(expect, value)
|
1243
|
+
* return value if expect.nil?
|
1244
|
+
* if expect.is_a?(Proc)
|
1245
|
+
* raise "could not validate field value: #{value}" unless instance_exec(value, &expect)
|
1246
|
+
* else
|
1247
|
+
* raise "could not validate field value: #{value} expected: #{expect}" unless expect == value
|
1248
|
+
* end
|
1249
|
+
* return value
|
1250
|
+
* end
|
1251
|
+
*/
|
1252
|
+
rb_define_method(cStructure, "__decode_expect", cStructure_decode_expect, 2);
|
1253
|
+
/**
|
1254
|
+
* @overload __decode_seek_offset(offset, relative_offset, align)
|
1255
|
+
* Decode the offset and seek to this position in the active streams.
|
1256
|
+
* @param offset [Proc,Integer,nil] the expression to decode
|
1257
|
+
* @param relative_offset [Boolean] the offset should be relative to the structure base (+__position+)
|
1258
|
+
* @param align [false,Integer] the required alignement of the field
|
1259
|
+
* @return [nil,false,Integer] return nil if no offset was specified, an Integer if the active streams
|
1260
|
+
* had to seek, or false if a zero offset was computed.
|
1261
|
+
* @note Do not overload, this is not called through the usual ruby dispatch for performance reasons
|
1262
|
+
* @example
|
1263
|
+
* # Original Ruby implementation
|
1264
|
+
* def __decode_seek_offset(offset, relative_offset, align)
|
1265
|
+
* cur_pos = nil
|
1266
|
+
* if !offset
|
1267
|
+
* return nil unless align
|
1268
|
+
* cur_pos =
|
1269
|
+
* if __input
|
1270
|
+
* __input.tell
|
1271
|
+
* elsif __output
|
1272
|
+
* __output.tell
|
1273
|
+
* else
|
1274
|
+
* __cur_position
|
1275
|
+
* end
|
1276
|
+
* pad = cur_pos % align
|
1277
|
+
* return nil if pad == 0
|
1278
|
+
* cur_pos += align - pad
|
1279
|
+
* else
|
1280
|
+
* cur_pos = __decode_expression(offset)
|
1281
|
+
* return false if cur_pos == 0x0
|
1282
|
+
* cur_pos += __position if relative_offset
|
1283
|
+
* cur_pos += align - (cur_pos % align) if align && cur_pos % align > 0
|
1284
|
+
* end
|
1285
|
+
* __cur_position = cur_pos
|
1286
|
+
* __input.seek(cur_pos) if __input
|
1287
|
+
* __output.seek(cur_pos) if __output
|
1288
|
+
* cur_pos
|
1289
|
+
* end
|
1290
|
+
*/
|
1291
|
+
rb_define_method(cStructure, "__decode_seek_offset", cStructure_decode_seek_offset, 3);
|
1292
|
+
/**
|
1293
|
+
* @overload __decode_condition(condition)
|
1294
|
+
* Decode the condition expression
|
1295
|
+
* @param condition [Proc,Boolean,nil] the expression to decode
|
1296
|
+
* @return [Boolean] the field is active
|
1297
|
+
* @note Do not overload, this is not called through the usual ruby dispatch for performance reasons
|
1298
|
+
* @example
|
1299
|
+
* # Original Ruby implementation
|
1300
|
+
* def __decode_condition(condition)
|
1301
|
+
* return true unless condition
|
1302
|
+
* __decode_expression(condition)
|
1303
|
+
* end
|
1304
|
+
*/
|
1305
|
+
rb_define_method(cStructure, "__decode_condition", cStructure_decode_condition, 1);
|
1306
|
+
/**
|
1307
|
+
* @overload __decode_count(count)
|
1308
|
+
* Decode the count expression.
|
1309
|
+
* @param count [Proc,Integer,nil] the expression to decode
|
1310
|
+
* @return [Integer] 1 if +count+ is nil, the decoded count otherwise
|
1311
|
+
* @note Do not overload, this is not called through the usual ruby dispatch for performance reasons
|
1312
|
+
* @example
|
1313
|
+
* # Original Ruby implementation
|
1314
|
+
* def __decode_count(count)
|
1315
|
+
* return 1 unless count
|
1316
|
+
* __decode_expression(count)
|
1317
|
+
* end
|
1318
|
+
*/
|
1319
|
+
rb_define_method(cStructure, "__decode_count", cStructure_decode_count, 1);
|
1320
|
+
/**
|
1321
|
+
* @overload __decode_type(type)
|
1322
|
+
* Decode the type expression.
|
1323
|
+
* @param type [Proc,Class] the expression to decode
|
1324
|
+
* @return [Class] the decoded type
|
1325
|
+
* @note Do not overload, this is not called through the usual ruby dispatch for performance reasons
|
1326
|
+
* @example
|
1327
|
+
* # Original Ruby implementation
|
1328
|
+
* def __decode_type(type)
|
1329
|
+
* __decode_expression(type)
|
1330
|
+
* end
|
1331
|
+
*/
|
1332
|
+
rb_define_method(cStructure, "__decode_type", cStructure_decode_type, 1);
|
1333
|
+
/**
|
1334
|
+
* @overload __decode_length(length)
|
1335
|
+
* Decode the length expression.
|
1336
|
+
* @param length [Proc,Integer,nil] the expression to decode
|
1337
|
+
* @return [Integer,nil] nil if the field is not a vector, or the
|
1338
|
+
* length of the vector
|
1339
|
+
* @note Do not overload, this is not called through the usual ruby dispatch for performance reasons
|
1340
|
+
* @example
|
1341
|
+
* # Original Ruby implementation
|
1342
|
+
* def __decode_length(length)
|
1343
|
+
* __decode_expression(length)
|
1344
|
+
* end
|
1345
|
+
*/
|
1346
|
+
rb_define_method(cStructure, "__decode_length", cStructure_decode_length, 1);
|
1347
|
+
/**
|
1348
|
+
* @overload __decode_static_conditions(field)
|
1349
|
+
* Sets field specific context. Return nil if the field is inactive.
|
1350
|
+
* If the field is a sequence, only +__count+ is set, if not,
|
1351
|
+
* +__offset+, +__condition+, +__type+, and +__count+ are
|
1352
|
+
* also set.
|
1353
|
+
* @param field [Field] the field descriptor
|
1354
|
+
* @return [Integer,nil] nil if the field is inactive, the repetition count otherwise
|
1355
|
+
* @note Do not overload, this is not called through the usual ruby dispatch for performance reasons
|
1356
|
+
* @example
|
1357
|
+
* # Original Ruby implementation
|
1358
|
+
* def __decode_static_conditions(field)
|
1359
|
+
* __offset = nil
|
1360
|
+
* __condition = nil
|
1361
|
+
* __type = nil
|
1362
|
+
* __length = nil
|
1363
|
+
* __count = nil
|
1364
|
+
* unless field.sequence?
|
1365
|
+
* __offset = __decode_seek_offset(field.offset, field.relative_offset?, field.align)
|
1366
|
+
* return nil if __offset == false
|
1367
|
+
* __condition = __decode_condition(field.condition)
|
1368
|
+
* return nil unless __condition
|
1369
|
+
* __type = __decode_type(field.type)
|
1370
|
+
* __length = __decode_length(field.length)
|
1371
|
+
* end
|
1372
|
+
* __count = __decode_count(field.count)
|
1373
|
+
* end
|
1374
|
+
*/
|
1375
|
+
rb_define_method(cStructure, "__decode_static_conditions", cStructure_decode_static_conditions, 1);
|
1376
|
+
/**
|
1377
|
+
* @overload __decode_dynamic_conditions(field)
|
1378
|
+
* Sets field repetition specific context.
|
1379
|
+
* Namely +__offset+, +__condition+, +__type+, and +__length+
|
1380
|
+
* should be set if the field repetition is active.
|
1381
|
+
* @param field [Field] the field descriptor
|
1382
|
+
* @return [Boolean] field repetition is active
|
1383
|
+
* @note Do not overload, this is not called through the usual ruby dispatch for performance reasons.
|
1384
|
+
* @example
|
1385
|
+
* # Original Ruby implementation
|
1386
|
+
* def __decode_dynamic_conditions(field)
|
1387
|
+
* return true unless field.sequence?
|
1388
|
+
* __offset = nil
|
1389
|
+
* __condition = nil
|
1390
|
+
* __type = nil
|
1391
|
+
* __length = nil
|
1392
|
+
* __offset = __decode_seek_offset(field.offset, field.relative_offset?, field.align)
|
1393
|
+
* return false if __offset == false
|
1394
|
+
* __condition = __decode_condition(field.condition)
|
1395
|
+
* return false unless __condition
|
1396
|
+
* __type = __decode_type(field.type)
|
1397
|
+
* __length = __decode_length(field.length)
|
1398
|
+
* return true
|
1399
|
+
* end
|
1400
|
+
*/
|
1401
|
+
rb_define_method(cStructure, "__decode_dynamic_conditions", cStructure_decode_dynamic_conditions, 1);
|
1402
|
+
|
1403
|
+
/**
|
1404
|
+
* Restore the field specific context.
|
1405
|
+
* @return nil
|
1406
|
+
* @example
|
1407
|
+
* # Original Ruby implementation
|
1408
|
+
* def __restore_context
|
1409
|
+
* __iterator = nil
|
1410
|
+
* __type = nil
|
1411
|
+
* __length = nil
|
1412
|
+
* __count = nil
|
1413
|
+
* __offset = nil
|
1414
|
+
* __condition = nil
|
1415
|
+
* __value = nil
|
1416
|
+
* end
|
1417
|
+
*/
|
1418
|
+
rb_define_method(cStructure, "__restore_context", cStructure_restore_context, 0);
|
1419
|
+
|
1420
|
+
/**
|
1421
|
+
* @overload __convert_field(field)
|
1422
|
+
* Load and dump the value of a structure field.
|
1423
|
+
* @param field [Field] the field descriptor
|
1424
|
+
* @return the field value or nil if the field was inactive
|
1425
|
+
* @example
|
1426
|
+
* # Original Ruby implementation
|
1427
|
+
* def __convert_field(field)
|
1428
|
+
* return nil if __decode_static_conditions(field).nil?
|
1429
|
+
* vs = __count.times.collect do |it|
|
1430
|
+
* __iterator = it
|
1431
|
+
* if __decode_dynamic_conditions(field)
|
1432
|
+
* __value = __type::convert(__input, __output, __input_big, __output_big, self, it, __length)
|
1433
|
+
* __decode_expect(field.expect, __value)
|
1434
|
+
* else
|
1435
|
+
* nil
|
1436
|
+
* end
|
1437
|
+
* end
|
1438
|
+
* __restore_context
|
1439
|
+
* vs = vs.first unless field.count
|
1440
|
+
* vs
|
1441
|
+
* end
|
1442
|
+
*/
|
1443
|
+
rb_define_method(cStructure, "__convert_field", cStructure_convert_field, 1);
|
1444
|
+
/**
|
1445
|
+
* @overload __load_field(field)
|
1446
|
+
* Load the value of a structure field.
|
1447
|
+
* @param field [Field] the field descriptor
|
1448
|
+
* @return the field value or nil if the field was inactive
|
1449
|
+
* @example
|
1450
|
+
* # Original Ruby implementation
|
1451
|
+
* def __load_field(field)
|
1452
|
+
* return nil if __decode_static_conditions(field).nil?
|
1453
|
+
* vs = __count.times.collect do |it|
|
1454
|
+
* __iterator = it
|
1455
|
+
* if __decode_dynamic_conditions(field)
|
1456
|
+
* __value = __type::load(__input, __input_big, self, it, __length)
|
1457
|
+
* __decode_expect(field.expect, __value)
|
1458
|
+
* else
|
1459
|
+
* nil
|
1460
|
+
* end
|
1461
|
+
* end
|
1462
|
+
* __restore_context
|
1463
|
+
* vs = vs.first unless field.count
|
1464
|
+
* vs
|
1465
|
+
* end
|
1466
|
+
*/
|
1467
|
+
rb_define_method(cStructure, "__load_field", cStructure_load_field, 1);
|
1468
|
+
/**
|
1469
|
+
* @overload __dump_field(value, field)
|
1470
|
+
* Dump the value of a structure field.
|
1471
|
+
* @param value the field value
|
1472
|
+
* @param field [Field] the field descriptor
|
1473
|
+
* @return nil
|
1474
|
+
* @example
|
1475
|
+
* # Original Ruby implementation
|
1476
|
+
* def __dump_field(vs, field)
|
1477
|
+
* return nil if __decode_static_conditions(field).nil?
|
1478
|
+
* vs = [vs] unless field.count
|
1479
|
+
* __count.times do |it|
|
1480
|
+
* __iterator = it
|
1481
|
+
* if __decode_dynamic_conditions(field)
|
1482
|
+
* __value = vs[it]
|
1483
|
+
* __decode_expect(field.expect, __value)
|
1484
|
+
* __type::dump(__value, __output, __output_big, self, it, __length)
|
1485
|
+
* end
|
1486
|
+
* end
|
1487
|
+
* __restore_context
|
1488
|
+
* end
|
1489
|
+
*/
|
1490
|
+
rb_define_method(cStructure, "__dump_field", cStructure_dump_field, 2);
|
1491
|
+
/**
|
1492
|
+
* @overload __shape_field(value, kind, field)
|
1493
|
+
* Return the shape of the structure field.
|
1494
|
+
* @param value the field value
|
1495
|
+
* @param kind [Class] the class of the shape required
|
1496
|
+
* @param field [Field] the field descriptor
|
1497
|
+
* @return [nil,kind,Array<kind>] the field shape, or nil if the field was inactive
|
1498
|
+
* @example
|
1499
|
+
* # Original Ruby implementation
|
1500
|
+
* def __shape_field(vs, kind, field)
|
1501
|
+
* return nil if __decode_static_conditions(field).nil?
|
1502
|
+
* vs = [vs] unless field.count
|
1503
|
+
* vs = vs.each_with_index.collect do |v, it|
|
1504
|
+
* __iterator = it
|
1505
|
+
* if __decode_dynamic_conditions(field)
|
1506
|
+
* sh = __type::shape(v, __cur_position, self, it, kind, __length)
|
1507
|
+
* __cur_position = sh.last + 1 if sh.last && sh.last >= 0
|
1508
|
+
* sh
|
1509
|
+
* end
|
1510
|
+
* end
|
1511
|
+
* __restore_context
|
1512
|
+
* vs = field.count ? kind.new(vs) : vs.first
|
1513
|
+
* vs
|
1514
|
+
* end
|
1515
|
+
*/
|
1516
|
+
rb_define_method(cStructure, "__shape_field", cStructure_shape_field, 3);
|
1517
|
+
|
1518
|
+
/**
|
1519
|
+
* Load the fields of the structure. The load state must
|
1520
|
+
* have been set beforehand.
|
1521
|
+
* @return [Structure] self
|
1522
|
+
* @example
|
1523
|
+
* # Original Ruby implementation
|
1524
|
+
* def __load_fields
|
1525
|
+
* field = nil
|
1526
|
+
* begin
|
1527
|
+
* __fields.each { |field|
|
1528
|
+
* send("#{field.name}=", __load_field(field))
|
1529
|
+
* }
|
1530
|
+
* rescue
|
1531
|
+
* STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
|
1532
|
+
* raise
|
1533
|
+
* end
|
1534
|
+
* self
|
1535
|
+
* end
|
1536
|
+
*/
|
1537
|
+
rb_define_method(cStructure, "__load_fields", cStructure_load_fields, 0);
|
1538
|
+
/**
|
1539
|
+
* Dump the fields of the structure. The dump state must
|
1540
|
+
* have been set beforehand.
|
1541
|
+
* @return [Structure] self
|
1542
|
+
* @example
|
1543
|
+
* # Original Ruby implementation
|
1544
|
+
* def __dump_fields
|
1545
|
+
* field = nil
|
1546
|
+
* begin
|
1547
|
+
* __fields.each { |field|
|
1548
|
+
* __dump_field(send(field.name), field)
|
1549
|
+
* }
|
1550
|
+
* rescue
|
1551
|
+
* STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
|
1552
|
+
* raise
|
1553
|
+
* end
|
1554
|
+
* self
|
1555
|
+
* end
|
1556
|
+
*/
|
1557
|
+
rb_define_method(cStructure, "__dump_fields", cStructure_dump_fields, 0);
|
1558
|
+
/**
|
1559
|
+
* Convert the fields of the structure. The conversion
|
1560
|
+
* state must have been set beforehand.
|
1561
|
+
* @return [Structure] self
|
1562
|
+
* @example
|
1563
|
+
* # Original Ruby implementation
|
1564
|
+
* def __convert_fields
|
1565
|
+
* field = nil
|
1566
|
+
* begin
|
1567
|
+
* __fields.each { |field|
|
1568
|
+
* send("#{field.name}=", __convert_field(field))
|
1569
|
+
* }
|
1570
|
+
* rescue
|
1571
|
+
* STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
|
1572
|
+
* raise
|
1573
|
+
* end
|
1574
|
+
* self
|
1575
|
+
* end
|
1576
|
+
*/
|
1577
|
+
rb_define_method(cStructure, "__convert_fields", cStructure_convert_fields, 0);
|
1578
|
+
/**
|
1579
|
+
* @overload __shape_fields(kind)
|
1580
|
+
* Return the shape of the structure fields in a Hash, indexed by the fields' names.
|
1581
|
+
* The size state must have been set beforehand.
|
1582
|
+
* @param kind [Class] the kind of structure to create
|
1583
|
+
* @return [Hash{Symbol=>kind}] the fields shape
|
1584
|
+
* @example
|
1585
|
+
* # Original Ruby implementation
|
1586
|
+
* def __shape_fields(kind)
|
1587
|
+
* members = {}
|
1588
|
+
* field = nil
|
1589
|
+
* begin
|
1590
|
+
* __fields.each { |field|
|
1591
|
+
* members[field.name] = __shape_field(send(field.name), kind, field)
|
1592
|
+
* }
|
1593
|
+
* rescue
|
1594
|
+
* LibBin.output.puts "#{self.class}: #{field.name}(#{field.type})" if LibBin.output
|
1595
|
+
* raise
|
1596
|
+
* end
|
1597
|
+
* return members
|
1598
|
+
* end
|
1599
|
+
*/
|
1600
|
+
rb_define_method(cStructure, "__shape_fields", cStructure_shape_fields, 1);
|
1601
|
+
|
1602
|
+
/**
|
1603
|
+
* @overload __load(input, input_big, parent = nil, index = nil)
|
1604
|
+
* Fill in the structure by loading it from +input+.
|
1605
|
+
* @param input [IO] the stream to load the structure from
|
1606
|
+
* @param input_big [Boolean] the endianness of +input+
|
1607
|
+
* @param parent [Structure] if given, the parent of the structure
|
1608
|
+
* @param index [Integer] if given, the structure is repeated and +index+ is the rank this structure
|
1609
|
+
* @return [Structure] self
|
1610
|
+
* @example
|
1611
|
+
* # Original Ruby implementation
|
1612
|
+
* def __load(input, input_big, parent = nil, index = nil)
|
1613
|
+
* __set_load_state(input, input_big, parent, index)
|
1614
|
+
* __load_fields
|
1615
|
+
* __unset_load_state
|
1616
|
+
* self
|
1617
|
+
* end
|
1618
|
+
*/
|
1619
|
+
rb_define_method(cStructure, "__load", cStructure_load, -1);
|
1620
|
+
/**
|
1621
|
+
* @overload __dump(output, output_big, parent = nil, index = nil)
|
1622
|
+
* Dump the structure to +output+.
|
1623
|
+
* @param output [IO] the stream to dump the structure to
|
1624
|
+
* @param output_big [Boolean] the endianness of +output+
|
1625
|
+
* @param parent [Structure] if given, the parent of the structure
|
1626
|
+
* @param index [Integer] if given, the structure is repeated and +index+ is the rank this structure
|
1627
|
+
* @return [Structure] self
|
1628
|
+
* @example
|
1629
|
+
* # Original Ruby implementation
|
1630
|
+
* def __dump(output, output_big, parent = nil, index = nil)
|
1631
|
+
* __set_dump_state(output, output_big, parent, index)
|
1632
|
+
* __dump_fields
|
1633
|
+
* __unset_dump_state
|
1634
|
+
* self
|
1635
|
+
* end
|
1636
|
+
*/
|
1637
|
+
rb_define_method(cStructure, "__dump", cStructure_dump, -1);
|
1638
|
+
/**
|
1639
|
+
* @overload __convert(input, output, input_big, output_big, parent = nil, index = nil)
|
1640
|
+
* Fill in the structure by loading it from +input+ and
|
1641
|
+
* dumping it to +output+.
|
1642
|
+
* @param input [IO] the stream to load the structure from
|
1643
|
+
* @param output [IO] the stream to dump the structure to
|
1644
|
+
* @param input_big [Boolean] the endianness of +input+
|
1645
|
+
* @param output_big [Boolean] the endianness of +output+
|
1646
|
+
* @param parent [Structure] if given, the parent of the structure
|
1647
|
+
* @param index [Integer] if given, the structure is repeated and +index+ is the rank this structure
|
1648
|
+
* @return [Structure] self
|
1649
|
+
* @example
|
1650
|
+
* # Original Ruby implementation
|
1651
|
+
* def __convert(input, output, input_big, output_big, parent = nil, index = nil)
|
1652
|
+
* __set_convert_state(input, output, input_big, output_big, parent, index)
|
1653
|
+
* __convert_fields
|
1654
|
+
* __unset_convert_state
|
1655
|
+
* self
|
1656
|
+
* end
|
1657
|
+
*/
|
1658
|
+
rb_define_method(cStructure, "__convert", cStructure_convert, -1);
|
1659
|
+
/**
|
1660
|
+
* @overload __shape(offset = 0, parent = nil, index = nil, kind = DataShape)
|
1661
|
+
* Return the shape of the structure.
|
1662
|
+
* @param offset [Integer] the base position of the field
|
1663
|
+
* @param parent [Structure] if given, the parent of the structure
|
1664
|
+
* @param index [Integer] if given, the structure is repeated and +index+ is the rank this structure
|
1665
|
+
* @param kind [Class] the kind of structure to create
|
1666
|
+
* @return [kind] the the shape of the structure
|
1667
|
+
* @example
|
1668
|
+
* # Original Ruby implementation
|
1669
|
+
* def __shape(previous_offset = 0, parent = nil, index = nil, kind = DataShape)
|
1670
|
+
* __set_size_state(previous_offset, parent, index)
|
1671
|
+
* members = __shape_fields(kind)
|
1672
|
+
* __unset_size_state
|
1673
|
+
* return nil if members.values.compact.size <= 0
|
1674
|
+
* kind::new(members)
|
1675
|
+
* end
|
1676
|
+
*/
|
1677
|
+
rb_define_method(cStructure, "__shape", cStructure_shape, -1);
|
1678
|
+
|
1679
|
+
/**
|
1680
|
+
* @overload load(input, input_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
|
1681
|
+
* Load a structure from +input+.
|
1682
|
+
* @param input [IO] the stream to load the structure from
|
1683
|
+
* @param input_big [Boolean] the endianness of +input+
|
1684
|
+
* @param parent [Structure] if given, the parent of the structure
|
1685
|
+
* @param index [Integer] if given, the structure is repeated and +index+ is the rank this structure
|
1686
|
+
* @param length [Integer] if given, the length of the vector of structure
|
1687
|
+
* @return [Structure,Array<Structure>] a new strcuture, or
|
1688
|
+
* an array of structures if length was specified
|
1689
|
+
* @example
|
1690
|
+
* # Original Ruby implementation
|
1691
|
+
* def self.load(input, input_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
|
1692
|
+
* if length
|
1693
|
+
* length.times.collect {
|
1694
|
+
* self.new.__load(input, input_big, parent, index)
|
1695
|
+
* }
|
1696
|
+
* else
|
1697
|
+
* self.new.__load(input, input_big, parent, index)
|
1698
|
+
* end
|
1699
|
+
* end
|
1700
|
+
*/
|
1701
|
+
rb_define_singleton_method(cStructure, "load", cStructure_singl_load, -1);
|
1702
|
+
/**
|
1703
|
+
* @overload dump(value, output, output_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
|
1704
|
+
* Dump a structure to +output+.
|
1705
|
+
* @param value [Structure,Array<Structure>] the value of structure to dump
|
1706
|
+
* @param output [IO] the stream to dump the structure to
|
1707
|
+
* @param output_big [Boolean] the endianness of +output+
|
1708
|
+
* @param parent [Structure] if given, the parent of the structure
|
1709
|
+
* @param index [Integer] if given, the structure is repeated and +index+ is the rank this structure
|
1710
|
+
* @param length [Integer] if given, the length of the vector of structure
|
1711
|
+
* @return [Structure,Array<Structure>] +value+
|
1712
|
+
* @example
|
1713
|
+
* # Original Ruby implementation
|
1714
|
+
* def self.dump(value, output, output_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
|
1715
|
+
* if length
|
1716
|
+
* length.times.each { |i|
|
1717
|
+
* value[i].__dump(output, output_big, parent, index)
|
1718
|
+
* }
|
1719
|
+
* value
|
1720
|
+
* else
|
1721
|
+
* value.__dump(output, output_big, parent, index)
|
1722
|
+
* end
|
1723
|
+
* end */
|
1724
|
+
rb_define_singleton_method(cStructure, "dump", cStructure_singl_dump, -1);
|
1725
|
+
/**
|
1726
|
+
* @overload convert(input, output, input_big = LibBin::default_big?, output_big = !input_big, parent = nil, index = nil, length = nil)
|
1727
|
+
* Convert a structure by loading it from +input+ and
|
1728
|
+
* dumping it to +output+. Returns the loaded structure.
|
1729
|
+
* @param input [IO] the stream to load the structure from
|
1730
|
+
* @param output [IO] the stream to dump the structure to
|
1731
|
+
* @param input_big [Boolean] the endianness of +input+
|
1732
|
+
* @param output_big [Boolean] the endianness of +output+
|
1733
|
+
* @param parent [Structure] if given, the parent of the structure
|
1734
|
+
* @param index [Integer] if given, the structure is repeated and +index+ is the rank this structure
|
1735
|
+
* @param length [Integer] if given, the length of the vector of structure
|
1736
|
+
* @return [Structure,Array<Structure>] a new strcuture, or
|
1737
|
+
* an array of structures if length was specified
|
1738
|
+
* @example
|
1739
|
+
* # Original Ruby implementation
|
1740
|
+
* def self.convert(input, output, input_big = LibBin::default_big?, output_big = !input_big, parent = nil, index = nil, length = nil)
|
1741
|
+
* if length
|
1742
|
+
* length.times.collect {
|
1743
|
+
* self.new.__convert(input, output, input_big, output_big, parent, index)
|
1744
|
+
* }
|
1745
|
+
* else
|
1746
|
+
* self.new.__convert(input, output, input_big, output_big, parent, index)
|
1747
|
+
* end
|
1748
|
+
* end
|
1749
|
+
*/
|
1750
|
+
rb_define_singleton_method(cStructure, "convert", cStructure_singl_convert, -1);
|
1751
|
+
/**
|
1752
|
+
* @overload shape(value, offset = 0, parent = nil, index = nil, kind = DataShape, length = nil)
|
1753
|
+
* Return the shape of the value.
|
1754
|
+
* @param value [Structure,Array<Structure>] the value of structure to get the shape of
|
1755
|
+
* @param offset [Integer] the base position of the field
|
1756
|
+
* @param parent [Structure] if given, the parent of the structure
|
1757
|
+
* @param index [Integer] if given, the structure is repeated and +index+ is the rank this structure
|
1758
|
+
* @param kind [Class] the kind of structure to create
|
1759
|
+
* @param length [Integer] if given, the length of the vector of structure
|
1760
|
+
* @return [kind] the the shape of the structure
|
1761
|
+
* @example
|
1762
|
+
* # Original Ruby implementation
|
1763
|
+
* def self.shape(value, previous_offset = 0, parent = nil, index = nil, kind = DataShape, length = nil)
|
1764
|
+
* if length
|
1765
|
+
* kind.new(length.times.collect { |i|
|
1766
|
+
* value[i].__shape(previous_offset, parent, index, kind)
|
1767
|
+
* })
|
1768
|
+
* else
|
1769
|
+
* value.__shape(previous_offset, parent, index, kind)
|
1770
|
+
* end
|
1771
|
+
* end
|
1772
|
+
*/
|
1773
|
+
rb_define_singleton_method(cStructure, "shape", cStructure_singl_shape, -1);
|
1412
1774
|
}
|
1413
1775
|
|
1414
1776
|
static VALUE pghalf_from_string_p(VALUE self, VALUE str, VALUE pack_str) {
|
@@ -1461,14 +1823,118 @@ static VALUE half_to_string_p(VALUE self, VALUE number, VALUE pack_str) {
|
|
1461
1823
|
return rb_funcall(arr, rb_intern("pack"), 1, pack_str);
|
1462
1824
|
}
|
1463
1825
|
|
1826
|
+
static void define_cField() {
|
1827
|
+
id_gsub = rb_intern("gsub");
|
1828
|
+
|
1829
|
+
rb_str_dot_dot = rb_obj_freeze(rb_str_new_cstr(".."));
|
1830
|
+
rb_gc_register_mark_object(rb_str_dot_dot);
|
1831
|
+
rb_str___parent = rb_obj_freeze(rb_str_new_cstr("__parent"));
|
1832
|
+
rb_gc_register_mark_object(rb_str___parent);
|
1833
|
+
rb_str_backslash = rb_obj_freeze(rb_str_new_cstr("\\"));
|
1834
|
+
rb_gc_register_mark_object(rb_str_backslash);
|
1835
|
+
rb_str_dot = rb_obj_freeze(rb_str_new_cstr("."));
|
1836
|
+
rb_gc_register_mark_object(rb_str_dot);
|
1837
|
+
|
1838
|
+
cField = rb_define_class_under(cStructure, "Field", rb_cObject);
|
1839
|
+
rb_define_alloc_func(cField, cField_alloc);
|
1840
|
+
/**
|
1841
|
+
* @overload initialize(name, type, length, count, offset, sequence, condition, relative_offset, align, expect)
|
1842
|
+
* @param name [Symbol, String] the name of the field.
|
1843
|
+
* @param type [Class, String, Proc] the type of the field, as a Class, or
|
1844
|
+
* as a String or Proc that will be evaluated in the context of the
|
1845
|
+
* {Structure} instance.
|
1846
|
+
* @param length [nil, Integer, String, Proc] if given, consider the field a
|
1847
|
+
* vector of the type. The length is either a constant Integer of a
|
1848
|
+
* String or Proc that will be evaluated in the context of the
|
1849
|
+
* {Structure} instance.
|
1850
|
+
* @param count [nil, Integer, String, Proc] if given, consider the field is
|
1851
|
+
* repeated count times. The count is either a constant Integer of a
|
1852
|
+
* String or Proc that will be evaluated in the context of the
|
1853
|
+
* {Structure} instance.
|
1854
|
+
* @param offset [nil, integer, String, Proc] if given, the absolute offset in
|
1855
|
+
* the file, or the offset from the parent position, where the field can
|
1856
|
+
* be found. See relative offset. The offset is either a constant
|
1857
|
+
* Integer of a String or Proc that will be evaluated in the context
|
1858
|
+
* of the {Structure} instance.
|
1859
|
+
* @param sequence [Boolean] if true, +type+, +length+, +offset+, and
|
1860
|
+
* +condition+ are evaluated for each repetition.
|
1861
|
+
* @param condition [nil, String, Proc] if given, the field, or repetition of the
|
1862
|
+
* field can be conditionally present. The condition will be evaluated in
|
1863
|
+
* the context of the {Structure} instance.
|
1864
|
+
* @param relative_offset [Boolean] consider the +offset+ relative to
|
1865
|
+
* the field +parent+.
|
1866
|
+
* @param align [nil, Integer] if given, align the field. If given as an
|
1867
|
+
* Integer it must be a power of 2. Else the field is aligned to the
|
1868
|
+
* field's type preferred alignment
|
1869
|
+
* @param expect [nil, Proc, Object] if given as a Proc the proc must
|
1870
|
+
* evaluate to a truthy value or an exception will be raised. Else, the
|
1871
|
+
* object will be tested for equality, and an exception will be raised if
|
1872
|
+
* objects were not equal. Proc is evaluated in the context of the {Structure}
|
1873
|
+
* instance and #__value will be set. Each repetition is validated.
|
1874
|
+
* @return [Field] new Field
|
1875
|
+
*/
|
1876
|
+
rb_define_method(cField, "initialize", cField_initialize, 10);
|
1877
|
+
DEFINE_FIELD_STATE_GETTER(name);
|
1878
|
+
DEFINE_FIELD_STATE_GETTER(type);
|
1879
|
+
DEFINE_FIELD_STATE_GETTER(length);
|
1880
|
+
DEFINE_FIELD_STATE_GETTER(count);
|
1881
|
+
DEFINE_FIELD_STATE_GETTER(offset);
|
1882
|
+
DEFINE_FIELD_STATE_GETTER_BOOL(sequence);
|
1883
|
+
DEFINE_FIELD_STATE_GETTER(condition);
|
1884
|
+
DEFINE_FIELD_STATE_GETTER_BOOL(relative_offset);
|
1885
|
+
DEFINE_FIELD_STATE_GETTER(align);
|
1886
|
+
DEFINE_FIELD_STATE_GETTER(expect);
|
1887
|
+
}
|
1888
|
+
|
1464
1889
|
void Init_libbin_c() {
|
1465
1890
|
mLibBin = rb_define_module("LibBin");
|
1891
|
+
/**
|
1892
|
+
* @overload half_from_string(str, unpack_str)
|
1893
|
+
* Load (unpacks) a half precision floating point.
|
1894
|
+
* @param str [String] the strin to read the number from
|
1895
|
+
* @param unpack_str [String] the unpack format of the underlying 16bit integer
|
1896
|
+
* @return [Float] the ruby representation of the value
|
1897
|
+
* @example
|
1898
|
+
* # Read a half precision floating point value stored in 'str' in little endian fashion
|
1899
|
+
* value = half_from_string(str, "S<")
|
1900
|
+
*/
|
1466
1901
|
rb_define_module_function(mLibBin, "half_from_string", half_from_string_p, 2);
|
1902
|
+
/**
|
1903
|
+
* @overload half_to_string(value, pack_str)
|
1904
|
+
* Convert a Numeric value to a half precision floating point and pack it into a string.
|
1905
|
+
* @param value [Numeric] the number to convert
|
1906
|
+
* @param pack_str [String] the pack format to store the underlying 16 bit integer representation of the value
|
1907
|
+
* @return [String] the packed half precision value
|
1908
|
+
* @example
|
1909
|
+
* # Stores a number as a half precision floating point value in a big endian fashion
|
1910
|
+
* str = half_to_string(value, "S>")
|
1911
|
+
*/
|
1467
1912
|
rb_define_module_function(mLibBin, "half_to_string", half_to_string_p, 2);
|
1913
|
+
/**
|
1914
|
+
* @overload pghalf_from_string(str, unpack_str)
|
1915
|
+
* Load (unpacks) a half precision floating point as used by PlatinumGames in some formats.
|
1916
|
+
* @param str [String] the strin to read the number from
|
1917
|
+
* @param unpack_str [String] the unpack format of the underlying 16bit integer
|
1918
|
+
* @return [Float] the ruby representation of the value
|
1919
|
+
* @example
|
1920
|
+
* # Read a half precision floating point value stored in 'str' in little endian fashion
|
1921
|
+
* half_from_string(str, "S<")
|
1922
|
+
*/
|
1468
1923
|
rb_define_module_function(mLibBin, "pghalf_from_string", pghalf_from_string_p, 2);
|
1924
|
+
/**
|
1925
|
+
* @overload pghalf_to_string(value, pack_str)
|
1926
|
+
* Convert a Numeric value to a half precision floating point as used by PlatinumGames in some formats, and pack it into a string.
|
1927
|
+
* @param value [Numeric] the number to convert
|
1928
|
+
* @param pack_str [String] the pack format to store the underlying 16 bit integer representation of the value
|
1929
|
+
* @return [String] the packed half precision value
|
1930
|
+
* @example
|
1931
|
+
* # Stores a number as a half precision floating point value in a big endian fashion
|
1932
|
+
* str = half_to_string(value, "S>")
|
1933
|
+
*/
|
1469
1934
|
rb_define_module_function(mLibBin, "pghalf_to_string", pghalf_to_string_p, 2);
|
1470
|
-
|
1935
|
+
cDataRange = rb_define_class_under(mLibBin, "DataRange", rb_cObject);
|
1936
|
+
cDataShape = rb_define_class_under(mLibBin, "DataShape", cDataRange);
|
1937
|
+
define_cStructure();
|
1471
1938
|
define_cField();
|
1472
|
-
define_cDataConverter();
|
1473
1939
|
define_cScalar();
|
1474
1940
|
}
|