libbin 1.0.8 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }