class LibBin::DataConverter

Constants

DATA_ENDIAN
DATA_SIZES
SCALAR_TYPES

Attributes

__index[R]
__iterator[R]
__parent[R]
__position[R]

Public Class Methods

convert(input, output, input_big = LibBin::default_big?, output_big = !LibBin::default_big?, parent = nil, index = nil, length = nil) click to toggle source
# File lib/libbin.rb, line 338
def self.convert(input, output, input_big = LibBin::default_big?, output_big = !LibBin::default_big?, parent = nil, index = nil, length = nil)
  if length
    length.times.collect {
      h = self::new
      h.__load(input, input_big, parent, index)
    }
  else
    h = self::new
    h.__convert(input, output, input_big, output_big, parent, index)
  end
end
create_scalar_type(symbol) click to toggle source
# File lib/libbin/data_types.rb, line 433
    def self.create_scalar_type(symbol)
      klassname, name = SCALAR_TYPES[symbol]
      eval <<EOF
    class #{klassname} < Scalar
      init(#{symbol.inspect})
    end

    def self.#{name}(field, length: nil, count: nil, offset: nil, sequence: false, condition: nil, relative_offset: false)
      @fields.push(Field::new(field, #{klassname}, length, count, offset, sequence, condition, relative_offset))
      attr_accessor field
    end
EOF
    end
dump(value, output, output_big = LibBin::default_big?, parent = nil, index = nil, length = nil) click to toggle source
# File lib/libbin.rb, line 362
def self.dump(value, output, output_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
  if length
    length.times.collect { |i|
      value[i].__dump(output, output_big, parent, index)
    }
    value
  else
    value.__dump(output, output_big, parent, index)
  end
end
inherited(subclass) click to toggle source
# 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, length = nil) click to toggle source
# File lib/libbin.rb, line 350
def self.load(input, input_big = LibBin::default_big?, parent = nil, index = nil, length = nil)
  if length
    length.times.collect {
      h = self::new
      h.__load(input, input_big, parent, index)
    }
  else
    h = self::new
    h.__load(input, input_big, parent, index)
  end
end
register_field(field, type, length: nil, count: nil, offset: nil, sequence: false, condition: nil, relative_offset: false) click to toggle source
# File lib/libbin/data_types.rb, line 419
def self.register_field(field, type, length: nil, count: nil, offset: nil, sequence: false, condition: nil, relative_offset: false)
  if type.kind_of?(Symbol)
    if type[0] == 'a'
      real_type = Class::new(Str) do init(sym) end
    else
      real_type = const_get(SCALAR_TYPES[type][0])
    end
  else
    real_type = type
  end
  @fields.push(Field::new(field, real_type, length, count, offset, sequence, condition, relative_offset))
  attr_accessor field
end
shape(value, previous_offset = 0, parent = nil, index = nil, kind = DataShape, length = nil) click to toggle source
# File lib/libbin.rb, line 381
def self.shape(value, previous_offset = 0, parent = nil, index = nil, kind = DataShape, length = nil)
  if length
    kind::new(length.times.collect { |i|
      value[i].__shape(previous_offset, parent, index, kind)
    })
  else
    value.__shape(previous_offset, parent, index, kind)
  end
end
size(value, previous_offset = 0, parent = nil, index = nil, length = nil) click to toggle source
# File lib/libbin.rb, line 373
def self.size(value, previous_offset = 0, parent = nil, index = nil, length = nil)
  if length
    shape(value, previous_offset, parent, index, length).size
  else
    value.__shape(previous_offset, parent, index).size
  end
end
string( field, length = nil, count: nil, offset: nil, sequence: false, condition: nil, relative_offset: false) click to toggle source
# File lib/libbin/data_types.rb, line 480
def self.string( field, length = nil, count: nil, offset: nil, sequence: false, condition: nil, relative_offset: false)
  sym = (length ? :"a" : :"a*")
  c = Class::new(Str) do
    init(sym)
  end
  @fields.push(Field::new(field, c, length, count, offset, sequence, condition, relative_offset))
  attr_accessor field
end

Public Instance Methods

__convert(input, output, input_big, output_big, parent = nil, index = nil) click to toggle source
# File lib/libbin.rb, line 317
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) click to toggle source
# File lib/libbin.rb, line 190
def __convert_field(field)
  __decode_static_conditions(field)
  vs = @__count.times.collect do |it|
    @__iterator = it
    if __decode_dynamic_conditions(field)
      @__type::convert(@__input, @__output, @__input_big, @__output_big, self, it, @__length)
    else
      nil
    end
  end
  __restore_context
  vs = vs.first unless field.count
  vs
end
__convert_fields() click to toggle source
# File lib/libbin.rb, line 272
def __convert_fields
  self.class.instance_variable_get(:@fields).each { |field|
    begin
      vs = catch(:ignored) do
        __convert_field(field)
      end
      send("#{field.name}=", vs)
    rescue
      STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
      raise
    end
  }
  self
end
__decode_condition(condition) click to toggle source
# File lib/libbin.rb, line 131
def __decode_condition(condition)
  return true unless condition
  __decode_expression(condition)
end
__decode_count(count) click to toggle source
# File lib/libbin.rb, line 136
def __decode_count(count)
  return 1 unless count
  __decode_expression(count)
end
__decode_dynamic_conditions(field) click to toggle source
# File lib/libbin.rb, line 166
def __decode_dynamic_conditions(field)
  return true unless field.sequence?
  @__offset = nil
  @__condition = nil
  @__type = nil
  @__length = nil
  @__offset = __decode_seek_offset(field.offset, field.relative_offset?)
  return false if @__offset == false
  @__condition = __decode_condition(field.condition)
  return false unless @__condition
  @__type = __decode_type(field.type)
  @__length = __decode_length(field.length)
  return true
end
__decode_expression(sym) click to toggle source
# 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_length(length) click to toggle source
# File lib/libbin.rb, line 145
def __decode_length(length)
  __decode_expression(length)
end
__decode_seek_offset(offset, relative_offset) click to toggle source
# File lib/libbin.rb, line 120
def __decode_seek_offset(offset, relative_offset)
  return nil unless offset
  offset = __decode_expression(offset)
  return false if offset == 0x0
  offset += @__position if relative_offset
  @__cur_position = offset
  @__input.seek(offset) if @__input
  @__output.seek(offset) if @__output
  offset
end
__decode_static_conditions(field) click to toggle source
# File lib/libbin.rb, line 149
def __decode_static_conditions(field)
  @__offset = nil
  @__condition = nil
  @__type = nil
  @__length = nil
  @__count = nil
  unless field.sequence?
    @__offset = __decode_seek_offset(field.offset, field.relative_offset?)
    throw :ignored, nil if @__offset == false
    @__condition = __decode_condition(field.condition)
    throw :ignored, nil unless @__condition
    @__type = __decode_type(field.type)
    @__length = __decode_length(field.length)
  end
  @__count = __decode_count(field.count)
end
__decode_type(type) click to toggle source
# File lib/libbin.rb, line 141
def __decode_type(type)
  return __decode_expression(type)
end
__dump(output, output_big, parent = nil, index = nil) click to toggle source
# File lib/libbin.rb, line 331
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) click to toggle source
# File lib/libbin.rb, line 220
def __dump_field(vs, field)
  __decode_static_conditions(field)
  vs = [vs] unless field.count
  vs.each_with_index do |v, it|
    @__iterator = it
    if __decode_dynamic_conditions(field)
      @__type::dump(v, @__output, @__output_big, self, it, @__length)
    end
  end
  __restore_context
end
__dump_fields() click to toggle source
# File lib/libbin.rb, line 302
def __dump_fields
  self.class.instance_variable_get(:@fields).each { |field|
    begin
      vs = send(field.name)
      catch(:ignored) do
        __dump_field(vs, field)
      end
    rescue
      STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
      raise
    end
  }
  self
end
__load(input, input_big, parent = nil, index = nil) click to toggle source
# File lib/libbin.rb, line 324
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) click to toggle source
# File lib/libbin.rb, line 205
def __load_field(field)
  __decode_static_conditions(field)
  vs = @__count.times.collect do |it|
    @__iterator = it
    if __decode_dynamic_conditions(field)
      @__type::load(@__input, @__input_big, self, it, @__length)
    else
      nil
    end
  end
  __restore_context
  vs = vs.first unless field.count
  vs
end
__load_fields() click to toggle source
# File lib/libbin.rb, line 287
def __load_fields
  self.class.instance_variable_get(:@fields).each { |field|
    begin
      vs = catch(:ignored) do
        __load_field(field)
      end
      send("#{field.name}=", vs)
    rescue
      STDERR.puts "#{self.class}: #{field.name}(#{field.type})"
      raise
    end
  }
  self
end
__restore_context() click to toggle source
# File lib/libbin.rb, line 181
def __restore_context
  @__iterator = nil
  @__type = nil
  @__length = nil
  @__count = nil
  @__offset = nil
  @__condition = nil
end
__set_convert_type(input, output, input_big, output_big, parent, index) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# File lib/libbin.rb, line 252
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 { |field|
    begin
      vs = send(field.name)
      member = catch(:ignored) do
        __shape_field(vs, previous_offset, kind, field)
      end
      members[field.name] = member
    rescue
      STDERR.puts "#{self.class}: #{field.name}(#{field.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) click to toggle source
# File lib/libbin.rb, line 232
def __shape_field(vs, previous_offset, kind, field)
  __decode_static_conditions(field)
  vs = [vs] unless field.count
  vs = vs.each_with_index.collect do |v, it|
    @__iterator = it
    if __decode_dynamic_conditions(field)
      sh = @__type::shape(v, @__cur_position, self, it, kind, @__length)
      @__cur_position = sh.last + 1 if sh.last && sh.last >= 0
      sh
    end
  end
  __restore_context
  vs = vs.first unless field.count
  vs
end
__size(previous_offset = 0, parent = nil, index = nil) click to toggle source
# File lib/libbin.rb, line 248
def __size(previous_offset = 0, parent = nil, index = nil)
  __shape(previous_offset, parent, index, DataRange).size
end
__unset_convert_type() click to toggle source
# 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_type() click to toggle source
# 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_type() click to toggle source
# 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_type() click to toggle source
# File lib/libbin.rb, line 79
def __unset_size_type
  @__parent = nil
  @__index = nil
  @__position = nil
  @__cur_position = nil
end
inspect() click to toggle source
# File lib/libbin.rb, line 24
def inspect
  to_s
end