libbin 1.0.7 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,12 @@
1
+ #ifndef LIBBIN_C_H__
2
+ #define LIBBIN_C_H__
3
+ #include "./half.h"
4
+ #include "./pghalf.h"
5
+ #include "./libbin_endian.h"
6
+ #include "./data_types.h"
7
+
8
+
9
+ extern VALUE mLibBin;
10
+ extern VALUE cField;
11
+
12
+ #endif
@@ -0,0 +1,126 @@
1
+ #ifndef LIBBIN_ENDIAN_H__
2
+ #define LIBBIN_ENDIAN_H__
3
+
4
+ #include <stdint.h>
5
+
6
+ static inline void little_big_swap(void *addr, size_t sz) {
7
+ char *p = (char *)addr;
8
+ for (size_t i = 0, j = sz - 1; i < (sz >> 1); i++, j--) {
9
+ char tmp = p[i];
10
+ p[i] = p[j];
11
+ p[j] = tmp;
12
+ }
13
+ }
14
+ #define LITTLE_BIG_SWAP(val) little_big_swap(&(val), sizeof(val))
15
+
16
+ static inline unsigned is_little_endian(void)
17
+ {
18
+ const union { unsigned u; unsigned char c[4]; } one = { 1 };
19
+ return one.c[0];
20
+ }
21
+
22
+ /* https://stackoverflow.com/a/2182184 */
23
+ static inline uint8_t bswap_uint8(uint8_t x) {
24
+ return x;
25
+ }
26
+
27
+ static inline uint16_t bswap_uint16(uint16_t x) {
28
+ return ((( x & 0xff00u ) >> 8 ) |
29
+ (( x & 0x00ffu ) << 8 ));
30
+ }
31
+
32
+ static inline uint32_t bswap_uint32(uint32_t x) {
33
+ return ((( x & 0xff000000u ) >> 24 ) |
34
+ (( x & 0x00ff0000u ) >> 8 ) |
35
+ (( x & 0x0000ff00u ) << 8 ) |
36
+ (( x & 0x000000ffu ) << 24 ));
37
+ }
38
+
39
+ static inline uint64_t bswap_uint64(uint64_t x) {
40
+ return ((( x & 0xff00000000000000ull ) >> 56 ) |
41
+ (( x & 0x00ff000000000000ull ) >> 40 ) |
42
+ (( x & 0x0000ff0000000000ull ) >> 24 ) |
43
+ (( x & 0x000000ff00000000ull ) >> 8 ) |
44
+ (( x & 0x00000000ff000000ull ) << 8 ) |
45
+ (( x & 0x0000000000ff0000ull ) << 24 ) |
46
+ (( x & 0x000000000000ff00ull ) << 40 ) |
47
+ (( x & 0x00000000000000ffull ) << 56 ));
48
+ }
49
+
50
+
51
+
52
+ #define SWAP_CONVERT(TYPE, MAPPED_NAME, MAPPED_TYPE) \
53
+ do { \
54
+ union { TYPE t; MAPPED_TYPE m; } v = { .m = x }; \
55
+ v.m = bswap_ ## MAPPED_NAME(v.m); \
56
+ return v.t; \
57
+ } while (0)
58
+
59
+ #define CONVERT(TYPE, MAPPED_TYPE) \
60
+ do { \
61
+ union { TYPE t; MAPPED_TYPE m; } v = { .m = x }; \
62
+ return v.t; \
63
+ } while (0)
64
+
65
+ #define CONVERT_SWAP(TYPE, MAPPED_NAME, MAPPED_TYPE) \
66
+ do { \
67
+ union { TYPE t; MAPPED_TYPE m; } v = { .t = x }; \
68
+ v.m = bswap_ ## MAPPED_NAME(v.m); \
69
+ return v.m; \
70
+ } while(0)
71
+
72
+ #define UNPACKER_BE(NAME, TYPE, MAPPED_NAME, MAPPED_TYPE) \
73
+ static inline TYPE unpack_ ## NAME ## _be(MAPPED_TYPE x) { \
74
+ if (is_little_endian()) \
75
+ SWAP_CONVERT(TYPE, MAPPED_NAME, MAPPED_TYPE); \
76
+ else \
77
+ CONVERT(TYPE, MAPPED_TYPE); \
78
+ }
79
+
80
+ #define UNPACKER_LE(NAME, TYPE, MAPPED_NAME, MAPPED_TYPE) \
81
+ static inline TYPE unpack_ ## NAME ## _le(MAPPED_TYPE x) { \
82
+ if (is_little_endian()) \
83
+ CONVERT(TYPE, MAPPED_TYPE); \
84
+ else \
85
+ SWAP_CONVERT(TYPE, MAPPED_NAME, MAPPED_TYPE); \
86
+ }
87
+
88
+ #define PACKER_BE(NAME, TYPE, MAPPED_NAME, MAPPED_TYPE) \
89
+ static inline MAPPED_TYPE pack_ ## NAME ## _be(TYPE x) { \
90
+ if (is_little_endian()) \
91
+ CONVERT_SWAP(TYPE, MAPPED_NAME, MAPPED_TYPE); \
92
+ else \
93
+ CONVERT(MAPPED_TYPE, TYPE); \
94
+ }
95
+
96
+ #define PACKER_LE(NAME, TYPE, MAPPED_NAME, MAPPED_TYPE) \
97
+ static inline MAPPED_TYPE pack_ ## NAME ## _le(TYPE x) { \
98
+ if (is_little_endian()) \
99
+ CONVERT(MAPPED_TYPE, TYPE); \
100
+ else \
101
+ CONVERT_SWAP(TYPE, MAPPED_NAME, MAPPED_TYPE); \
102
+ }
103
+
104
+ #define CONVERTER_TYPE(NAME, TYPE, MAPPED_NAME, MAPPED_TYPE) \
105
+ UNPACKER_BE(NAME, TYPE, MAPPED_NAME, MAPPED_TYPE) \
106
+ UNPACKER_LE(NAME, TYPE, MAPPED_NAME, MAPPED_TYPE) \
107
+ PACKER_BE(NAME, TYPE, MAPPED_NAME, MAPPED_TYPE) \
108
+ PACKER_LE(NAME, TYPE, MAPPED_NAME, MAPPED_TYPE)
109
+
110
+ #define CONVERTER(NAME, TYPE, SIZE) \
111
+ CONVERTER_TYPE(NAME, TYPE, uint ## SIZE, uint ## SIZE ## _t)
112
+
113
+ CONVERTER(uint8, uint8_t, 8)
114
+ CONVERTER(int8, int8_t, 8)
115
+ CONVERTER(uint16, uint16_t, 16)
116
+ CONVERTER(int16, int16_t, 16)
117
+ CONVERTER(uint32, uint32_t, 32)
118
+ CONVERTER(int32, int32_t, 32)
119
+ CONVERTER(uint64, uint64_t, 64)
120
+ CONVERTER(int64, int64_t, 64)
121
+ CONVERTER(float, float, 32)
122
+ CONVERTER(double, double, 64)
123
+ CONVERTER(half, uint16_t, 16)
124
+ CONVERTER(pghalf, uint16_t, 16)
125
+
126
+ #endif
@@ -27,7 +27,11 @@ module LibBin
27
27
  @members = nil
28
28
  else
29
29
  @members = args[0]
30
- @range = @members.values.flatten.compact.collect(&:range).reduce(:+)
30
+ if @members.kind_of?(Hash)
31
+ @range = @members.values.compact.collect(&:range).reduce(:+)
32
+ else
33
+ @range = @members.compact.collect(&:range).reduce(:+)
34
+ end
31
35
  end
32
36
  end
33
37
 
@@ -53,7 +57,11 @@ module LibBin
53
57
  if args.length == 2
54
58
  @range = Range::new(args[0], args[1])
55
59
  else
56
- @range = args[0].values.flatten.compact.collect(&:range).reduce(:+)
60
+ if args[0].kind_of?(Hash)
61
+ @range = args[0].values.compact.collect(&:range).reduce(:+)
62
+ else
63
+ @range = args[0].compact.collect(&:range).reduce(:+)
64
+ end
57
65
  end
58
66
  end
59
67
 
@@ -71,58 +79,38 @@ module LibBin
71
79
 
72
80
  end
73
81
 
74
- class Field
75
- attr_reader :name,
76
- :type,
77
- :length,
78
- :count,
79
- :offset,
80
- :sequence,
81
- :condition
82
-
83
- def sequence?
84
- @sequence
85
- end
86
-
87
- def relative_offset?
88
- @relative_offset
89
- end
90
-
91
- def initialize(name, type, length, count, offset, sequence, condition, relative_offset)
92
- @name = name
93
- @type = type
94
- @length = length
95
- @count = count
96
- @offset = offset
97
- @sequence = sequence
98
- @condition = condition
99
- @relative_offset = relative_offset
100
- end
101
-
102
- end
82
+ # class Field
83
+ # attr_reader :name,
84
+ # :type,
85
+ # :length,
86
+ # :count,
87
+ # :offset,
88
+ # :sequence,
89
+ # :condition
90
+ #
91
+ # def sequence?
92
+ # @sequence
93
+ # end
94
+ #
95
+ # def relative_offset?
96
+ # @relative_offset
97
+ # end
98
+ #
99
+ # def initialize(name, type, length, count, offset, sequence, condition, relative_offset)
100
+ # @name = name
101
+ # @type = type
102
+ # @length = length
103
+ # @count = count
104
+ # @offset = offset
105
+ # @sequence = sequence
106
+ # @condition = condition
107
+ # @relative_offset = relative_offset
108
+ # end
109
+ #
110
+ # end
103
111
 
104
112
  class DataConverter
105
113
 
106
- rl = lambda { |type, str, number = nil|
107
- if number
108
- str.unpack(type.to_s+number.to_s)
109
- else
110
- str.unpack(type.to_s).first
111
- end
112
- }
113
-
114
- sl = lambda { |type, value, number = nil|
115
- if number
116
- value.pack(type.to_s+number.to_s)
117
- else
118
- [value].pack(type.to_s)
119
- end
120
- }
121
-
122
- l = lambda { |type|
123
- [rl.curry[type], sl.curry[type]]
124
- }
125
-
126
114
  SCALAR_TYPES = {
127
115
  :c => [:Int8, :int8],
128
116
  :C => [:UInt8, :uint8],
@@ -160,271 +148,12 @@ module LibBin
160
148
  :pghalf => [:PGHalf, :pghalf],
161
149
  :pghalf_le => [:PGHalf_LE, :pghalf_le],
162
150
  :pghalf_be => [:PGHalf_BE, :pghalf_be]
163
- }
164
-
165
- DATA_SIZES = Hash::new { |h,k|
166
- if k.kind_of?(Symbol) && m = k.match(/a(\d+)/)
167
- m[1].to_i
168
- else
169
- nil
170
- end
171
- }
172
- DATA_SIZES.merge!( {
173
- :c => 1,
174
- :C => 1,
175
- :s => 2,
176
- :"s<" => 2,
177
- :"s>" => 2,
178
- :S => 2,
179
- :"S<" => 2,
180
- :"S>" => 2,
181
- :v => 2,
182
- :n => 2,
183
- :l => 4,
184
- :"l<" => 4,
185
- :"l>" => 4,
186
- :L => 4,
187
- :"L<" => 4,
188
- :"L>" => 4,
189
- :V => 4,
190
- :N => 4,
191
- :q => 8,
192
- :"q<" => 8,
193
- :"q>" => 8,
194
- :Q => 8,
195
- :"Q<" => 8,
196
- :"Q>" => 8,
197
- :F => 4,
198
- :e => 4,
199
- :g => 4,
200
- :D => 8,
201
- :E => 8,
202
- :G => 8,
203
- :a => 1,
204
- :"a*" => -1,
205
- :half => 2,
206
- :half_le => 2,
207
- :half_be => 2,
208
- :pghalf => 2,
209
- :pghalf_le => 2,
210
- :pghalf_be => 2
211
- } )
212
- DATA_ENDIAN = {
213
- true => Hash::new { |h,k|
214
- if k.kind_of?(Symbol) && m = k.match(/a(\d+)/)
215
- l[k]
216
- else
217
- nil
218
- end
219
- },
220
- false => Hash::new { |h,k|
221
- if k.kind_of?(Symbol) && m = k.match(/a(\d+)/)
222
- l[k]
223
- else
224
- nil
225
- end
226
- }
227
- }
228
-
229
- rhl = lambda { |type, str, number = nil|
230
- if number
231
- number.times.collect { |i| LibBin::half_from_string(str[i*2,2], type) }
232
- else
233
- LibBin::half_from_string(str, type)
234
- end
235
- }
236
-
237
- shl = lambda { |type, value, number = nil|
238
- if number
239
- str = ""
240
- number.times { |i| str << LibBin::half_to_string(value[i], type) }
241
- str
242
- else
243
- LibBin::half_to_string(value, type)
244
- end
245
- }
246
-
247
- hl = lambda { |type|
248
- [rhl.curry[type], shl.curry[type]]
249
- }
250
-
251
- rpghl = lambda { |type, str, number = nil|
252
- if number
253
- number.times.collect { |i| LibBin::pghalf_from_string(str[i*2,2], type) }
254
- else
255
- LibBin::pghalf_from_string(str, type)
256
- end
257
151
  }
258
152
 
259
- spghl = lambda { |type, value, number = nil|
260
- if number
261
- str = ""
262
- number.times { |i| str << LibBin::pghalf_to_string(value[i], type) }
263
- str
264
- else
265
- LibBin::pghalf_to_string(value, type)
266
- end
267
- }
268
-
269
- pghl = lambda { |type|
270
- [rpghl.curry[type], spghl.curry[type]]
271
- }
272
-
273
- DATA_ENDIAN[true].merge!( {
274
- :c => l["c"],
275
- :C => l["C"],
276
- :s => l["s>"],
277
- :"s<" => l["s<"],
278
- :"s>" => l["s>"],
279
- :S => l["S>"],
280
- :"S<" => l["S<"],
281
- :"S>" => l["S>"],
282
- :v => l["v"],
283
- :n => l["n"],
284
- :l => l["l>"],
285
- :"l<" => l["l<"],
286
- :"l>" => l["l>"],
287
- :L => l["L>"],
288
- :"L<" => l["L<"],
289
- :"L>" => l["L>"],
290
- :V => l["V"],
291
- :N => l["N"],
292
- :q => l["q>"],
293
- :"q<" => l["q<"],
294
- :"q>" => l["q>"],
295
- :Q => l["Q>"],
296
- :"Q<" => l["Q<"],
297
- :"Q>" => l["Q>"],
298
- :F => l["g"],
299
- :e => l["e"],
300
- :g => l["g"],
301
- :D => l["G"],
302
- :E => l["E"],
303
- :G => l["G"],
304
- :half => hl["S>"],
305
- :half_le => hl["S<"],
306
- :half_be => hl["S>"],
307
- :pghalf => pghl["S>"],
308
- :pghalf_le => pghl["S<"],
309
- :pghalf_be => pghl["S>"]
310
- } )
311
- DATA_ENDIAN[false].merge!( {
312
- :c => l["c"],
313
- :C => l["C"],
314
- :s => l["s<"],
315
- :"s<" => l["s<"],
316
- :"s>" => l["s>"],
317
- :S => l["S<"],
318
- :"S<" => l["S<"],
319
- :"S>" => l["S>"],
320
- :v => l["v"],
321
- :n => l["n"],
322
- :l => l["l<"],
323
- :"l<" => l["l<"],
324
- :"l>" => l["l>"],
325
- :L => l["L<"],
326
- :"L<" => l["L<"],
327
- :"L>" => l["L>"],
328
- :V => l["V"],
329
- :N => l["N"],
330
- :q => l["q<"],
331
- :"q<" => l["q<"],
332
- :"q>" => l["q>"],
333
- :Q => l["Q<"],
334
- :"Q<" => l["Q<"],
335
- :"Q>" => l["Q>"],
336
- :F => l["e"],
337
- :e => l["e"],
338
- :g => l["g"],
339
- :D => l["E"],
340
- :E => l["E"],
341
- :G => l["G"],
342
- :half => hl["S<"],
343
- :half_le => hl["S<"],
344
- :half_be => hl["S>"],
345
- :pghalf => pghl["S<"],
346
- :pghalf_le => pghl["S<"],
347
- :pghalf_be => pghl["S>"]
348
- } )
349
-
350
-
351
- class Scalar
352
-
353
- def self.size(*args)
354
- @size
355
- end
356
-
357
- def self.shape(value, previous_offset = 0, _ = nil, _ = nil, kind = DataShape, length = nil)
358
- length = 1 unless length
359
- kind::new(previous_offset, previous_offset - 1 + length * @size)
360
- end
361
-
362
- def self.init(symbol)
363
- @symbol = symbol
364
- @size = DATA_SIZES[symbol]
365
- @rl_be, @sl_be = DATA_ENDIAN[true][symbol]
366
- @rl_le, @sl_le = DATA_ENDIAN[false][symbol]
367
- end
368
-
369
- def self.load(input, input_big = LibBin::default_big?, _ = nil, _ = nil, length = nil)
370
- l = (length ? length : 1)
371
- str = input.read(@size*l)
372
- input_big ? @rl_be[str, length] : @rl_le[str, length]
373
- end
374
-
375
- def self.dump(value, output, output_big = LibBin::default_big?, _ = nil, _ = nil, length = nil)
376
- str = (output_big ? @sl_be[value, length] : @sl_le[value, length])
377
- output.write(str)
378
- end
379
-
380
- def self.convert(input, output, input_big = LibBin::default_big?, output_big = !input_big, _ = nil, _ = nil, length = nil)
381
- l = (length ? length : 1)
382
- str = input.read(@size*l)
383
- value = (input_big ? @rl_be[str, length] : @rl_le[str, length])
384
- str = (output_big ? @sl_be[value, length] : @sl_le[value, length])
385
- output.write(str)
386
- value
387
- end
388
-
389
- end
390
-
391
- class Str < Scalar
392
-
393
- def self.size(value, previous_offset = 0, parent = nil, index = nil, length = nil)
394
- length ? length : value.size
395
- end
396
-
397
- def self.load(input, input_big = LibBin::default_big?, _ = nil, _ = nil, length = nil)
398
- str = (length ? input.read(length) : input.readline("\x00"))
399
- end
400
-
401
- def self.convert(input, output, input_big = LibBin::default_big?, output_big = !LibBin::default_big, _ = nil, _ = nil, length = nil)
402
- str = (length ? input.read(length) : input.readline("\x00"))
403
- output.write(str)
404
- str
405
- end
406
-
407
- def self.shape(value, previous_offset = 0, _ = nil, _ = nil, kind = DataShape, length = nil)
408
- if length
409
- kind::new(previous_offset, previous_offset + length - 1)
410
- else
411
- kind::new(previous_offset, previous_offset + value.size - 1)
412
- end
413
- end
414
-
415
- def self.dump(value, output, output_big = LibBin::default_big?, _ = nil, _ = nil, length = nil)
416
- if length
417
- output.write([value].pack("Z#{length}"))
418
- else
419
- output.write(value)
420
- end
421
- end
422
- end
423
-
424
153
  def self.register_field(field, type, length: nil, count: nil, offset: nil, sequence: false, condition: nil, relative_offset: false)
425
154
  if type.kind_of?(Symbol)
426
155
  if type[0] == 'a'
427
- real_type = Class::new(Str) do init(sym) end
156
+ real_type = Str
428
157
  else
429
158
  real_type = const_get(SCALAR_TYPES[type][0])
430
159
  end
@@ -435,13 +164,9 @@ module LibBin
435
164
  attr_accessor field
436
165
  end
437
166
 
438
- def self.create_scalar_type(symbol)
167
+ def self.create_scalar_accessor(symbol)
439
168
  klassname, name = SCALAR_TYPES[symbol]
440
169
  eval <<EOF
441
- class #{klassname} < Scalar
442
- init(#{symbol.inspect})
443
- end
444
-
445
170
  def self.#{name}(field, length: nil, count: nil, offset: nil, sequence: false, condition: nil, relative_offset: false)
446
171
  @fields.push(Field::new(field, #{klassname}, length, count, offset, sequence, condition, relative_offset))
447
172
  attr_accessor field
@@ -449,45 +174,23 @@ module LibBin
449
174
  EOF
450
175
  end
451
176
 
452
- create_scalar_type(:c)
453
- create_scalar_type(:C)
454
- create_scalar_type(:s)
455
- create_scalar_type(:"s<")
456
- create_scalar_type(:"s>")
457
- create_scalar_type(:S)
458
- create_scalar_type(:"S<")
459
- create_scalar_type(:"S>")
460
- create_scalar_type(:l)
461
- create_scalar_type(:"l<")
462
- create_scalar_type(:"l>")
463
- create_scalar_type(:L)
464
- create_scalar_type(:"L<")
465
- create_scalar_type(:"L>")
466
- create_scalar_type(:q)
467
- create_scalar_type(:"q<")
468
- create_scalar_type(:"q>")
469
- create_scalar_type(:Q)
470
- create_scalar_type(:"Q<")
471
- create_scalar_type(:"Q>")
472
- create_scalar_type(:F)
473
- create_scalar_type(:e)
474
- create_scalar_type(:g)
475
- create_scalar_type(:D)
476
- create_scalar_type(:E)
477
- create_scalar_type(:G)
478
- create_scalar_type(:half)
479
- create_scalar_type(:half_le)
480
- create_scalar_type(:half_be)
481
- create_scalar_type(:pghalf)
482
- create_scalar_type(:pghalf_le)
483
- create_scalar_type(:pghalf_be)
177
+ [:c,
178
+ :C,
179
+ :s, :"s<", :"s>",
180
+ :S, :"S<", :"S>",
181
+ :l, :"l<", :"l>",
182
+ :L, :"L<", :"L>",
183
+ :q, :"q<", :"q>",
184
+ :Q, :"Q<", :"Q>",
185
+ :F, :e, :g,
186
+ :D, :E, :G,
187
+ :half, :half_le, :half_be,
188
+ :pghalf, :pghalf_le, :pghalf_be].each { |c|
189
+ create_scalar_accessor(c)
190
+ }
484
191
 
485
192
  def self.string( field, length = nil, count: nil, offset: nil, sequence: false, condition: nil, relative_offset: false)
486
- sym = (length ? :"a" : :"a*")
487
- c = Class::new(Str) do
488
- init(sym)
489
- end
490
- @fields.push(Field::new(field, c, length, count, offset, sequence, condition, relative_offset))
193
+ @fields.push(Field::new(field, Str, length, count, offset, sequence, condition, relative_offset))
491
194
  attr_accessor field
492
195
  end
493
196