class BinData::Struct
:byte_align
.
[:byte_align
] This field’s rel_offset must be a multiple of
calls to #read, #write, #num_bytes or #snapshot.
iffalse
, this object will not be included in any
[:onlyif
] Used to indicate a data object is optional.
Fields may have have extra parameters as listed below:
== Field Parameters
a match is found.
unrecognised, then each prefix is applied until:search_prefix
- Allows abbreviated type names. If a type is
nested data objects.
endian of any numerics in this struct, or in any:endian
- Either :little or :big. This specifies the default
by name.
in #snapshot or #field_names but are still accessible
from the outside world. Hidden fields don’t appear:hide
- A list of the names of fields that are to be hidden
that field is anonymous and behaves as a hidden field.
when instantiating it. If name is “” or nil, then
optional hash of parameters to pass to this field
type. Name is the name of this field. Params is an
params]. Type is a symbol representing a registered
Each element of the array is of the form [type, name,:fields
-
An array specifying the fields for this struct.
an object. These params are:
Parameters may be provided at initialisation to control the behaviour of
== Parameters
obj.field_names =># [:b, :s]
[:tuple, :s] ])
[:int16le, :b],
:fields => [ [:int32le, :a],
obj = BinData::Struct.new(:hide => :a,
end
int8 :z
int8 :y
int8 :x
class Tuple < BinData::Record
require ‘bindata’
A Struct is an ordered collection of named data objects.
- A list of the names of fields that are to be hidden
- Either :little or :big. This specifies the default
- Allows abbreviated type names. If a type is
def [](key)
def [](key) find_obj_for_name(key) end
def []=(key, value)
def []=(key, value) obj = find_obj_for_name(key) if obj obj.assign(value) end end
def as_stringified_hash(val)
def as_stringified_hash(val) if BinData::Struct === val val elsif val.nil? {} else hash = Snapshot.new val.each_pair { |k,v| hash[k] = v } hash end end
def assign(val)
def assign(val) clear assign_fields(val) end
def assign_fields(val)
def assign_fields(val) src = as_stringified_hash(val) @field_names.compact.each do |name| obj = find_obj_for_name(name) if obj and src.has_key?(name) obj.assign(src[name]) end end end
def base_field_name(name)
def base_field_name(name) name.to_s.sub(/(=|\?)\z/, "").to_sym end
def clear #:nodoc:
def clear #:nodoc: @field_objs.each { |f| f.clear unless f.nil? } end
def clear? #:nodoc:
def clear? #:nodoc: @field_objs.all? { |f| f.nil? or f.clear? } end
def debug_name_of(child) #:nodoc:
def debug_name_of(child) #:nodoc: field_name = @field_names[find_index_of(child)] "#{debug_name}.#{field_name}" end
def define_field_accessors
def define_field_accessors get_parameter(:fields).each_with_index do |field, i| name = field.name_as_sym define_field_accessors_for(name, i) if name end end
def define_field_accessors_for(name, index)
def define_field_accessors_for(name, index) define_singleton_method(name) do instantiate_obj_at(index) if @field_objs[index].nil? @field_objs[index] end define_singleton_method("#{name}=") do |*vals| instantiate_obj_at(index) if @field_objs[index].nil? @field_objs[index].assign(*vals) end define_singleton_method("#{name}?") do instantiate_obj_at(index) if @field_objs[index].nil? include_obj?(@field_objs[index]) end end
def do_num_bytes #:nodoc:
def do_num_bytes #:nodoc: instantiate_all_objs sum_num_bytes_for_all_fields end
def do_read(io) #:nodoc:
def do_read(io) #:nodoc: instantiate_all_objs @field_objs.each { |f| f.do_read(io) if include_obj?(f) } end
def do_write(io) #:nodoc
def do_write(io) #:nodoc instantiate_all_objs @field_objs.each { |f| f.do_write(io) if include_obj?(f) } end
def each_pair
def each_pair @field_names.compact.each do |name| yield [name, find_obj_for_name(name)] end end
def field_names(include_hidden = false)
object. +include_hidden+ specifies whether to include hidden names
Returns a list of the names of all fields accessible through this
def field_names(include_hidden = false) if include_hidden @field_names.compact else hidden = get_parameter(:hide) || [] @field_names.compact - hidden end end
def find_index_of(obj)
def find_index_of(obj) @field_objs.index { |el| el.equal?(obj) } end
def find_obj_for_name(name)
def find_obj_for_name(name) index = @field_names.index(base_field_name(name)) if index instantiate_obj_at(index) @field_objs[index] else nil end end
def has_key?(key)
def has_key?(key) @field_names.index(base_field_name(key)) end
def include_obj?(obj)
def include_obj?(obj) not obj.has_parameter?(:onlyif) or obj.eval_parameter(:onlyif) end
def initialize_instance
def initialize_instance @field_objs = [] end
def initialize_shared_instance
def initialize_shared_instance fields = get_parameter(:fields) @field_names = fields.field_names.freeze extend ByteAlignPlugin if fields.any_field_has_parameter?(:byte_align) define_field_accessors super end
def instantiate_all_objs
def instantiate_all_objs @field_names.each_index { |i| instantiate_obj_at(i) } end
def instantiate_obj_at(index)
def instantiate_obj_at(index) if @field_objs[index].nil? field = get_parameter(:fields)[index] @field_objs[index] = field.instantiate(nil, self) end end
def offset_of(child) #:nodoc:
def offset_of(child) #:nodoc: instantiate_all_objs sum = sum_num_bytes_below_index(find_index_of(child)) child.do_num_bytes.is_a?(Integer) ? sum.ceil : sum.floor end
def snapshot
def snapshot snapshot = Snapshot.new field_names.each do |name| obj = find_obj_for_name(name) snapshot[name] = obj.snapshot if include_obj?(obj) end snapshot end
def sum_num_bytes_below_index(index)
def sum_num_bytes_below_index(index) (0...index).inject(0) do |sum, i| obj = @field_objs[i] if include_obj?(obj) nbytes = obj.do_num_bytes (nbytes.is_a?(Integer) ? sum.ceil : sum) + nbytes else sum end end end
def sum_num_bytes_for_all_fields
def sum_num_bytes_for_all_fields sum_num_bytes_below_index(@field_objs.length) end