Class: BinData::Struct

Inherits:
Base
  • Object
show all
Defined in:
lib/bindata/struct.rb

Overview

A Struct is an ordered collection of named data objects.

require 'bindata'

class Tuple < BinData::Record
  int8  :x
  int8  :y
  int8  :z
end

obj = BinData::Struct.new(:hide => :a,
                          :fields => [ [:int32le, :a],
                                       [:int16le, :b],
                                       [:tuple, :s] ])
obj.field_names   =># ["b", "s"]

Parameters

Parameters may be provided at initialisation to control the behaviour of an object. These params are:

:fields

An array specifying the fields for this struct. Each element of the array is of the form [type, name, params]. Type is a symbol representing a registered type. Name is the name of this field. Params is an optional hash of parameters to pass to this field when instantiating it. If name is “” or nil, then that field is anonymous and behaves as a hidden field.

:hide

A list of the names of fields that are to be hidden from the outside world. Hidden fields don’t appear in #snapshot or #field_names but are still accessible by name.

:endian

Either :little or :big. This specifies the default endian of any numerics in this struct, or in any nested data objects.

Field Parameters

Fields may have have extra parameters as listed below:

:onlyif

Used to indicate a data object is optional. if false, this object will not be included in any calls to #read, #write, #num_bytes or #snapshot.

Direct Known Subclasses

Record

Defined Under Namespace

Classes: Snapshot

Constant Summary collapse

RESERVED =

These reserved words may not be used as field names

Hash[*
                 (Hash.instance_methods +
%w{alias and begin break case class def defined do else elsif
   end ensure false for if in module next nil not or redo
   rescue retry return self super then true undef unless until
   when while yield} +
%w{array element index value} ).collect { |name| name.to_sym }.
uniq.collect { |key| [key, true]

Instance Attribute Summary

Attributes inherited from Base

#parent

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#==, #_assign, #_do_num_bytes, #_do_read, #_do_write, #_snapshot, arg_extractor, bindata_name, #debug_name, #eval_parameter, #get_parameter, #has_parameter?, #initialize_with_deprecation, #inspect, #new, #num_bytes, #offset, #pretty_print, #read, read, register, register_self, register_subclasses, #rel_offset, #to_binary_s, #to_s, unregister_self, #write

Methods included from CheckOrAdjustOffsetMixin

#do_read_with_adjust_offset, #do_read_with_check_offset, included

Methods included from AcceptedParametersMixin

included

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args, &block) ⇒ Object

:nodoc:



190
191
192
193
194
195
196
197
# File 'lib/bindata/struct.rb', line 190

def method_missing(symbol, *args, &block) #:nodoc:
  obj = find_obj_for_name(symbol)
  if obj
    invoke_field(obj, symbol, args)
  else
    super
  end
end

Class Method Details

.sanitize_parameters!(params) ⇒ Object

:nodoc:



71
72
73
74
75
# File 'lib/bindata/struct.rb', line 71

def sanitize_parameters!(params) #:nodoc:
  sanitize_endian(params)
  sanitize_fields(params)
  sanitize_hide(params)
end

Instance Method Details

#[](key) ⇒ Object



225
226
227
# File 'lib/bindata/struct.rb', line 225

def [](key)
  find_obj_for_name(key)
end

#[]=(key, value) ⇒ Object



229
230
231
232
233
234
# File 'lib/bindata/struct.rb', line 229

def []=(key, value)
  obj = find_obj_for_name(key)
  if obj
    obj.assign(value)
  end
end

#assign(val) ⇒ Object



160
161
162
163
# File 'lib/bindata/struct.rb', line 160

def assign(val)
  clear
  assign_fields(val)
end

#clearObject

:nodoc:



152
153
154
# File 'lib/bindata/struct.rb', line 152

def clear #:nodoc:
  @field_objs.each { |f| f.clear unless f.nil? }
end

#clear?Boolean

:nodoc:

Returns:

  • (Boolean)


156
157
158
# File 'lib/bindata/struct.rb', line 156

def clear? #:nodoc:
  @field_objs.all? { |f| f.nil? or f.clear? }
end

#debug_name_of(child) ⇒ Object

:nodoc:



199
200
201
202
# File 'lib/bindata/struct.rb', line 199

def debug_name_of(child) #:nodoc:
  field_name = @field_names[find_index_of(child)]
  "#{debug_name}.#{field_name}"
end

#do_num_bytesObject

:nodoc:



220
221
222
223
# File 'lib/bindata/struct.rb', line 220

def do_num_bytes #:nodoc:
  instantiate_all_objs
  sum_num_bytes_for_all_fields
end

#do_read(io) ⇒ Object

:nodoc:



210
211
212
213
# File 'lib/bindata/struct.rb', line 210

def do_read(io) #:nodoc:
  instantiate_all_objs
  @field_objs.each { |f| f.do_read(io) if include_obj(f) }
end

#do_write(io) ⇒ Object

:nodoc



215
216
217
218
# File 'lib/bindata/struct.rb', line 215

def do_write(io) #:nodoc
  instantiate_all_objs
  @field_objs.each { |f| f.do_write(io) if include_obj(f) }
end

#field_names(include_hidden = false) ⇒ Object

Returns a list of the names of all fields accessible through this object. include_hidden specifies whether to include hidden names in the listing.



177
178
179
180
181
182
183
184
# File 'lib/bindata/struct.rb', line 177

def field_names(include_hidden = false)
  if include_hidden
    @field_names.compact
  else
    hidden = get_parameter(:hide) || []
    @field_names.compact - hidden
  end.collect { |x| x.to_s }
end

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


236
237
238
# File 'lib/bindata/struct.rb', line 236

def has_key?(key)
  @field_names.index(base_field_name(key))
end

#initialize_instanceObject



148
149
150
# File 'lib/bindata/struct.rb', line 148

def initialize_instance
  @field_objs  = []
end

#initialize_shared_instanceObject



144
145
146
# File 'lib/bindata/struct.rb', line 144

def initialize_shared_instance
  @field_names = get_parameter(:fields).field_names.freeze
end

#offset_of(child) ⇒ Object

:nodoc:



204
205
206
207
208
# File 'lib/bindata/struct.rb', line 204

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

#respond_to?(symbol, include_private = false) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


186
187
188
# File 'lib/bindata/struct.rb', line 186

def respond_to?(symbol, include_private = false) #:nodoc:
  @field_names.include?(base_field_name(symbol)) || super
end

#snapshotObject



165
166
167
168
169
170
171
172
# File 'lib/bindata/struct.rb', line 165

def snapshot
  snapshot = Snapshot.new(field_names)
  field_names.each do |name|
    obj = find_obj_for_name(name)
    snapshot[name] = obj.snapshot if include_obj(obj)
  end
  snapshot
end