class BinData::Choice
- selection changes. Default is false.
selection to the current selection whenever the:copy_on_change
- If set to true, copy the value of the previous
specifies the currently active choice.:selection
- An index/key into the :choices array/hash which
:selection does not exist in the :choices hash.
of :default. :default is to be used when then
not contain symbols as keys, with the exception
implementation constraint is that the hash may
be provided as [type_symbol, hash_params]. An
is to have params passed to it, then it should
representing the data object type. If a choice
array/hash.values is a list of symbols
data objects. The format of the:choices
-
Either an array or a hash specifying the possible
an object. These params are:
Parameters may be provided at initialisation to control the behaviour of
== Parameters
a.to_binary_s #=> “000001”
mychoice.choice = ‘little’
a.to_binary_s #=> “001000”
a.assign(256)
:selection => lambda { mychoice.choice })
a = BinData::Choice.new(:choices => choices, :copy_on_change => true,
choices = {‘big’ => :uint16be, ‘little’ => :uint16le}
mychoice.choice = ‘big’
mychoice = Chooser.new
Chooser = Struct.new(:choice)
a # => “Type1”
a = BinData::Choice.new(:choices => choices, :selection => 3)
choices = [ nil, nil, nil, type1, nil, type2 ]
a # => “Type2”
a = BinData::Choice.new(:choices => choices, :selection => 1)
choices = [ type1, type2 ]
a # => “Type1”
a = BinData::Choice.new(:choices => choices, :selection => 5)
choices = {5 => type1, 17 => type2}
type2 = [:string, {:value => “Type2”}]
type1 = [:string, {:value => “Type1”}]
require ‘bindata’
choice.
at any particular time. Method calls will be delegated to the active
A Choice is a collection of data objects of which only one is active
- An index/key into the :choices array/hash which
- If set to true, copy the value of the previous
def assign(val)
def assign(val) current_choice.assign(val) end
def choices_as_hash(choices)
def choices_as_hash(choices) if choices.respond_to?(:to_ary) key_array_by_index(choices.to_ary) else choices end end
def clear? #:nodoc:
def clear? #:nodoc: current_choice.clear? end
def current_choice
def current_choice current_selection = selection @choices[current_selection] ||= instantiate_choice(current_selection) end
def do_num_bytes #:nodoc:
def do_num_bytes #:nodoc: current_choice.do_num_bytes end
def do_read(io) #:nodoc:
def do_read(io) #:nodoc: current_choice.do_read(io) end
def do_read_with_hook(io)
def do_read_with_hook(io) trace_selection do_read_without_hook(io) end
def do_write(io) #:nodoc:
def do_write(io) #:nodoc: current_choice.do_write(io) end
def ensure_valid_keys(choices)
def ensure_valid_keys(choices) if choices.has_key?(nil) raise ArgumentError, ":choices hash may not have nil key" end if choices.keys.detect { |key| key.is_a?(Symbol) and key != :default } raise ArgumentError, ":choices hash may not have symbols for keys" end end
def initialize_instance
def initialize_instance @choices = {} @last_selection = nil end
def initialize_shared_instance
def initialize_shared_instance extend CopyOnChangePlugin if eval_parameter(:copy_on_change) == true super end
def instantiate_choice(selection)
def instantiate_choice(selection) prototype = get_parameter(:choices)[selection] if prototype.nil? raise IndexError, "selection '#{selection}' does not exist in :choices for #{debug_name}" end prototype.instantiate(nil, self) end
def key_array_by_index(array)
def key_array_by_index(array) result = {} array.each_with_index do |el, i| result[i] = el unless el.nil? end result end
def method_missing(symbol, *args, &block) #:nodoc:
def method_missing(symbol, *args, &block) #:nodoc: current_choice.__send__(symbol, *args, &block) end
def respond_to?(symbol, include_private = false) #:nodoc:
def respond_to?(symbol, include_private = false) #:nodoc: current_choice.respond_to?(symbol, include_private) || super end
def safe_respond_to?(symbol, include_private = false) #:nodoc:
def safe_respond_to?(symbol, include_private = false) #:nodoc: base_respond_to?(symbol, include_private) end
def sanitize_parameters!(params) #:nodoc:
def sanitize_parameters!(params) #:nodoc: params.merge!(dsl_params) if params.needs_sanitizing?(:choices) choices = choices_as_hash(params[:choices]) ensure_valid_keys(choices) params[:choices] = params.create_sanitized_choices(choices) end end
def selection
def selection selection = eval_parameter(:selection) if selection.nil? raise IndexError, ":selection returned nil for #{debug_name}" end selection end
def snapshot
def snapshot current_choice.snapshot end
def trace_selection
def trace_selection BinData::trace_message do |tracer| selection_string = eval_parameter(:selection).inspect tracer.trace_obj("#{debug_name}-selection-", selection_string) end end
def turn_off_tracing
def turn_off_tracing alias_method :do_read, :do_read_without_hook end
def turn_on_tracing
def turn_on_tracing alias_method :do_read_without_hook, :do_read alias_method :do_read, :do_read_with_hook end