Class: LibBin::DataConverter

Inherits:
Object
  • Object
show all
Includes:
Alignment
Defined in:
lib/libbin.rb,
lib/libbin/data_types.rb

Defined Under Namespace

Classes: Scalar, Str

Constant Summary collapse

SCALAR_TYPES =
{
 :c => [:Int8, :int8],
 :C => [:UInt8, :uint8],
 :s => [:Int16, :int16],
 :"s<" => [:Int16_LE, :int16_le],
 :"s>" => [:Int16_BE, :int16_be],
 :S => [:UInt16, :uint16],
 :"S<" => [:UInt16_LE, :uint16_le],
 :"S>" => [:UInt16_BE, :uint16_be],
 :v => [:UInt16_LE, :uint16_le],
 :n => [:UInt16_BE, :uint16_be],
 :l => [:Int32, :int32],
 :"l<" => [:Int32_LE, :int32_le],
 :"l>" => [:Int32_BE, :int32_be],
 :L => [:UInt32, :uint32],
 :"L<" => [:UInt32_LE, :uint32_le],
 :"L>" => [:UInt32_BE, :uint32_be],
 :V => [:UInt32_LE, :uint32_le],
 :N => [:UInt32_BE, :uint32_be],
 :q => [:Int64, :int64],
 :"q<" => [:Int64_LE, :int64_le],
 :"q>" => [:Int64_BE, :int64_be],
 :Q => [:UInt64, :uint64],
 :"Q<" => [:UInt64_LE, :uint64_le],
 :"Q>" => [:UInt64_BE, :uint64_be],
 :F => [:Flt, :float],
 :e => [:Flt_LE, :float_le],
 :g => [:Flt_BE, :float_be],
 :D => [:Double, :double],
 :E => [:Double_LE, :double_le],
 :G => [:Double_BE, :double_be],
 :half => [:Half, :half],
 :half_le => [:Half_LE, :half_le],
 :half_be => [:Half_BE, :half_be],
 :pghalf => [:PGHalf, :pghalf],
 :pghalf_le => [:PGHalf_LE, :pghalf_le],
 :pghalf_be => [:PGHalf_BE, :pghalf_be]
}
DATA_SIZES =
Hash::new { |h,k|
  if k.kind_of?(Symbol) && m = k.match(/a(\d+)/)
    m[1].to_i
  else
    nil
  end
}
DATA_ENDIAN =
{
  true => Hash::new { |h,k|
    if k.kind_of?(Symbol) && m = k.match(/a(\d+)/)
      l[k]
    else
      nil
    end
  },
  false => Hash::new { |h,k|
    if k.kind_of?(Symbol) && m = k.match(/a(\d+)/)
      l[k]
    else
      nil
    end
  }
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#__indexObject (readonly)

Returns the value of attribute __index.



29
30
31
# File 'lib/libbin.rb', line 29

def __index
  @__index
end

#__iteratorObject (readonly)

Returns the value of attribute __iterator.



30
31
32
# File 'lib/libbin.rb', line 30

def __iterator
  @__iterator
end

#__parentObject (readonly)

Returns the value of attribute __parent.



28
29
30
# File 'lib/libbin.rb', line 28

def __parent
  @__parent
end

#__positionObject (readonly)

Returns the value of attribute __position.



31
32
33
# File 'lib/libbin.rb', line 31

def __position
  @__position
end

Class Method Details

.convert(input, output, input_big = LibBin::default_big?, output_big = !LibBin::default_big?,, parent = nil, index = nil) ⇒ Object



328
329
330
331
332
# File 'lib/libbin.rb', line 328

def self.convert(input, output, input_big = LibBin::default_big?, output_big = !LibBin::default_big?, parent = nil, index = nil)
  h = self::new
  h.__convert(input, output, input_big, output_big, parent, index)
  h
end

.create_scalar_type(symbol) ⇒ Object



357
358
359
360
361
362
363
364
365
366
367
368
369
# File 'lib/libbin/data_types.rb', line 357

def self.create_scalar_type(symbol)
  klassname, name = SCALAR_TYPES[symbol]
  eval <<EOF
class #{klassname} < Scalar
  init(#{symbol.inspect})
end

def self.#{name}(field, count: nil, offset: nil, sequence: false, condition: nil)
  @fields.push([field, #{klassname}, count, offset, sequence, condition])
  attr_accessor field
end
EOF
end

.dump(value, output, output_big = LibBin::default_big?, parent = nil, index = nil) ⇒ Object



340
341
342
# File 'lib/libbin.rb', line 340

def self.dump(value, output, output_big = LibBin::default_big?, parent = nil, index = nil)
  value.__dump(output, output_big, parent, index)
end

.inherited(subclass) ⇒ Object



104
105
106
# File 'lib/libbin.rb', line 104

def self.inherited(subclass)
  subclass.instance_variable_set(:@fields, [])
end

.load(input, input_big = LibBin::default_big?, parent = nil, index = nil) ⇒ Object



334
335
336
337
338
# File 'lib/libbin.rb', line 334

def self.load(input, input_big = LibBin::default_big?, parent = nil, index = nil)
  h = self::new
  h.__load(input, input_big, parent, index)
  h
end

.register_field(field, type, count: nil, offset: nil, sequence: false, condition: nil) ⇒ Object



343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/libbin/data_types.rb', line 343

def self.register_field(field, type, count: nil, offset: nil, sequence: false, condition: nil)
  if type.kind_of?(Symbol)
    if type[0] == 'a'
      c = Class::new(Str) do init(sym) end
      @fields.push([field, c, count, offset, sequence, condition])
    else
      @fields.push([field, const_get(SCALAR_TYPES[type][0]), count, offset, sequence, condition])
    end
  else
    @fields.push([field, type, count, offset, sequence, condition])
  end
  attr_accessor field
end

.shape(value, previous_offset = 0, parent = nil, index = nil, kind = DataShape) ⇒ Object



348
349
350
# File 'lib/libbin.rb', line 348

def self.shape(value, previous_offset = 0, parent = nil, index = nil, kind = DataShape)
  value.__shape(previous_offset, parent, index, kind = DataShape)
end

.size(value, previous_offset = 0, parent = nil, index = nil) ⇒ Object



344
345
346
# File 'lib/libbin.rb', line 344

def self.size(value, previous_offset = 0, parent = nil, index = nil)
  value.__shape(previous_offset, parent, index).size
end

.string(field, length = nil, count: nil, offset: nil, sequence: false, condition: nil) ⇒ Object



404
405
406
407
408
409
410
411
# File 'lib/libbin/data_types.rb', line 404

def self.string( field, length = nil, count: nil, offset: nil, sequence: false, condition: nil)
  sym = (length ? :"a#{length}" : :"a*")
  c = Class::new(Str) do
    init(sym)
  end
  @fields.push([field, c, count, offset, sequence, condition])
  attr_accessor field
end

Instance Method Details

#__convert(input, output, input_big, output_big, parent = nil, index = nil) ⇒ Object



307
308
309
310
311
312
# File 'lib/libbin.rb', line 307

def __convert(input, output, input_big, output_big, parent = nil, index = nil)
  __set_convert_type(input, output, input_big, output_big, parent, index)
  __convert_fields
  __unset_convert_type
  self
end

#__convert_field(field, type, count, offset, sequence, condition) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/libbin.rb', line 180

def __convert_field(field, type, count, offset, sequence, condition)
  __decode_static_conditions(type, count, offset, sequence, condition)
  vs = @__count.times.collect do |it|
    @__iterator = it
    if __decode_dynamic_conditions(type, offset, sequence, condition)
      @__type::convert(@__input, @__output, @__input_big, @__output_big, self, it)
    else
      nil
    end
  end
  __restore_context
  vs = vs.first unless count
  vs
end

#__convert_fieldsObject



262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/libbin.rb', line 262

def __convert_fields
  self.class.instance_variable_get(:@fields).each { |name, type, *args|
    begin
      vs = catch(:ignored) do
        __convert_field(name, type, *args)
      end
      send("#{name}=", vs)
    rescue
      STDERR.puts "#{self.class}: #{name}(#{type})"
      raise
    end
  }
  self
end

#__decode_condition(condition) ⇒ Object



130
131
132
133
# File 'lib/libbin.rb', line 130

def __decode_condition(condition)
  return true unless condition
  __decode_expression(condition)
end

#__decode_count(count) ⇒ Object



135
136
137
138
# File 'lib/libbin.rb', line 135

def __decode_count(count)
  return 1 unless count
  __decode_expression(count)
end

#__decode_dynamic_conditions(type, offset, sequence, condition) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/libbin.rb', line 159

def __decode_dynamic_conditions(type, offset, sequence, condition)
  return true unless sequence
  @__offset = nil
  @__condition = nil
  @__type = nil
  @__offset = __decode_seek_offset(offset)
  return false if @__offset == false
  @__condition = __decode_condition(condition)
  return false unless @__condition
  @__type = __decode_type(type)
  return true
end

#__decode_expression(sym) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
# File 'lib/libbin.rb', line 108

def __decode_expression(sym)
  case sym
  when Proc
    return sym.call
  when String
    exp = sym.gsub("..","__parent").gsub("\\",".")
    return eval(exp)
  else
    return sym
  end
end

#__decode_seek_offset(offset) ⇒ Object



120
121
122
123
124
125
126
127
128
# File 'lib/libbin.rb', line 120

def __decode_seek_offset(offset)
  return nil unless offset
  offset = __decode_expression(offset)
  return false if offset == 0x0
  @__cur_position = offset
  @__input.seek(offset) if @__input
  @__output.seek(offset) if @__output
  offset
end

#__decode_static_conditions(type, count, offset, sequence, condition) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/libbin.rb', line 144

def __decode_static_conditions(type, count, offset, sequence, condition)
  @__offset = nil
  @__condition = nil
  @__type = nil
  @__count = nil
  unless sequence
    @__offset = __decode_seek_offset(offset)
    throw :ignored, nil if @__offset == false
    @__condition = __decode_condition(condition)
    throw :ignored, nil unless @__condition
    @__type = __decode_type(type)
  end
  @__count = __decode_count(count)
end

#__decode_type(type) ⇒ Object



140
141
142
# File 'lib/libbin.rb', line 140

def __decode_type(type)
  return __decode_expression(type)
end

#__dump(output, output_big, parent = nil, index = nil) ⇒ Object



321
322
323
324
325
326
# File 'lib/libbin.rb', line 321

def __dump(output, output_big, parent = nil, index = nil)
  __set_dump_type(output, output_big, parent, index)
  __dump_fields
  __unset_dump_type
  self
end

#__dump_field(vs, field, type, count, offset, sequence, condition) ⇒ Object



210
211
212
213
214
215
216
217
218
219
220
# File 'lib/libbin.rb', line 210

def __dump_field(vs, field, type, count, offset, sequence, condition)
  __decode_static_conditions(type, count, offset, sequence, condition)
  vs = [vs] unless count
  vs.each_with_index do |v, it|
    @__iterator = it
    if __decode_dynamic_conditions(type, offset, sequence, condition)
      @__type::dump(v, @__output, @__output_big, self, it)
    end
  end
  __restore_context
end

#__dump_fieldsObject



292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/libbin.rb', line 292

def __dump_fields
  self.class.instance_variable_get(:@fields).each { |name, type, *args|
    begin
      vs = send(name)
      catch(:ignored) do
        __dump_field(vs, name, type, *args)
      end
    rescue
      STDERR.puts "#{self.class}: #{name}(#{type})"
      raise
    end
  }
  self
end

#__load(input, input_big, parent = nil, index = nil) ⇒ Object



314
315
316
317
318
319
# File 'lib/libbin.rb', line 314

def __load(input, input_big, parent = nil, index = nil)
  __set_load_type(input, input_big, parent, index)
  __load_fields
  __unset_load_type
  self
end

#__load_field(field, type, count, offset, sequence, condition) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/libbin.rb', line 195

def __load_field(field, type, count, offset, sequence, condition)
  __decode_static_conditions(type, count, offset, sequence, condition)
  vs = @__count.times.collect do |it|
    @__iterator = it
    if __decode_dynamic_conditions(type, offset, sequence, condition)
      @__type::load(@__input, @__input_big, self, it)
    else
      nil
    end
  end
  __restore_context
  vs = vs.first unless count
  vs
end

#__load_fieldsObject



277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/libbin.rb', line 277

def __load_fields
  self.class.instance_variable_get(:@fields).each { |name, type, *args|
    begin
      vs = catch(:ignored) do
        __load_field(name, type, *args)
      end
      send("#{name}=", vs)
    rescue
      STDERR.puts "#{self.class}: #{name}(#{type})"
      raise
    end
  }
  self
end

#__restore_contextObject



172
173
174
175
176
177
178
# File 'lib/libbin.rb', line 172

def __restore_context
  @__iterator = nil
  @__type = nil
  @__count = nil
  @__offset = nil
  @__condition = nil
end

#__set_convert_type(input, output, input_big, output_big, parent, index) ⇒ Object



32
33
34
35
36
37
38
39
40
41
# File 'lib/libbin.rb', line 32

def __set_convert_type(input, output, input_big, output_big, parent, index)
  @__input_big = input_big
  @__output_big = output_big
  @__input = input
  @__output = output
  @__parent = parent
  @__index = index
  @__position = input.tell
  @__cur_position = @__position
end

#__set_dump_type(output, output_big, parent, index) ⇒ Object



59
60
61
62
63
64
65
66
# File 'lib/libbin.rb', line 59

def __set_dump_type(output, output_big, parent, index)
  @__output_big = output_big
  @__output = output
  @__parent = parent
  @__index = index
  @__position = output.tell
  @__cur_position = @__position
end

#__set_load_type(input, input_big, parent, index) ⇒ Object



50
51
52
53
54
55
56
57
# File 'lib/libbin.rb', line 50

def __set_load_type(input, input_big, parent, index)
  @__input_big = input_big
  @__input = input
  @__parent = parent
  @__index = index
  @__position = input.tell
  @__cur_position = @__position
end

#__set_size_type(position, parent, index) ⇒ Object



43
44
45
46
47
48
# File 'lib/libbin.rb', line 43

def __set_size_type(position, parent, index)
  @__parent = parent
  @__index = index
  @__position = position
  @__cur_position = @__position
end

#__shape(previous_offset = 0, parent = nil, index = nil, kind = DataShape) ⇒ Object



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/libbin.rb', line 242

def __shape(previous_offset = 0, parent = nil, index = nil, kind = DataShape)
  __set_size_type(previous_offset, parent, index)
  members = {}
  self.class.instance_variable_get(:@fields).each { |name, type, *args|
    begin
      vs = send(name)
      member = catch(:ignored) do
        __shape_field(vs, previous_offset, kind, name, type, *args)
      end
      members[name] = member
    rescue
      STDERR.puts "#{self.class}: #{name}(#{type})"
      raise
    end
  }
  __unset_size_type
  return nil if members.values.flatten.compact.size <= 0
  kind::new(members)
end

#__shape_field(vs, previous_offset, kind, field, type, count, offset, sequence, condition) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/libbin.rb', line 222

def __shape_field(vs, previous_offset, kind, field, type, count, offset, sequence, condition)
  __decode_static_conditions(type, count, offset, sequence, condition)
  vs = [vs] unless count
  vs = vs.each_with_index.collect do |v, it|
    @__iterator = it
    if __decode_dynamic_conditions(type, offset, sequence, condition)
      sh = @__type::shape(v, @__cur_position, self, it, kind)
      @__cur_position = sh.last + 1 if sh.last && sh.last >= 0
      sh
    end
  end
  __restore_context
  vs = vs.first unless count
  vs
end

#__size(previous_offset = 0, parent = nil, index = nil) ⇒ Object



238
239
240
# File 'lib/libbin.rb', line 238

def __size(previous_offset = 0, parent = nil, index = nil)
  __shape(previous_offset, parent, index, DataRange).size
end

#__unset_convert_typeObject



68
69
70
71
72
73
74
75
76
77
# File 'lib/libbin.rb', line 68

def __unset_convert_type
  @__input_big = nil
  @__output_big = nil
  @__input = nil
  @__output = nil
  @__parent = nil
  @__index = nil
  @__position = nil
  @__cur_position = nil
end

#__unset_dump_typeObject



95
96
97
98
99
100
101
102
# File 'lib/libbin.rb', line 95

def __unset_dump_type
  @__output_big = nil
  @__output = nil
  @__parent = nil
  @__index = nil
  @__position = nil
  @__cur_position = nil
end

#__unset_load_typeObject



86
87
88
89
90
91
92
93
# File 'lib/libbin.rb', line 86

def __unset_load_type
  @__input_big = nil
  @__input = nil
  @__parent = nil
  @__index = nil
  @__position = nil
  @__cur_position = nil
end

#__unset_size_typeObject



79
80
81
82
83
84
# File 'lib/libbin.rb', line 79

def __unset_size_type
  @__parent = nil
  @__index = nil
  @__position = nil
  @__cur_position = nil
end

#inspectObject



24
25
26
# File 'lib/libbin.rb', line 24

def inspect
  to_s
end