class BinData::BasePrimitive
the value just read in.
or failure. Any other return is compared to
parameter. A boolean return indicates success
available to any lambda assigned to this
this criteria. The variable value
is made
[:check_value
] Raise an error unless the value read in meets
IO, not the result of the :value
param.
will return the value of the data read from the
calls to #do_read and #done_read, #value
using this param. In the interval between
Calls to #value= are ignored when
[:value
] The object will always have this value.
either #read or explicitly set with #value=.
[:initial_value
] This is the initial value to use before one is
an object. These params include those for BinData::Base as well as:
Parameters may be provided at initialisation to control the behaviour of
== Parameters
obj.read(“007”) #=> BinData::ValidityError: value not as expected
obj = BinData::Uint8.new(:check_value => lambda { value < 5 })
obj.read(“005”) #=> BinData::ValidityError: value is ‘5’ but expected ‘3’
obj = BinData::Uint8.new(:check_value => 3)
obj.value #=> 42
obj.value = 5
obj.value #=> 42
obj = BinData::Uint8.new(:value => 42)
obj.value #=> 42
obj.clear
obj.value #=> 5
obj.value = 5
obj.value #=> 42
obj = BinData::Uint8.new(:initial_value => 42)
require ‘bindata’
this object. This value can be read from or written to an IO stream.
such as as integer, float or string. Only one value can be contained by
particular binary representation. A value corresponds to a primitive type
A BinData::BasePrimitive object is a container for a value that has a
def _assign(val)
def _assign(val) raise ArgumentError, "can't set a nil value for #{debug_name}" if val.nil? unless has_parameter?(:value) raw_val = val.respond_to?(:snapshot) ? val.snapshot : val @value = begin raw_val.dup rescue TypeError # can't dup Fixnums raw_val end end end
def _do_num_bytes
def _do_num_bytes value_to_binary_string(_value).length end
def _do_read(io)
def _do_read(io) @in_read = true @value = read_and_return_value(io) trace_value if has_parameter?(:check_value) check_value(value) end end
def _do_write(io)
def _do_write(io) raise "can't write whilst reading #{debug_name}" if @in_read io.writebytes(value_to_binary_string(_value)) end
def _done_read
def _done_read @in_read = false end
def _snapshot
def _snapshot _value end
def _value
method. This is so that #value can be overridden in subclasses to
The unmodified value of this data object. Note that #value calls this
def _value # Table of possible preconditions and expected outcome # 1. :value and !in_read -> :value # 2. :value and in_read -> @value # 3. :initial_value and clear? -> :initial_value # 4. :initial_value and !clear? -> @value # 5. clear? -> sensible_default # 6. !clear? -> @value if not @in_read and has_parameter?(:value) # rule 1 above eval_parameter(:value) else # combining all other rules gives this simplified expression @value || eval_parameter(:value) || eval_parameter(:initial_value) || sensible_default() end end
def check_value(current_value)
def check_value(current_value) expected = eval_parameter(:check_value, :value => current_value) if not expected raise ValidityError, "value '#{current_value}' not as expected for #{debug_name}" elsif current_value != expected and expected != true raise ValidityError, "value is '#{current_value}' but " + "expected '#{expected}' for #{debug_name}" end end
def clear #:nodoc:
def clear #:nodoc: @value = nil @in_read = false end
def clear? #:nodoc:
def clear? #:nodoc: @value.nil? end
def eql?(other)
def eql?(other) # double dispatch other.eql?(snapshot) end
def hash
def hash snapshot.hash end
def initialize(params = {}, parent = nil)
def initialize(params = {}, parent = nil) super(params, parent) @value = nil @in_read = false end
def method_missing(symbol, *args, &block) #:nodoc:
def method_missing(symbol, *args, &block) #:nodoc: if value.respond_to?(symbol) value.__send__(symbol, *args, &block) else super end end
def read_and_return_value(io)
def read_and_return_value(io) raise NotImplementedError end
def respond_to?(symbol, include_private=false) #:nodoc:
def respond_to?(symbol, include_private=false) #:nodoc: super || value.respond_to?(symbol, include_private) end
def sensible_default
def sensible_default raise NotImplementedError end
def trace_value
def trace_value BinData::trace_message do |tracer| value_string = _value.inspect if value_string.length > 30 value_string = value_string.slice(0 .. 30) + "..." end tracer.trace("#{debug_name} => #{value_string}") end end
def value
def value # TODO: warn "#value is deprecated, use #snapshot instead" snapshot end
def value=(val)
def value=(val) # TODO: warn "#value= is deprecated, use #assign instead" assign(val) end
def value_to_binary_string(val)
def value_to_binary_string(val) raise NotImplementedError end