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.
@@ -3,7 +3,7 @@
3
3
 
4
4
  VALUE cField;
5
5
  VALUE mLibBin;
6
- VALUE cDataConverter;
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
- static VALUE cField_name(VALUE self) {
94
- struct cField_data *data;
95
- TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
96
- return data->name;
97
- }
104
+ #define FIELD_STATE_GETTER(propname) cField_get_ ## propname
98
105
 
99
- static VALUE cField_get_type(VALUE self) {
100
- struct cField_data *data;
101
- TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
102
- return data->type;
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
- static VALUE cField_length(VALUE self) {
106
- struct cField_data *data;
107
- TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
108
- return data->length;
109
- }
113
+ #define DEFINE_FIELD_STATE_GETTER(propname) \
114
+ rb_define_method(cField, #propname, FIELD_STATE_GETTER(propname), 0)
110
115
 
111
- static VALUE cField_count(VALUE self) {
112
- struct cField_data *data;
113
- TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
114
- return data->count;
115
- }
116
+ #define DEFINE_FIELD_STATE_GETTER_BOOL(propname) \
117
+ rb_define_method(cField, #propname "?", FIELD_STATE_GETTER(propname), 0)
116
118
 
117
- static VALUE cField_offset(VALUE self) {
118
- struct cField_data *data;
119
- TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
120
- return data->offset;
121
- }
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
- static VALUE cField_sequence(VALUE self) {
124
- struct cField_data *data;
125
- TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
126
- return data->sequence;
127
- }
128
-
129
- static VALUE cField_condition(VALUE self) {
130
- struct cField_data *data;
131
- TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
132
- return data->condition;
133
- }
134
-
135
- static VALUE cField_relative_offset(VALUE self) {
136
- struct cField_data *data;
137
- TypedData_Get_Struct(self, struct cField_data, &cField_type, data);
138
- return data->relative_offset;
139
- }
140
-
141
- static void define_cField() {
142
- VALUE ary = rb_ary_new_capa(4);
143
- id_gsub = rb_intern("gsub");
144
-
145
- rb_str_dot_dot = rb_str_new_cstr("..");
146
- rb_ary_store(ary, 0, rb_str_dot_dot);
147
- rb_str___parent = rb_str_new_cstr("__parent");
148
- rb_ary_store(ary, 1, rb_str___parent);
149
- rb_str_backslash = rb_str_new_cstr("\\");
150
- rb_ary_store(ary, 2, rb_str_backslash);
151
- rb_str_dot = rb_str_new_cstr(".");
152
- rb_ary_store(ary, 3, rb_str_dot);
153
-
154
- cField = rb_define_class_under(mLibBin, "Field", rb_cObject);
155
- rb_define_alloc_func(cField, cField_alloc);
156
- rb_const_set(cField, rb_intern("STRINGS"), ary);
157
- rb_define_method(cField, "initialize", cField_initialize, 8);
158
- rb_define_method(cField, "name", cField_name, 0);
159
- rb_define_method(cField, "type", cField_get_type, 0);
160
- rb_define_method(cField, "length", cField_length, 0);
161
- rb_define_method(cField, "count", cField_count, 0);
162
- rb_define_method(cField, "offset", cField_offset, 0);
163
- rb_define_method(cField, "sequence", cField_sequence, 0);
164
- rb_define_method(cField, "sequence?", cField_sequence, 0);
165
- rb_define_method(cField, "condition", cField_condition, 0);
166
- rb_define_method(cField, "relative_offset?", cField_relative_offset, 0);
167
- }
168
-
169
- struct cDataConverter_data {
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 cDataConverter_mark(void* data) {
149
+ static void cStructure_mark(void* data) {
188
150
  void *start = data;
189
- void *end = (char *)data + sizeof(struct cDataConverter_data);
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 cDataConverter_size(const void* data) {
155
+ static size_t cStructure_size(const void* data) {
194
156
  (void)data;
195
- return sizeof(struct cDataConverter_data);
157
+ return sizeof(struct cStructure_data);
196
158
  }
197
159
 
198
- static const rb_data_type_t cDataConverter_type = {
199
- .wrap_struct_name = "cDataConverter_data",
160
+ static const rb_data_type_t cStructure_type = {
161
+ .wrap_struct_name = "cStructure_data",
200
162
  .function = {
201
- .dmark = cDataConverter_mark,
163
+ .dmark = cStructure_mark,
202
164
  .dfree = RUBY_DEFAULT_FREE,
203
- .dsize = cDataConverter_size,
165
+ .dsize = cStructure_size,
204
166
  },
205
167
  .data = NULL,
206
168
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
207
169
  };
208
170
 
209
- static VALUE cDataConverter_alloc(VALUE self) {
210
- struct cDataConverter_data *data;
211
- VALUE res = TypedData_Make_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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 cDataConverter_initialize(VALUE self) {
216
- struct cDataConverter_data *data;
217
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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
- /* attr_reader :__parent
236
- attr_reader :__index
237
- attr_reader :__iterator
238
- attr_reader :__position */
239
-
240
- static VALUE cDataConverter_parent(VALUE self) {
241
- struct cDataConverter_data *data;
242
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
243
- return data->__parent;
244
- }
245
-
246
- static VALUE cDataConverter_index(VALUE self) {
247
- struct cDataConverter_data *data;
248
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
249
- return data->__index;
250
- }
251
-
252
- static VALUE cDataConverter_iterator(VALUE self) {
253
- struct cDataConverter_data *data;
254
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
255
- return data->__iterator;
256
- }
257
-
258
- static VALUE cDataConverter_position(VALUE self) {
259
- struct cDataConverter_data *data;
260
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
261
- return data->__position;
262
- }
263
-
264
- /* attr_reader :__input
265
- attr_reader :__output
266
- attr_reader :__input_big
267
- attr_reader :__output_big */
268
-
269
- static VALUE cDataConverter_input(VALUE self) {
270
- struct cDataConverter_data *data;
271
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
272
- return data->__input;
273
- }
274
-
275
- static VALUE cDataConverter_output(VALUE self) {
276
- struct cDataConverter_data *data;
277
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
278
- return data->__output;
279
- }
280
-
281
- static VALUE cDataConverter_input_big(VALUE self) {
282
- struct cDataConverter_data *data;
283
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
284
- return data->__input_big;
285
- }
286
-
287
- static VALUE cDataConverter_output_big(VALUE self) {
288
- struct cDataConverter_data *data;
289
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
290
- return data->__output_big;
291
- }
292
-
293
- ID id_tell;
294
-
295
- /* def __set_convert_type(input, output, input_big, output_big, parent, index)
296
- @__input_big = input_big
297
- @__output_big = output_big
298
- @__input = input
299
- @__output = output
300
- @__parent = parent
301
- @__index = index
302
- @__position = input.tell
303
- @__cur_position = @__position
304
- end */
305
-
306
- static inline VALUE cDataConverter_set_convert_type(
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 cDataConverter_data *data;
316
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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
- /* def __unset_convert_type
329
- @__input_big = nil
330
- @__output_big = nil
331
- @__input = nil
332
- @__output = nil
333
- @__parent = nil
334
- @__index = nil
335
- @__position = nil
336
- @__cur_position = nil
337
- end */
338
-
339
- static inline VALUE cDataConverter_unset_convert_type(VALUE self) {
340
- struct cDataConverter_data *data;
341
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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
- /* def __set_size_type(position, parent, index)
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 inline VALUE cDataConverter_set_size_type(
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 cDataConverter_data *data;
367
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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
- /* def __unset_size_type
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 inline VALUE cDataConverter_unset_size_type(VALUE self) {
383
- struct cDataConverter_data *data;
384
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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
- /* def __set_load_type(input, input_big, parent, index)
393
- @__input_big = input_big
394
- @__input = input
395
- @__parent = parent
396
- @__index = index
397
- @__position = input.tell
398
- @__cur_position = @__position
399
- end */
306
+ static ID id___set_load_state;
400
307
 
401
- static inline VALUE cDataConverter_set_load_type(
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 cDataConverter_data *data;
409
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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
- /* def __unset_load_type
420
- @__input_big = nil
421
- @__input = nil
422
- @__parent = nil
423
- @__index = nil
424
- @__position = nil
425
- @__cur_position = nil
426
- end */
427
-
428
- static inline VALUE cDataConverter_unset_load_type(VALUE self) {
429
- struct cDataConverter_data *data;
430
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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
- /* def __set_dump_type(output, output_big, parent, index)
441
- @__output_big = output_big
442
- @__output = output
443
- @__parent = parent
444
- @__index = index
445
- @__position = output.tell
446
- @__cur_position = @__position
447
- end */
340
+ static ID id___set_dump_state;
448
341
 
449
- static inline VALUE cDataConverter_set_dump_type(
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 cDataConverter_data *data;
457
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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
- /* def __unset_dump_type
468
- @__output_big = nil
469
- @__output = nil
470
- @__parent = nil
471
- @__index = nil
472
- @__position = nil
473
- @__cur_position = nil
474
- end */
475
-
476
- static inline VALUE cDataConverter_unset_dump_type(VALUE self) {
477
- struct cDataConverter_data *data;
478
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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 cDataConverter_decode_expression(VALUE self, VALUE expression) {
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
- /* def __decode_seek_offset(offset, relative_offset)
507
- return nil unless offset
508
- offset = __decode_expression(offset)
509
- return false if offset == 0x0
510
- offset += @__position if relative_offset
511
- @__cur_position = offset
512
- @__input.seek(offset) if @__input
513
- @__output.seek(offset) if @__output
514
- offset
515
- end */
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 cDataConverter_decode_seek_offset(VALUE self, VALUE offset, VALUE relative_offset) {
520
- struct cDataConverter_data *data;
521
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
522
- if (!RTEST(offset))
523
- return Qnil;
524
- ptrdiff_t off = NUM2LL(cDataConverter_decode_expression(self, offset));
525
- if (off == 0)
526
- return Qfalse;
527
- if (RTEST(relative_offset))
528
- off += NUM2LL(data->__position);
529
- data->__cur_position = LL2NUM(off);
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
- /* def __decode_condition(condition)
538
- return true unless condition
539
- __decode_expression(condition)
540
- end */
541
-
542
- static inline VALUE cDataConverter_decode_condition(VALUE self, VALUE condition) {
434
+ static inline VALUE cStructure_decode_condition(VALUE self, VALUE condition) {
543
435
  if (!RTEST(condition))
544
436
  return Qtrue;
545
- return cDataConverter_decode_expression(self, condition);
437
+ return cStructure_decode_expression(self, condition);
546
438
  }
547
439
 
548
- /* def __decode_count(count)
549
- return 1 unless count
550
- __decode_expression(count)
551
- end */
552
-
553
- static inline VALUE cDataConverter_decode_count(VALUE self, VALUE count) {
440
+ static inline VALUE cStructure_decode_count(VALUE self, VALUE count) {
554
441
  if (!RTEST(count))
555
442
  return INT2FIX(1);
556
- return cDataConverter_decode_expression(self, count);
443
+ return cStructure_decode_expression(self, count);
557
444
  }
558
445
 
559
- /* def __decode_type(type)
560
- __decode_expression(type)
561
- end */
562
-
563
- static inline VALUE cDataConverter_decode_type(VALUE self, VALUE type) {
564
- return cDataConverter_decode_expression(self, type);
446
+ static inline VALUE cStructure_decode_type(VALUE self, VALUE type) {
447
+ return cStructure_decode_expression(self, type);
565
448
  }
566
449
 
567
- /* def __decode_length(length)
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 cDataConverter_decode_expression(self, length);
453
+ return cStructure_decode_expression(self, length);
575
454
  }
576
455
 
577
- /* def __decode_static_conditions(field)
578
- @__offset = nil
579
- @__condition = nil
580
- @__type = nil
581
- @__length = nil
582
- @__count = nil
583
- unless field.sequence?
584
- @__offset = __decode_seek_offset(field.offset, field.relative_offset?)
585
- throw :ignored, nil if @__offset == false
586
- @__condition = __decode_condition(field.condition)
587
- throw :ignored, nil unless @__condition
588
- @__type = __decode_type(field.type)
589
- @__length = __decode_length(field.length)
590
- end
591
- @__count = __decode_count(field.count)
592
- end */
593
-
594
- static inline VALUE cDataConverter_decode_static_conditions(VALUE self, VALUE field) {
595
- struct cDataConverter_data *data;
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 cDataConverter_data, &cDataConverter_type, data);
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 = cDataConverter_decode_seek_offset(self, field_data->offset, field_data->relative_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 = cDataConverter_decode_condition(self, field_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 = cDataConverter_decode_type(self, field_data->type);
612
- data->__length = cDataConverter_decode_length(self, field_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 = cDataConverter_decode_count(self, field_data->count);
476
+ data->__count = cStructure_decode_count(self, field_data->count);
615
477
  return Qtrue;
616
478
  }
617
479
 
618
- /* def __decode_dynamic_conditions(field)
619
- return true unless field.sequence?
620
- @__offset = nil
621
- @__condition = nil
622
- @__type = nil
623
- @__length = nil
624
- @__offset = __decode_seek_offset(field.offset, field.relative_offset?)
625
- return false if @__offset == false
626
- @__condition = __decode_condition(field.condition)
627
- return false unless @__condition
628
- @__type = __decode_type(field.type)
629
- @__length = __decode_length(field.length)
630
- return true
631
- end */
632
-
633
- static inline VALUE cDataConverter_decode_dynamic_conditions(VALUE self, VALUE field) {
634
- struct cDataConverter_data *data;
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 cDataConverter_data, &cDataConverter_type, data);
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 = cDataConverter_decode_seek_offset(self, field_data->offset, field_data->relative_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 = cDataConverter_decode_condition(self, field_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 = cDataConverter_decode_type(self, field_data->type);
651
- data->__length = cDataConverter_decode_length(self, field_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
- /* def __restore_context
656
- @__iterator = nil
657
- @__type = nil
658
- @__length = nil
659
- @__count = nil
660
- @__offset = nil
661
- @__condition = nil
662
- end */
663
-
664
- static inline VALUE cDataConverter_restore_context(VALUE self) {
665
- struct cDataConverter_data *data;
666
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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 cDataConverter_convert_field(VALUE self, VALUE field) {
518
+ static inline VALUE cStructure_convert_field(VALUE self, VALUE field) {
694
519
  VALUE res;
695
- struct cDataConverter_data *data;
520
+ struct cStructure_data *data;
696
521
  struct cField_data *field_data;
697
- if (NIL_P(cDataConverter_decode_static_conditions(self, field)))
522
+ if (NIL_P(cStructure_decode_static_conditions(self, field)))
698
523
  return Qnil;
699
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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(cDataConverter_decode_dynamic_conditions(self, field)))
709
- rb_ary_store(res, i, rb_funcall(data->__type, id_convert, 7,
710
- data->__input,
711
- data->__output,
712
- data->__input_big,
713
- data->__output_big,
714
- self,
715
- data->__iterator,
716
- data->__length));
717
- else
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(cDataConverter_decode_dynamic_conditions(self, field)))
723
- res = rb_funcall(data->__type, id_convert, 7,
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
- else
558
+ res = cStructure_decode_expect(self, field_data->expect, data->__value);
559
+ } else
732
560
  res = Qnil;
733
561
  }
734
562
 
735
- cDataConverter_restore_context(self);
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 cDataConverter_load_field(VALUE self, VALUE field) {
570
+ static inline VALUE cStructure_load_field(VALUE self, VALUE field) {
757
571
  VALUE res;
758
- struct cDataConverter_data *data;
572
+ struct cStructure_data *data;
759
573
  struct cField_data *field_data;
760
- if (NIL_P(cDataConverter_decode_static_conditions(self, field)))
574
+ if (NIL_P(cStructure_decode_static_conditions(self, field)))
761
575
  return Qnil;
762
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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(cDataConverter_decode_dynamic_conditions(self, field)))
772
- rb_ary_store(res, i, rb_funcall(data->__type, id_load, 5,
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
- else
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(cDataConverter_decode_dynamic_conditions(self, field)))
784
- res = rb_funcall(data->__type, id_load, 5,
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
- else
606
+ res = cStructure_decode_expect(self, field_data->expect, data->__value);
607
+ } else
791
608
  res = Qnil;
792
609
  }
793
- cDataConverter_restore_context(self);
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 cDataConverter_dump_field(VALUE self, VALUE values, VALUE field) {
812
- struct cDataConverter_data *data;
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(cDataConverter_decode_static_conditions(self, field)))
620
+ if (NIL_P(cStructure_decode_static_conditions(self, field)))
815
621
  return Qnil;
816
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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(cDataConverter_decode_dynamic_conditions(self, field)))
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
- rb_ary_entry(values, i),
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(cDataConverter_decode_dynamic_conditions(self, field)))
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
- values,
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
- cDataConverter_restore_context(self);
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 cDataConverter_shape_field(
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 cDataConverter_data *data;
670
+ struct cStructure_data *data;
874
671
  struct cField_data *field_data;
875
- if (NIL_P(cDataConverter_decode_static_conditions(self, field)))
672
+ if (NIL_P(cStructure_decode_static_conditions(self, field)))
876
673
  return Qnil;
877
- TypedData_Get_Struct(self, struct cDataConverter_data, &cDataConverter_type, data);
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(cDataConverter_decode_dynamic_conditions(self, field))) {
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(cDataConverter_decode_dynamic_conditions(self, field))) {
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
- cDataConverter_restore_context(self);
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 cDataConverter_fields_rescue(VALUE state_p, VALUE exception) {
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 cDataConverter_data *data;
950
- TypedData_Get_Struct(state->self, struct cDataConverter_data, &cDataConverter_type, data);
951
- if (!NIL_P(rb_ivar_get(mLibBin, rb_intern("@__output"))))
952
- rb_funcall(rb_ivar_get(mLibBin, rb_intern("@__output")), rb_intern("print"), 6,
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(rb_ivar_get(mLibBin, rb_intern("@__output"))))
963
- rb_funcall(rb_ivar_get(mLibBin, rb_intern("@__output")), rb_intern("print"), 6,
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 cDataConverter_load_fields_wrapper(VALUE state_p) {
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, cDataConverter_load_field(state->self, state->field));
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 inline VALUE cDataConverter_load_fields(VALUE self) {
774
+ static VALUE cStructure_load_fields(VALUE self) {
990
775
  struct fields_state state = {self, Qnil, Qnil};
991
- rb_rescue(&cDataConverter_load_fields_wrapper, (VALUE)&state,
992
- &cDataConverter_fields_rescue, (VALUE)&state);
776
+ rb_rescue(&cStructure_load_fields_wrapper, (VALUE)&state,
777
+ &cStructure_fields_rescue, (VALUE)&state);
993
778
  return self;
994
779
  }
995
780
 
996
- /* def __dump_fields
997
- self.class.instance_variable_get(:@fields).each { |field|
998
- begin
999
- __dump_field(send(field.name), field)
1000
- rescue
1001
- STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
1002
- raise
1003
- end
1004
- }
1005
- self
1006
- end */
1007
-
1008
- static inline VALUE cDataConverter_dump_fields_wrapper(VALUE state_p) {
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
- cDataConverter_dump_field(state->self, rb_funcall(state->self, field_data->getter, 0), state->field);
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 inline VALUE cDataConverter_dump_fields(VALUE self) {
795
+ static VALUE cStructure_dump_fields(VALUE self) {
1023
796
  struct fields_state state = {self, Qnil, Qnil};
1024
- rb_rescue(&cDataConverter_dump_fields_wrapper, (VALUE)&state,
1025
- &cDataConverter_fields_rescue, (VALUE)&state);
797
+ rb_rescue(&cStructure_dump_fields_wrapper, (VALUE)&state,
798
+ &cStructure_fields_rescue, (VALUE)&state);
1026
799
  return self;
1027
800
  }
1028
801
 
1029
- /* def __convert_fields
1030
- self.class.instance_variable_get(:@fields).each { |field|
1031
- begin
1032
- send("#{field.name}=", __convert_field(field))
1033
- rescue
1034
- STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
1035
- raise
1036
- end
1037
- }
1038
- self
1039
- end */
1040
-
1041
- static inline VALUE cDataConverter_convert_fields_wrapper(VALUE state_p) {
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, cDataConverter_convert_field(state->self, state->field));
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 inline VALUE cDataConverter_convert_fields(VALUE self) {
816
+ static VALUE cStructure_convert_fields(VALUE self) {
1056
817
  struct fields_state state = {self, Qnil, Qnil};
1057
- rb_rescue(&cDataConverter_convert_fields_wrapper, (VALUE)&state,
1058
- &cDataConverter_fields_rescue, (VALUE)&state);
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 cDataConverter_shape_fields_wrapper(VALUE state_p) {
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), cDataConverter_shape_field(state->self, rb_funcall(state->self, field_data->getter, 0), state->kind, state->field));
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 inline VALUE cDataConverter_shape_fields(VALUE self, VALUE kind) {
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(&cDataConverter_shape_fields_wrapper, (VALUE)&state,
1100
- &cDataConverter_fields_rescue, (VALUE)&state);
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 cDataConverter_load(int argc, VALUE *argv, VALUE self) {
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
- cDataConverter_set_load_type(self, input, input_big, parent, index);
860
+ rb_funcall(self, id___set_load_state, 4, input, input_big, parent, index);
1119
861
  rb_funcall(self, id___load_fields, 0);
1120
- cDataConverter_unset_load_type(self);
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 cDataConverter_dump(int argc, VALUE *argv, VALUE self) {
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
- cDataConverter_set_dump_type(self, output, output_big, parent, index);
874
+ rb_funcall(self, id___set_dump_state, 4, output, output_big, parent, index);
1140
875
  rb_funcall(self, id___dump_fields, 0);
1141
- cDataConverter_unset_dump_type(self);
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 inline VALUE cDataConverter_convert(int argc, VALUE *argv, VALUE self) {
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
- cDataConverter_set_convert_type(self, input, output, input_big, output_big, parent, index);
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
- cDataConverter_unset_convert_type(self);
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 inline VALUE cDataConverter_shape(int argc, VALUE *argv, VALUE self) {
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
- cDataConverter_set_size_type(self, previous_offset, parent, index);
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
- cDataConverter_unset_size_type(self);
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
- /* def self.load(input, input_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
1197
- if length
1198
- length.times.collect {
1199
- h = self::new
1200
- h.__load(input, input_big, parent, index)
1201
- }
1202
- else
1203
- h = self::new
1204
- h.__load(input, input_big, parent, index)
1205
- end
1206
- end */
1207
-
1208
- static inline VALUE cDataConverter_singl_load(int argc, VALUE *argv, VALUE self) {
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
- /* def self.dump(value, output, output_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
1235
- if length
1236
- length.times.each { |i|
1237
- value[i].__dump(output, output_big, parent, index)
1238
- }
1239
- value
1240
- else
1241
- value.__dump(output, output_big, parent, index)
1242
- end
1243
- end */
1244
-
1245
- static inline VALUE cDataConverter_singl_dump(int argc, VALUE *argv, VALUE self) {
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
- /* def self.convert(input, output, input_big = LibBin::default_big?, output_big = !input_big, parent = nil, index = nil, length = nil)
1265
- if length
1266
- length.times.collect {
1267
- h = self::new
1268
- h.__convert(input, output, input_big, output_big, parent, index)
1269
- }
1270
- else
1271
- h = self::new
1272
- h.__convert(input, output, input_big, output_big, parent, index)
1273
- end
1274
- end */
1275
-
1276
- static inline VALUE cDataConverter_singl_convert(int argc, VALUE *argv, VALUE self) {
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
- /* def self.shape(value, previous_offset = 0, parent = nil, index = nil, kind = DataShape, length = nil)
1306
- if length
1307
- kind::new(length.times.collect { |i|
1308
- value[i].__shape(previous_offset, parent, index, kind)
1309
- })
1310
- else
1311
- value.__shape(previous_offset, parent, index, kind)
1312
- end
1313
- end */
1314
-
1315
- static inline VALUE cDataConverter_singl_shape(int argc, VALUE *argv, VALUE self) {
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 define_cDataConverter() {
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
- cDataConverter = rb_define_class_under(mLibBin, "DataConverter", rb_cObject);
1362
- rb_define_alloc_func(cDataConverter, cDataConverter_alloc);
1363
- rb_define_method(cDataConverter, "initialize", cDataConverter_initialize, 0);
1364
- rb_define_method(cDataConverter, "__parent", cDataConverter_parent, 0);
1365
- rb_define_method(cDataConverter, "__index", cDataConverter_index, 0);
1366
- rb_define_method(cDataConverter, "__iterator", cDataConverter_iterator, 0);
1367
- rb_define_method(cDataConverter, "__position", cDataConverter_position, 0);
1368
- rb_define_method(cDataConverter, "__input", cDataConverter_input, 0);
1369
- rb_define_method(cDataConverter, "__output", cDataConverter_output, 0);
1370
- rb_define_method(cDataConverter, "__input_big", cDataConverter_input_big, 0);
1371
- rb_define_method(cDataConverter, "__output_big", cDataConverter_output_big, 0);
1372
-
1373
- rb_define_method(cDataConverter, "__set_convert_type", cDataConverter_set_convert_type, 6);
1374
- rb_define_method(cDataConverter, "__unset_convert_type", cDataConverter_unset_convert_type, 0);
1375
- rb_define_method(cDataConverter, "__set_size_type", cDataConverter_set_size_type, 3);
1376
- rb_define_method(cDataConverter, "__unset_size_type", cDataConverter_unset_size_type, 0);
1377
- rb_define_method(cDataConverter, "__set_load_type", cDataConverter_set_load_type, 4);
1378
- rb_define_method(cDataConverter, "__unset_load_type", cDataConverter_unset_load_type, 0);
1379
- rb_define_method(cDataConverter, "__set_dump_type", cDataConverter_set_dump_type, 4);
1380
- rb_define_method(cDataConverter, "__unset_dump_type", cDataConverter_unset_dump_type, 0);
1381
-
1382
- rb_define_method(cDataConverter, "__decode_expression", cDataConverter_decode_expression, 1);
1383
- rb_define_method(cDataConverter, "__decode_seek_offset", cDataConverter_decode_seek_offset, 2);
1384
- rb_define_method(cDataConverter, "__decode_condition", cDataConverter_decode_condition, 1);
1385
- rb_define_method(cDataConverter, "__decode_count", cDataConverter_decode_count, 1);
1386
- rb_define_method(cDataConverter, "__decode_type", cDataConverter_decode_type, 1);
1387
- rb_define_method(cDataConverter, "__decode_length", cDataConverter_decode_length, 1);
1388
- rb_define_method(cDataConverter, "__decode_static_conditions", cDataConverter_decode_static_conditions, 1);
1389
- rb_define_method(cDataConverter, "__decode_dynamic_conditions", cDataConverter_decode_dynamic_conditions, 1);
1390
-
1391
- rb_define_method(cDataConverter, "__restore_context", cDataConverter_restore_context, 0);
1392
-
1393
- rb_define_method(cDataConverter, "__convert_field", cDataConverter_convert_field, 1);
1394
- rb_define_method(cDataConverter, "__load_field", cDataConverter_load_field, 1);
1395
- rb_define_method(cDataConverter, "__dump_field", cDataConverter_dump_field, 2);
1396
- rb_define_method(cDataConverter, "__shape_field", cDataConverter_shape_field, 3);
1397
-
1398
- rb_define_method(cDataConverter, "__load_fields", cDataConverter_load_fields, 0);
1399
- rb_define_method(cDataConverter, "__dump_fields", cDataConverter_dump_fields, 0);
1400
- rb_define_method(cDataConverter, "__convert_fields", cDataConverter_convert_fields, 0);
1401
- rb_define_method(cDataConverter, "__shape_fields", cDataConverter_shape_fields, 1);
1402
-
1403
- rb_define_method(cDataConverter, "__load", cDataConverter_load, -1);
1404
- rb_define_method(cDataConverter, "__dump", cDataConverter_dump, -1);
1405
- rb_define_method(cDataConverter, "__convert", cDataConverter_convert, -1);
1406
- rb_define_method(cDataConverter, "__shape", cDataConverter_shape, -1);
1407
-
1408
- rb_define_singleton_method(cDataConverter, "load", cDataConverter_singl_load, -1);
1409
- rb_define_singleton_method(cDataConverter, "dump", cDataConverter_singl_dump, -1);
1410
- rb_define_singleton_method(cDataConverter, "convert", cDataConverter_singl_convert, -1);
1411
- rb_define_singleton_method(cDataConverter, "shape", cDataConverter_singl_shape, -1);
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
- cDataShape = rb_define_class_under(mLibBin, "DataShape", rb_cObject);
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
  }