class BinData::SingleValue
SingleValue objects accept all the parameters that BinData::Single do.
== Parameters
“0x%x” % u24.value #=> 0x123456
u24.read(“x12x34x56”)
u24 = Uint24be.new
end
end
self.byte3 = v & 0xff
self.byte2 = (v >> 8) & 0xff
self.byte1 = (v >> 16) & 0xff
v = 0xffffff if v > 0xffffff
v = 0 if v < 0
def set(v)
end
(self.byte1 << 16) | (self.byte2 << 8) | self.byte3
def get
uint8 :byte3
uint8 :byte2
uint8 :byte1
class Uint24be < BinData::SingleValue
# Unsigned 24 bit big endian integer
ps.value #=> “abc”
ps.read(“003abcde”)
ps.to_s #=> “005hello”
ps = PascalString.new(:initial_value => “hello”)
end
end
self.data = v
def set(v)
end
self.data
def get
string :data, :read_length => :len
uint8 :len, :value => lambda { data.length }
class PascalString < BinData::SingleValue
require ‘bindata’
and the #value of the object.
#get and #set method to extract / convert the data between the fields
To define a new data type, set fields as if for MultiValue and add a
that contain multiple values see BinData::MultiValue.
The data type must contain a single value only. For new data types
A SingleValue is a declarative way to define a new BinData data type.
def endian(endian = nil)
Endianess is applied to the fields of this structure.
Returns or sets the endianess of numerics used in this stucture.
def endian(endian = nil) @endian ||= nil if [:little, :big].include?(endian) @endian = endian elsif endian != nil raise ArgumentError, "unknown value for endian '#{endian}'" end @endian end
def fields
Returns all stored fields. Should only be called by
def fields @fields || [] end
def get
Extracts the value for this data object from the fields of the
def get raise NotImplementedError end
def inherited(subclass) #:nodoc:
Register the names of all subclasses of this class.
def inherited(subclass) #:nodoc: register(subclass.name, subclass) end
def initialize(params = {}, parent = nil)
def initialize(params = {}, parent = nil) super(params, parent) @struct = BinData::Struct.new(no_eval_param(:struct_params), self) end
def method_missing(symbol, *args)
def method_missing(symbol, *args) name, params = args type = symbol name = (name.nil? or name == "") ? nil : name.to_s params ||= {} # note that fields are stored in an instance variable not a class var @fields ||= [] # check that type is known unless Sanitizer.type_exists?(type, endian) raise TypeError, "unknown type '#{type}' for #{self}", caller end # check that name is okay if name != nil # check for duplicate names @fields.each do |t, n, p| if n == name raise SyntaxError, "duplicate field '#{name}' in #{self}", caller end end # check that name doesn't shadow an existing method if self.instance_methods.include?(name) raise NameError.new("", name), "field '#{name}' shadows an existing method", caller end end # remember this field. These fields will be recalled upon creating # an instance of this class @fields.push([type, name, params]) end
def method_missing(symbol, *args, &block)
def method_missing(symbol, *args, &block) if @struct.respond_to?(symbol) @struct.__send__(symbol, *args, &block) else super end end
def read_val(io)
def read_val(io) @struct.read(io) get end
def recursive?
def recursive? true end
def sanitize_parameters!(sanitizer, params)
def sanitize_parameters!(sanitizer, params) struct_params = {} struct_params[:fields] = self.fields struct_params[:endian] = self.endian unless self.endian.nil? params[:struct_params] = struct_params super(sanitizer, params) end
def sensible_default
def sensible_default get end
def set(v)
def set(v) raise NotImplementedError end
def val_to_str(val)
Sets +val+ into the fields of the internal struct then returns the
def val_to_str(val) set(val) @struct.to_s end