libbin 1.0.2 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a839d4dfb7966a79a1319812d1228919978b7ad98bffa0d99f8375b6d1756318
4
- data.tar.gz: dddf34d95677e7eec57f42dab96d278d0af6672d59a44126afa7ace584edbb14
3
+ metadata.gz: d3a9557a12a5d4ef9ed048592358290c19bebb42cb55d5dacf5d234e62aee6c0
4
+ data.tar.gz: 319fffa88af207c7613209e632b10e1c16a70bea0b5ddfbf7de6b1f54bb74cbf
5
5
  SHA512:
6
- metadata.gz: 4aa40ec6641631c60fbc11231a40519a42519f854496f74994a46f95e858e3d49bedf2c95cd88a317d9efd5174c16417562ba05533d2f90f4006fd6c52050663
7
- data.tar.gz: 9cdea5cac5feb7f7a5816bbc0670fefc77adb3f8febe9a3b2be7f8c85b95cd51426a8d668688a5b46c9dc45eb7b1d61f2fd6b23ca9fb20df0d5ceaab9126ac66
6
+ metadata.gz: a07e150714b61ea44cb2a7df3442e6ed7257d4b601bc8e2353e2329fc9eaaddcef56318dac85c2277a1eff3e8f6407919b4f43320e4e9d02506cce2bcea6bf35
7
+ data.tar.gz: 2d4ef297ce1c616ce464d2b3a667061959965ba8ca63113e699348e6313f3ab8ba15165c3041cc84cded5dc70ba5b5e5f31bcf338221f5a2a4bb725440636fad
data/LICENSE CHANGED
File without changes
File without changes
data/ext/libbin/half.c CHANGED
File without changes
data/ext/libbin/half.h CHANGED
File without changes
@@ -11,7 +11,7 @@ static VALUE pghalf_from_string_p(VALUE self, VALUE str, VALUE pack_str) {
11
11
  Check_Type(str, T_STRING);
12
12
  Check_Type(pack_str, T_STRING);
13
13
  VALUE arr = rb_funcall(str, rb_intern("unpack"), 1, pack_str);
14
- uint16_t val = NUM2USHORT(rb_funcall(arr, rb_intern("first"), 0));
14
+ uint16_t val = NUM2USHORT(rb_funcall(arr, rb_intern("first"), 0));
15
15
  union float_u res;
16
16
 
17
17
  res.i = pghalf_to_float(val);
@@ -22,7 +22,7 @@ static VALUE half_from_string_p(VALUE self, VALUE str, VALUE pack_str) {
22
22
  Check_Type(str, T_STRING);
23
23
  Check_Type(pack_str, T_STRING);
24
24
  VALUE arr = rb_funcall(str, rb_intern("unpack"), 1, pack_str);
25
- uint16_t val = NUM2USHORT(rb_funcall(arr, rb_intern("first"), 0));
25
+ uint16_t val = NUM2USHORT(rb_funcall(arr, rb_intern("first"), 0));
26
26
  union float_u res;
27
27
 
28
28
  res.i = half_to_float(val);
@@ -32,25 +32,25 @@ static VALUE half_from_string_p(VALUE self, VALUE str, VALUE pack_str) {
32
32
  static VALUE pghalf_to_string_p(VALUE self, VALUE number, VALUE pack_str) {
33
33
  Check_Type(number, T_FLOAT);
34
34
  union float_u val;
35
- uint16_t res;
35
+ uint16_t res;
36
36
 
37
37
  val.f = NUM2DBL(number);
38
38
  res = pghalf_from_float(val.i);
39
- VALUE arr = rb_ary_new3(1, UINT2NUM(res) );
39
+ VALUE arr = rb_ary_new3(1, UINT2NUM(res) );
40
40
 
41
- return rb_funcall(arr, rb_intern("pack"), 1, pack_str);
41
+ return rb_funcall(arr, rb_intern("pack"), 1, pack_str);
42
42
  }
43
43
 
44
44
  static VALUE half_to_string_p(VALUE self, VALUE number, VALUE pack_str) {
45
45
  Check_Type(number, T_FLOAT);
46
46
  union float_u val;
47
- uint16_t res;
47
+ uint16_t res;
48
48
 
49
49
  val.f = NUM2DBL(number);
50
50
  res = half_from_float(val.i);
51
- VALUE arr = rb_ary_new3(1, UINT2NUM(res) );
51
+ VALUE arr = rb_ary_new3(1, UINT2NUM(res) );
52
52
 
53
- return rb_funcall(arr, rb_intern("pack"), 1, pack_str);
53
+ return rb_funcall(arr, rb_intern("pack"), 1, pack_str);
54
54
  }
55
55
 
56
56
  void Init_libbin_c() {
data/ext/libbin/pghalf.c CHANGED
@@ -339,22 +339,22 @@ uint16_t
339
339
  pghalf_from_float( uint32_t f )
340
340
  {
341
341
  const uint32_t one = _uint32_li( 0x00000001 );
342
- const uint32_t f_s_mask = _uint32_li( 0x80000000 );
343
- const uint32_t f_e_mask = _uint32_li( 0x7f800000 );
344
- const uint32_t f_m_mask = _uint32_li( 0x007fffff );
345
- const uint32_t f_m_hidden_bit = _uint32_li( 0x00800000 );
346
- const uint32_t f_m_round_bit = _uint32_li( 0x00001000 );
347
- const uint32_t f_snan_mask = _uint32_li( 0x7fc00000 );
348
- const uint32_t f_e_pos = _uint32_li( 0x00000017 );
349
- const uint32_t h_e_pos = _uint32_li( 0x00000009 );
350
- const uint32_t h_e_mask = _uint32_li( 0x00007e00 );
351
- const uint32_t h_snan_mask = _uint32_li( 0x00007f00 );
352
- const uint32_t h_e_mask_value = _uint32_li( 0x0000003f );
353
- const uint32_t f_h_s_pos_offset = _uint32_li( 0x00000010 );
354
- const uint32_t f_h_bias_offset = _uint32_li( 0x00000050 );
355
- const uint32_t f_h_m_pos_offset = _uint32_li( 0x0000000e );
356
- const uint32_t h_nan_min = _uint32_li( 0x00007e01 );
357
- const uint32_t f_h_e_biased_flag = _uint32_li( 0x000000af );
342
+ const uint32_t f_s_mask = _uint32_li( 0x80000000 ); //bit 31
343
+ const uint32_t f_e_mask = _uint32_li( 0x7f800000 ); //bits 30-23
344
+ const uint32_t f_m_mask = _uint32_li( 0x007fffff ); //bits 22-0
345
+ const uint32_t f_m_hidden_bit = _uint32_li( 0x00800000 ); //1<<f_e_pos
346
+ const uint32_t f_m_round_bit = _uint32_li( 0x00002000 ); //1<<(f_e_pos - h_e_pos - 1)
347
+ const uint32_t f_snan_mask = _uint32_li( 0x7fc00000 ); //f_e_mask + 1 << (f_e_pos - 1)
348
+ const uint32_t f_e_pos = _uint32_li( 0x00000017 ); //23
349
+ const uint32_t h_e_pos = _uint32_li( 0x00000009 ); //9
350
+ const uint32_t h_e_mask = _uint32_li( 0x00007e00 ); //bits 14-9
351
+ const uint32_t h_snan_mask = _uint32_li( 0x00007f00 ); //h_e_mask + 1 << (h_e_pos - 1)
352
+ const uint32_t h_e_mask_value = _uint32_li( 0x0000003f ); //h_e_mask >> 9
353
+ const uint32_t f_h_s_pos_offset = _uint32_li( 0x00000010 ); //f_s_pos - h_s_pos
354
+ const uint32_t f_h_bias_offset = _uint32_li( 0x00000050 ); //f_bias - h_bias
355
+ const uint32_t f_h_m_pos_offset = _uint32_li( 0x0000000e ); //f_e_pos - h_e_pos
356
+ const uint32_t h_nan_min = _uint32_li( 0x00007e01 ); //h_e_mask + 1
357
+ const uint32_t f_h_e_biased_flag = _uint32_li( 0x000000af ); //f_bias + h_bias + 1
358
358
  const uint32_t f_s = _uint32_and( f, f_s_mask );
359
359
  const uint32_t f_e = _uint32_and( f, f_e_mask );
360
360
  const uint16_t h_s = _uint32_srl( f_s, f_h_s_pos_offset );
@@ -403,18 +403,18 @@ pghalf_from_float( uint32_t f )
403
403
  uint32_t
404
404
  pghalf_to_float( uint16_t h )
405
405
  {
406
- const uint32_t h_e_mask = _uint32_li( 0x00007e00 );
407
- const uint32_t h_m_mask = _uint32_li( 0x000001ff );
408
- const uint32_t h_s_mask = _uint32_li( 0x00008000 );
409
- const uint32_t h_f_s_pos_offset = _uint32_li( 0x00000010 );
410
- const uint32_t h_f_e_pos_offset = _uint32_li( 0x0000000e );
411
- const uint32_t h_f_bias_offset = _uint32_li( 0x0000a000 );
412
- const uint32_t f_e_mask = _uint32_li( 0x7f800000 );
413
- const uint32_t f_m_mask = _uint32_li( 0x007fffff );
414
- const uint32_t h_f_e_denorm_bias = _uint32_li( 0x0000005f );
415
- const uint32_t h_f_m_denorm_sa_bias = _uint32_li( 0x00000008 );
416
- const uint32_t f_e_pos = _uint32_li( 0x00000017 );
417
- const uint32_t h_e_mask_minus_one = _uint32_li( 0x00007dff );
406
+ const uint32_t h_e_mask = _uint32_li( 0x00007e00 ); //bits 14-9
407
+ const uint32_t h_m_mask = _uint32_li( 0x000001ff ); //bits 8-0
408
+ const uint32_t h_s_mask = _uint32_li( 0x00008000 ); //bit 15
409
+ const uint32_t h_f_s_pos_offset = _uint32_li( 0x00000010 ); //f_s_pos - h_s_pos
410
+ const uint32_t h_f_e_pos_offset = _uint32_li( 0x0000000e ); //f_m_bitcount - h_m_bitcount
411
+ const uint32_t h_f_bias_offset = _uint32_li( 0x0000a000 ); //(f_bias - h_bias) << 9
412
+ const uint32_t f_e_mask = _uint32_li( 0x7f800000 ); //bits 30-23
413
+ const uint32_t f_m_mask = _uint32_li( 0x007fffff ); //bits 22-0
414
+ const uint32_t h_f_e_denorm_bias = _uint32_li( 0x0000005f ); //h_f_e_pos_offset + 1 + (f_bias - h_bias)
415
+ const uint32_t h_f_m_denorm_sa_bias = _uint32_li( 0x00000008 ); //float exp bit count
416
+ const uint32_t f_e_pos = _uint32_li( 0x00000017 ); //23
417
+ const uint32_t h_e_mask_minus_one = _uint32_li( 0x00007dff ); //h_e_mask + h_m_mask - 1<<h_e_pos
418
418
  const uint32_t h_e = _uint32_and( h, h_e_mask );
419
419
  const uint32_t h_m = _uint32_and( h, h_m_mask );
420
420
  const uint32_t h_s = _uint32_and( h, h_s_mask );
data/ext/libbin/pghalf.h CHANGED
File without changes
File without changes
@@ -70,14 +70,52 @@ module LibBin
70
70
 
71
71
  end
72
72
 
73
+ class Field
74
+ attr_reader :name,
75
+ :type,
76
+ :length,
77
+ :count,
78
+ :offset,
79
+ :sequence,
80
+ :condition
81
+
82
+ def sequence?
83
+ @sequence
84
+ end
85
+
86
+ def relative_offset?
87
+ @relative_offset
88
+ end
89
+
90
+ def initialize(name, type, length, count, offset, sequence, condition, relative_offset)
91
+ @name = name
92
+ @type = type
93
+ @length = length
94
+ @count = count
95
+ @offset = offset
96
+ @sequence = sequence
97
+ @condition = condition
98
+ @relative_offset = relative_offset
99
+ end
100
+
101
+ end
102
+
73
103
  class DataConverter
74
104
 
75
- rl = lambda { |type, str|
76
- str.unpack(type.to_s).first
105
+ rl = lambda { |type, str, number = nil|
106
+ if number
107
+ str.unpack(type.to_s+number.to_s)
108
+ else
109
+ str.unpack(type.to_s).first
110
+ end
77
111
  }
78
112
 
79
- sl = lambda { |type, value|
80
- [value].pack(type.to_s)
113
+ sl = lambda { |type, value, number = nil|
114
+ if number
115
+ value.pack(type.to_s+number.to_s)
116
+ else
117
+ [value].pack(type.to_s)
118
+ end
81
119
  }
82
120
 
83
121
  l = lambda { |type|
@@ -161,6 +199,7 @@ module LibBin
161
199
  :D => 8,
162
200
  :E => 8,
163
201
  :G => 8,
202
+ :a => 1,
164
203
  :"a*" => -1,
165
204
  :half => 2,
166
205
  :half_le => 2,
@@ -186,6 +225,50 @@ module LibBin
186
225
  }
187
226
  }
188
227
 
228
+ rhl = lambda { |type, str, number = nil|
229
+ if number
230
+ number.times.collect { |i| LibBin::half_from_string(str[i*2,2], type) }
231
+ else
232
+ LibBin::half_from_string(str, type)
233
+ end
234
+ }
235
+
236
+ shl = lambda { |type, value, number = nil|
237
+ if number
238
+ str = ""
239
+ number.times { |i| str << LibBin::half_to_string(value[i], type) }
240
+ str
241
+ else
242
+ LibBin::half_to_string(value, type)
243
+ end
244
+ }
245
+
246
+ hl = lambda { |type|
247
+ [rhl.curry[type], shl.curry[type]]
248
+ }
249
+
250
+ rpghl = lambda { |type, str, number = nil|
251
+ if number
252
+ number.times.collect { |i| LibBin::pghalf_from_string(str[i*2,2], type) }
253
+ else
254
+ LibBin::pghalf_from_string(str, type)
255
+ end
256
+ }
257
+
258
+ spghl = lambda { |type, value, number = nil|
259
+ if number
260
+ str = ""
261
+ number.times { |i| str << LibBin::pghalf_to_string(value[i], type) }
262
+ str
263
+ else
264
+ LibBin::pghalf_to_string(value, type)
265
+ end
266
+ }
267
+
268
+ pghl = lambda { |type|
269
+ [rpghl.curry[type], spghl.curry[type]]
270
+ }
271
+
189
272
  DATA_ENDIAN[true].merge!( {
190
273
  :c => l["c"],
191
274
  :C => l["C"],
@@ -217,19 +300,12 @@ module LibBin
217
300
  :D => l["G"],
218
301
  :E => l["E"],
219
302
  :G => l["G"],
220
- :"a*" => l["a*"],
221
- :half => [ lambda { |str| LibBin::half_from_string(str, "S>") },
222
- lambda { |v| LibBin::half_to_string(v, "S>") } ],
223
- :half_le => [ lambda { |str| LibBin::half_from_string(str, "S<") },
224
- lambda { |v| LibBin::half_to_string(v, "S<") } ],
225
- :half_be => [ lambda { |str| LibBin::half_from_string(str, "S>") },
226
- lambda { |v| LibBin::half_to_string(v, "S>") } ],
227
- :pghalf => [ lambda { |str| LibBin::pghalf_from_string(str, "S>") },
228
- lambda { |v| LibBin::pghalf_to_string(v, "S>") } ],
229
- :pghalf_le => [ lambda { |str| LibBin::pghalf_from_string(str, "S<") },
230
- lambda { |v| LibBin::pghalf_to_string(v, "S<") } ],
231
- :pghalf_be => [ lambda { |str| LibBin::pghalf_from_string(str, "S>") },
232
- lambda { |v| LibBin::pghalf_to_string(v, "S>") } ]
303
+ :half => hl["S>"],
304
+ :half_le => hl["S<"],
305
+ :half_be => hl["S>"],
306
+ :pghalf => pghl["S>"],
307
+ :pghalf_le => pghl["S<"],
308
+ :pghalf_be => pghl["S>"]
233
309
  } )
234
310
  DATA_ENDIAN[false].merge!( {
235
311
  :c => l["c"],
@@ -262,19 +338,12 @@ module LibBin
262
338
  :D => l["E"],
263
339
  :E => l["E"],
264
340
  :G => l["G"],
265
- :"a*" => l["a*"],
266
- :half => [ lambda { |str| LibBin::half_from_string(str, "S<") },
267
- lambda { |v| LibBin::half_to_string(v, "S<") } ],
268
- :half_le => [ lambda { |str| LibBin::half_from_string(str, "S<") },
269
- lambda { |v| LibBin::half_to_string(v, "S<") } ],
270
- :half_be => [ lambda { |str| LibBin::half_from_string(str, "S>") },
271
- lambda { |v| LibBin::half_to_string(v, "S>") } ],
272
- :pghalf => [ lambda { |str| LibBin::pghalf_from_string(str, "S<") },
273
- lambda { |v| LibBin::pghalf_to_string(v, "S<") } ],
274
- :pghalf_le => [ lambda { |str| LibBin::pghalf_from_string(str, "S<") },
275
- lambda { |v| LibBin::pghalf_to_string(v, "S<") } ],
276
- :pghalf_be => [ lambda { |str| LibBin::pghalf_from_string(str, "S>") },
277
- lambda { |v| LibBin::pghalf_to_string(v, "S>") } ]
341
+ :half => hl["S<"],
342
+ :half_le => hl["S<"],
343
+ :half_be => hl["S>"],
344
+ :pghalf => pghl["S<"],
345
+ :pghalf_le => pghl["S<"],
346
+ :pghalf_be => pghl["S>"]
278
347
  } )
279
348
 
280
349
 
@@ -284,8 +353,9 @@ module LibBin
284
353
  @size
285
354
  end
286
355
 
287
- def self.shape(value, previous_offset = 0, _ = nil, _ = nil, kind = DataShape)
288
- kind::new(previous_offset, previous_offset + @size - 1)
356
+ def self.shape(value, previous_offset = 0, _ = nil, _ = nil, kind = DataShape, length = nil)
357
+ length = 1 unless length
358
+ kind::new(previous_offset, previous_offset - 1 + length * @size)
289
359
  end
290
360
 
291
361
  def self.init(symbol)
@@ -295,20 +365,22 @@ module LibBin
295
365
  @rl_le, @sl_le = DATA_ENDIAN[false][symbol]
296
366
  end
297
367
 
298
- def self.load(input, input_big = LibBin::default_big?, _ = nil, _ = nil)
299
- str = input.read(@size)
300
- input_big ? @rl_be[str] : @rl_le[str]
368
+ def self.load(input, input_big = LibBin::default_big?, _ = nil, _ = nil, length = nil)
369
+ l = (length ? length : 1)
370
+ str = input.read(@size*l)
371
+ input_big ? @rl_be[str, length] : @rl_le[str, length]
301
372
  end
302
373
 
303
- def self.dump(value, output, output_big = LibBin::default_big?, _ = nil, _ = nil)
304
- str = (output_big ? @sl_be[value] : @sl_le[value])
374
+ def self.dump(value, output, output_big = LibBin::default_big?, _ = nil, _ = nil, length = nil)
375
+ str = (output_big ? @sl_be[value, length] : @sl_le[value, length])
305
376
  output.write(str)
306
377
  end
307
378
 
308
- def self.convert(input, output, input_big = LibBin::default_big?, output_big = !input_big, _ = nil, _ = nil)
309
- str = input.read(@size)
310
- value = (input_big ? @rl_be[str] : @rl_le[str])
311
- str = (output_big ? @sl_be[value] : @sl_le[value])
379
+ def self.convert(input, output, input_big = LibBin::default_big?, output_big = !input_big, _ = nil, _ = nil, length = nil)
380
+ l = (length ? length : 1)
381
+ str = input.read(@size*l)
382
+ value = (input_big ? @rl_be[str, length] : @rl_le[str, length])
383
+ str = (output_big ? @sl_be[value, length] : @sl_le[value, length])
312
384
  output.write(str)
313
385
  value
314
386
  end
@@ -317,40 +389,48 @@ module LibBin
317
389
 
318
390
  class Str < Scalar
319
391
 
320
- def self.load(input, input_big = LibBin::default_big?, _ = nil, _ = nil)
321
- str = (@size < 0 ? input.readline("\x00") : input.read(@size))
322
- input_big ? @rl_be[str] : @rl_le[str]
392
+ def self.size(value, previous_offset = 0, parent = nil, index = nil, length = nil)
393
+ length ? length : value.size
394
+ end
395
+
396
+ def self.load(input, input_big = LibBin::default_big?, _ = nil, _ = nil, length = nil)
397
+ str = (length ? input.read(length) : input.readline("\x00"))
323
398
  end
324
399
 
325
- def self.convert(input, output, input_big = LibBin::default_big?, output_big = !LibBin::default_big, _ = nil, _ = nil)
326
- str = (@size < 0 ? input.readline("\x00") : input.read(@size))
327
- value = (input_big ? @rl_be[str] : @rl_le[str])
328
- str = (output_big ? @sl_be[value] : @sl_le[value])
400
+ def self.convert(input, output, input_big = LibBin::default_big?, output_big = !LibBin::default_big, _ = nil, _ = nil, length = nil)
401
+ str = (length ? input.read(length) : input.readline("\x00"))
329
402
  output.write(str)
330
- value
403
+ str
331
404
  end
332
405
 
333
- def self.shape(value, previous_offset = 0, _ = nil, _ = nil, kind = DataShape)
334
- if @size < 0
335
- kind::new(previous_offset, previous_offset + value.size - 1)
406
+ def self.shape(value, previous_offset = 0, _ = nil, _ = nil, kind = DataShape, length = nil)
407
+ if length
408
+ kind::new(previous_offset, previous_offset + length - 1)
336
409
  else
337
- kind::new(previous_offset, previous_offset + @size - 1)
410
+ kind::new(previous_offset, previous_offset + value.size - 1)
338
411
  end
339
412
  end
340
413
 
414
+ def self.dump(value, output, output_big = LibBin::default_big?, _ = nil, _ = nil, length = nil)
415
+ if length
416
+ output.write([value].pack("Z#{length}"))
417
+ else
418
+ output.write(value)
419
+ end
420
+ end
341
421
  end
342
422
 
343
- def self.register_field(field, type, count: nil, offset: nil, sequence: false, condition: nil)
423
+ def self.register_field(field, type, length: nil, count: nil, offset: nil, sequence: false, condition: nil, relative_offset: false)
344
424
  if type.kind_of?(Symbol)
345
425
  if type[0] == 'a'
346
- c = Class::new(Str) do init(sym) end
347
- @fields.push([field, c, count, offset, sequence, condition])
426
+ real_type = Class::new(Str) do init(sym) end
348
427
  else
349
- @fields.push([field, const_get(SCALAR_TYPES[type][0]), count, offset, sequence, condition])
428
+ real_type = const_get(SCALAR_TYPES[type][0])
350
429
  end
351
430
  else
352
- @fields.push([field, type, count, offset, sequence, condition])
431
+ real_type = type
353
432
  end
433
+ @fields.push(Field::new(field, real_type, length, count, offset, sequence, condition, relative_offset))
354
434
  attr_accessor field
355
435
  end
356
436
 
@@ -361,8 +441,8 @@ module LibBin
361
441
  init(#{symbol.inspect})
362
442
  end
363
443
 
364
- def self.#{name}(field, count: nil, offset: nil, sequence: false, condition: nil)
365
- @fields.push([field, #{klassname}, count, offset, sequence, condition])
444
+ def self.#{name}(field, length: nil, count: nil, offset: nil, sequence: false, condition: nil, relative_offset: false)
445
+ @fields.push(Field::new(field, #{klassname}, length, count, offset, sequence, condition, relative_offset))
366
446
  attr_accessor field
367
447
  end
368
448
  EOF
@@ -401,16 +481,15 @@ EOF
401
481
  create_scalar_type(:pghalf_le)
402
482
  create_scalar_type(:pghalf_be)
403
483
 
404
- def self.string( field, length = nil, count: nil, offset: nil, sequence: false, condition: nil)
405
- sym = (length ? :"a#{length}" : :"a*")
484
+ def self.string( field, length = nil, count: nil, offset: nil, sequence: false, condition: nil, relative_offset: false)
485
+ sym = (length ? :"a" : :"a*")
406
486
  c = Class::new(Str) do
407
487
  init(sym)
408
488
  end
409
- @fields.push([field, c, count, offset, sequence, condition])
489
+ @fields.push(Field::new(field, c, length, count, offset, sequence, condition, relative_offset))
410
490
  attr_accessor field
411
491
  end
412
492
 
413
-
414
493
  end
415
494
 
416
495
  end
data/lib/libbin.rb CHANGED
@@ -117,10 +117,11 @@ module LibBin
117
117
  end
118
118
  end
119
119
 
120
- def __decode_seek_offset(offset)
120
+ def __decode_seek_offset(offset, relative_offset)
121
121
  return nil unless offset
122
122
  offset = __decode_expression(offset)
123
123
  return false if offset == 0x0
124
+ offset += @__position if relative_offset
124
125
  @__cur_position = offset
125
126
  @__input.seek(offset) if @__input
126
127
  @__output.seek(offset) if @__output
@@ -141,97 +142,106 @@ module LibBin
141
142
  return __decode_expression(type)
142
143
  end
143
144
 
144
- def __decode_static_conditions(type, count, offset, sequence, condition)
145
+ def __decode_length(length)
146
+ __decode_expression(length)
147
+ end
148
+
149
+ def __decode_static_conditions(field)
145
150
  @__offset = nil
146
151
  @__condition = nil
147
152
  @__type = nil
153
+ @__length = nil
148
154
  @__count = nil
149
- unless sequence
150
- @__offset = __decode_seek_offset(offset)
155
+ unless field.sequence?
156
+ @__offset = __decode_seek_offset(field.offset, field.relative_offset?)
151
157
  throw :ignored, nil if @__offset == false
152
- @__condition = __decode_condition(condition)
158
+ @__condition = __decode_condition(field.condition)
153
159
  throw :ignored, nil unless @__condition
154
- @__type = __decode_type(type)
160
+ @__type = __decode_type(field.type)
161
+ @__length = __decode_length(field.length)
155
162
  end
156
- @__count = __decode_count(count)
163
+ @__count = __decode_count(field.count)
157
164
  end
158
165
 
159
- def __decode_dynamic_conditions(type, offset, sequence, condition)
160
- return true unless sequence
166
+ def __decode_dynamic_conditions(field)
167
+ return true unless field.sequence?
161
168
  @__offset = nil
162
169
  @__condition = nil
163
170
  @__type = nil
164
- @__offset = __decode_seek_offset(offset)
171
+ @__length = nil
172
+ @__offset = __decode_seek_offset(field.offset, field.relative_offset?)
165
173
  return false if @__offset == false
166
- @__condition = __decode_condition(condition)
174
+ @__condition = __decode_condition(field.condition)
167
175
  return false unless @__condition
168
- @__type = __decode_type(type)
176
+ @__type = __decode_type(field.type)
177
+ @__length = __decode_length(field.length)
169
178
  return true
170
179
  end
171
180
 
172
181
  def __restore_context
173
182
  @__iterator = nil
174
183
  @__type = nil
184
+ @__length = nil
175
185
  @__count = nil
176
186
  @__offset = nil
177
187
  @__condition = nil
178
188
  end
179
189
 
180
- def __convert_field(field, type, count, offset, sequence, condition)
181
- __decode_static_conditions(type, count, offset, sequence, condition)
190
+ def __convert_field(field)
191
+ __decode_static_conditions(field)
182
192
  vs = @__count.times.collect do |it|
183
193
  @__iterator = it
184
- if __decode_dynamic_conditions(type, offset, sequence, condition)
185
- @__type::convert(@__input, @__output, @__input_big, @__output_big, self, it)
194
+ if __decode_dynamic_conditions(field)
195
+ @__type::convert(@__input, @__output, @__input_big, @__output_big, self, it, @__length)
186
196
  else
187
197
  nil
188
198
  end
189
199
  end
190
200
  __restore_context
191
- vs = vs.first unless count
201
+ vs = vs.first unless field.count
192
202
  vs
193
203
  end
194
204
 
195
- def __load_field(field, type, count, offset, sequence, condition)
196
- __decode_static_conditions(type, count, offset, sequence, condition)
205
+ def __load_field(field)
206
+ __decode_static_conditions(field)
197
207
  vs = @__count.times.collect do |it|
198
208
  @__iterator = it
199
- if __decode_dynamic_conditions(type, offset, sequence, condition)
200
- @__type::load(@__input, @__input_big, self, it)
209
+ if __decode_dynamic_conditions(field)
210
+ @__type::load(@__input, @__input_big, self, it, @__length)
201
211
  else
202
212
  nil
203
213
  end
204
214
  end
205
215
  __restore_context
206
- vs = vs.first unless count
216
+ vs = vs.first unless field.count
207
217
  vs
208
218
  end
209
219
 
210
- def __dump_field(vs, field, type, count, offset, sequence, condition)
211
- __decode_static_conditions(type, count, offset, sequence, condition)
212
- vs = [vs] unless count
220
+ def __dump_field(vs, field)
221
+ __decode_static_conditions(field)
222
+ vs = [vs] unless field.count
213
223
  vs.each_with_index do |v, it|
214
224
  @__iterator = it
215
- if __decode_dynamic_conditions(type, offset, sequence, condition)
216
- @__type::dump(v, @__output, @__output_big, self, it)
225
+ if __decode_dynamic_conditions(field)
226
+ @__type::dump(v, @__output, @__output_big, self, it, @__length)
217
227
  end
218
228
  end
219
229
  __restore_context
220
230
  end
221
231
 
222
- def __shape_field(vs, previous_offset, kind, field, type, count, offset, sequence, condition)
223
- __decode_static_conditions(type, count, offset, sequence, condition)
224
- vs = [vs] unless count
232
+ def __shape_field(vs, previous_offset, kind, field)
233
+ __decode_static_conditions(field)
234
+ vs = [vs] unless field.count
225
235
  vs = vs.each_with_index.collect do |v, it|
226
236
  @__iterator = it
227
- if __decode_dynamic_conditions(type, offset, sequence, condition)
228
- sh = @__type::shape(v, @__cur_position, self, it, kind)
237
+ if __decode_dynamic_conditions(field)
238
+ sh = @__type::shape(v, @__cur_position, self, it, kind, @__length)
229
239
  @__cur_position = sh.last + 1 if sh.last && sh.last >= 0
230
240
  sh
231
241
  end
232
242
  end
233
243
  __restore_context
234
- vs = vs.first unless count
244
+ vs = vs.first unless field.count
235
245
  vs
236
246
  end
237
247
 
@@ -242,15 +252,15 @@ module LibBin
242
252
  def __shape(previous_offset = 0, parent = nil, index = nil, kind = DataShape)
243
253
  __set_size_type(previous_offset, parent, index)
244
254
  members = {}
245
- self.class.instance_variable_get(:@fields).each { |name, type, *args|
255
+ self.class.instance_variable_get(:@fields).each { |field|
246
256
  begin
247
- vs = send(name)
257
+ vs = send(field.name)
248
258
  member = catch(:ignored) do
249
- __shape_field(vs, previous_offset, kind, name, type, *args)
259
+ __shape_field(vs, previous_offset, kind, field)
250
260
  end
251
- members[name] = member
261
+ members[field.name] = member
252
262
  rescue
253
- STDERR.puts "#{self.class}: #{name}(#{type})"
263
+ STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
254
264
  raise
255
265
  end
256
266
  }
@@ -260,14 +270,14 @@ module LibBin
260
270
  end
261
271
 
262
272
  def __convert_fields
263
- self.class.instance_variable_get(:@fields).each { |name, type, *args|
273
+ self.class.instance_variable_get(:@fields).each { |field|
264
274
  begin
265
275
  vs = catch(:ignored) do
266
- __convert_field(name, type, *args)
276
+ __convert_field(field)
267
277
  end
268
- send("#{name}=", vs)
278
+ send("#{field.name}=", vs)
269
279
  rescue
270
- STDERR.puts "#{self.class}: #{name}(#{type})"
280
+ STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
271
281
  raise
272
282
  end
273
283
  }
@@ -275,14 +285,14 @@ module LibBin
275
285
  end
276
286
 
277
287
  def __load_fields
278
- self.class.instance_variable_get(:@fields).each { |name, type, *args|
288
+ self.class.instance_variable_get(:@fields).each { |field|
279
289
  begin
280
290
  vs = catch(:ignored) do
281
- __load_field(name, type, *args)
291
+ __load_field(field)
282
292
  end
283
- send("#{name}=", vs)
293
+ send("#{field.name}=", vs)
284
294
  rescue
285
- STDERR.puts "#{self.class}: #{name}(#{type})"
295
+ STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
286
296
  raise
287
297
  end
288
298
  }
@@ -290,14 +300,14 @@ module LibBin
290
300
  end
291
301
 
292
302
  def __dump_fields
293
- self.class.instance_variable_get(:@fields).each { |name, type, *args|
303
+ self.class.instance_variable_get(:@fields).each { |field|
294
304
  begin
295
- vs = send(name)
305
+ vs = send(field.name)
296
306
  catch(:ignored) do
297
- __dump_field(vs, name, type, *args)
307
+ __dump_field(vs, field)
298
308
  end
299
309
  rescue
300
- STDERR.puts "#{self.class}: #{name}(#{type})"
310
+ STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
301
311
  raise
302
312
  end
303
313
  }
@@ -325,28 +335,57 @@ module LibBin
325
335
  self
326
336
  end
327
337
 
328
- def self.convert(input, output, input_big = LibBin::default_big?, output_big = !LibBin::default_big?, parent = nil, index = nil)
329
- h = self::new
330
- h.__convert(input, output, input_big, output_big, parent, index)
331
- h
338
+ def self.convert(input, output, input_big = LibBin::default_big?, output_big = !LibBin::default_big?, parent = nil, index = nil, length = nil)
339
+ if length
340
+ length.times.collect {
341
+ h = self::new
342
+ h.__load(input, input_big, parent, index)
343
+ }
344
+ else
345
+ h = self::new
346
+ h.__convert(input, output, input_big, output_big, parent, index)
347
+ end
332
348
  end
333
349
 
334
- def self.load(input, input_big = LibBin::default_big?, parent = nil, index = nil)
335
- h = self::new
336
- h.__load(input, input_big, parent, index)
337
- h
350
+ def self.load(input, input_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
351
+ if length
352
+ length.times.collect {
353
+ h = self::new
354
+ h.__load(input, input_big, parent, index)
355
+ }
356
+ else
357
+ h = self::new
358
+ h.__load(input, input_big, parent, index)
359
+ end
338
360
  end
339
361
 
340
- def self.dump(value, output, output_big = LibBin::default_big?, parent = nil, index = nil)
341
- value.__dump(output, output_big, parent, index)
362
+ def self.dump(value, output, output_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
363
+ if length
364
+ length.times.collect { |i|
365
+ value[i].__dump(output, output_big, parent, index)
366
+ }
367
+ value
368
+ else
369
+ value.__dump(output, output_big, parent, index)
370
+ end
342
371
  end
343
372
 
344
- def self.size(value, previous_offset = 0, parent = nil, index = nil)
345
- value.__shape(previous_offset, parent, index).size
373
+ def self.size(value, previous_offset = 0, parent = nil, index = nil, length = nil)
374
+ if length
375
+ shape(value, previous_offset, parent, index, length).size
376
+ else
377
+ value.__shape(previous_offset, parent, index).size
378
+ end
346
379
  end
347
380
 
348
- def self.shape(value, previous_offset = 0, parent = nil, index = nil, kind = DataShape)
349
- value.__shape(previous_offset, parent, index, kind = DataShape)
381
+ def self.shape(value, previous_offset = 0, parent = nil, index = nil, kind = DataShape, length = nil)
382
+ if length
383
+ kind::new(length.times.collect { |i|
384
+ value[i].__shape(previous_offset, parent, index, kind)
385
+ })
386
+ else
387
+ value.__shape(previous_offset, parent, index, kind)
388
+ end
350
389
  end
351
390
 
352
391
  end
data/libbin.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'libbin'
3
- s.version = "1.0.2"
3
+ s.version = "1.0.6"
4
4
  s.author = "Brice Videau"
5
5
  s.email = "brice.videau@imag.fr"
6
6
  s.homepage = "https://github.com/kerilk/libbin"
@@ -8,7 +8,6 @@ Gem::Specification.new do |s|
8
8
  s.description = "Read, write and convert Binary data in Ruby."
9
9
  s.files = Dir[ 'libbin.gemspec', 'LICENSE', 'lib/**/*.rb', 'ext/libbin/extconf.rb', 'ext/libbin/*.c', 'ext/libbin/*.h' ]
10
10
  s.extensions << 'ext/libbin/extconf.rb'
11
- s.has_rdoc = false
12
11
  s.license = 'BSD-2-Clause'
13
12
  s.required_ruby_version = '>= 2.0.0'
14
13
  s.add_dependency 'float-formats', '~> 0.3', '>=0.3.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libbin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brice Videau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-04 00:00:00.000000000 Z
11
+ date: 2021-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: float-formats
@@ -67,8 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  requirements: []
70
- rubyforge_project:
71
- rubygems_version: 2.7.6
70
+ rubygems_version: 3.1.2
72
71
  signing_key:
73
72
  specification_version: 4
74
73
  summary: Library for loading and converting binary files