Class: BinData::Choice

Inherits:
Base
  • Object
show all
Extended by:
DSLMixin, TraceHook
Defined in:
lib/bindata/choice.rb,
lib/bindata/trace.rb

Overview

A Choice is a collection of data objects of which only one is active at any particular time. Method calls will be delegated to the active choice.

require 'bindata'

type1 = [:string, {value: "Type1"}]
type2 = [:string, {value: "Type2"}]

choices = {5 => type1, 17 => type2}
a = BinData::Choice.new(choices: choices, selection: 5)
a # => "Type1"

choices = [ type1, type2 ]
a = BinData::Choice.new(choices: choices, selection: 1)
a # => "Type2"

choices = [ nil, nil, nil, type1, nil, type2 ]
a = BinData::Choice.new(choices: choices, selection: 3)
a # => "Type1"

Chooser = Struct.new(:choice)
mychoice = Chooser.new
mychoice.choice = 'big'

choices = {'big' => :uint16be, 'little' => :uint16le}
a = BinData::Choice.new(choices: choices, copy_on_change: true,
                        selection: -> { mychoice.choice })
a.assign(256)
a.to_binary_s #=> "\001\000"

mychoice.choice = 'little'
a.to_binary_s #=> "\000\001"

Parameters

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

:choices

Either an array or a hash specifying the possible data objects. The format of the array/hash.values is a list of symbols representing the data object type. If a choice is to have params passed to it, then it should be provided as [type_symbol, hash_params]. An implementation constraint is that the hash may not contain symbols as keys, with the exception of :default. :default is to be used when then :selection does not exist in the :choices hash.

:selection

An index/key into the :choices array/hash which specifies the currently active choice.

:copy_on_change

If set to true, copy the value of the previous selection to the current selection whenever the selection changes. Default is false.

Instance Attribute Summary

Attributes inherited from Base

#parent

Instance Method Summary collapse

Methods included from TraceHook

turn_off_tracing, turn_on_tracing

Methods included from DSLMixin

dsl_parser, to_ary, to_str

Methods inherited from Base

#==, #=~, #abs_offset, arg_processor, auto_call_delayed_io, bindata_name, #clear, #debug_name, #eval_parameter, #get_parameter, #has_parameter?, #initialize_with_warning, #inspect, #lazy_evaluator, #new, #num_bytes, #pretty_print, #read, read, register_subclasses, #rel_offset, #safe_respond_to?, #to_binary_s, #to_hex, #to_s, unregister_self, #write

Methods included from AcceptedParametersPlugin

#accepted_parameters, #default_parameters, #mandatory_parameters, #mutually_exclusive_parameters, #optional_parameters

Methods included from RegisterNamePlugin

included

Methods included from Framework

#assign, #bit_aligned?, #clear?, #debug_name_of, #offset_of, #snapshot

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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

:nodoc:



93
94
95
# File 'lib/bindata/choice.rb', line 93

def method_missing(symbol, *args, &block) # :nodoc:
  current_choice.__send__(symbol, *args, &block)
end

Instance Method Details

#do_read_with_hook(io) ⇒ Object



79
80
81
82
83
84
85
86
# File 'lib/bindata/trace.rb', line 79

def do_read_with_hook(io)
  BinData.trace_message do |tracer|
    selection_string = eval_parameter(:selection).inspect
    tracer.trace_obj("#{debug_name}-selection-", selection_string)
  end

  do_read_without_hook(io)
end

#initialize_instanceObject



74
75
76
77
# File 'lib/bindata/choice.rb', line 74

def initialize_instance
  @choices = {}
  @last_selection = nil
end

#initialize_shared_instanceObject



69
70
71
72
# File 'lib/bindata/choice.rb', line 69

def initialize_shared_instance
  extend CopyOnChangePlugin if eval_parameter(:copy_on_change) == true
  super
end

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

:nodoc:

Returns:

  • (Boolean)


89
90
91
# File 'lib/bindata/choice.rb', line 89

def respond_to?(symbol, include_all = false) # :nodoc:
  current_choice.respond_to?(symbol, include_all) || super
end

#selectionObject

Returns the current selection.



80
81
82
83
84
85
86
87
# File 'lib/bindata/choice.rb', line 80

def selection
  selection = eval_parameter(:selection)
  if selection.nil?
    raise IndexError, ":selection returned nil for #{debug_name}"
  end

  selection
end