Class: BinData::Primitive

Inherits:
BasePrimitive show all
Extended by:
DSLMixin
Defined in:
lib/bindata/primitive.rb

Overview

A Primitive is a declarative way to define a new BinData data type. The data type must contain a primitive value only, i.e numbers or strings. For new data types that contain multiple values see BinData::Record.

To define a new data type, set fields as if for Record and add a #get and #set method to extract / convert the data between the fields and the #value of the object.

require 'bindata'

class PascalString < BinData::Primitive
 uint8  :len,  value: -> { data.length }
 string :data, read_length: :len

 def get
   self.data
 end

 def set(v)
   self.data = v
 end
end

ps = PascalString.new(initial_value: "hello")
ps.to_binary_s #=> "\005hello"
ps.read("\003abcde")
ps #=> "abc"

# Unsigned 24 bit big endian integer
class Uint24be < BinData::Primitive
 uint8 :byte1
 uint8 :byte2
 uint8 :byte3

 def get
   (self.byte1 << 16) | (self.byte2 << 8) | self.byte3
 end

 def set(v)
   v = 0 if v < 0
   v = 0xffffff if v > 0xffffff

   self.byte1 = (v >> 16) & 0xff
   self.byte2 = (v >>  8) & 0xff
   self.byte3 =  v        & 0xff
 end
end

u24 = Uint24be.new
u24.read("\x12\x34\x56")
"0x%x" % u24 #=> 0x123456

Parameters

Primitive objects accept all the parameters that BinData::BasePrimitive do.

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DSLMixin

dsl_parser, to_ary, to_str

Methods inherited from BasePrimitive

#<=>, #clear?, #do_read, #do_read_with_hook, #eql?, #hash, #initialize_shared_instance, #respond_to_missing?, #snapshot, #value, #value=

Methods included from TraceHook

#turn_off_tracing, #turn_on_tracing

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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

:nodoc:



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

def method_missing(symbol, *args, **kwargs, &block) # :nodoc:
  if @struct.respond_to?(symbol)
    @struct.__send__(symbol, *args, **kwargs, &block)
  else
    super
  end
end

Class Method Details

.bit_alignedObject



84
85
86
# File 'lib/bindata/alignment.rb', line 84

def Primitive.bit_aligned
  fail "'bit_aligned' is not supported for BinData::Primitives"
end

Instance Method Details

#assign(val) ⇒ Object



88
89
90
91
92
# File 'lib/bindata/primitive.rb', line 88

def assign(val)
  super(val)
  set(_value)
  @value = get
end

#debug_name_of(child) ⇒ Object

:nodoc:



94
95
96
# File 'lib/bindata/primitive.rb', line 94

def debug_name_of(child) # :nodoc:
  debug_name + "-internal-"
end

#do_num_bytesObject



103
104
105
106
# File 'lib/bindata/primitive.rb', line 103

def do_num_bytes
  set(_value)
  @struct.do_num_bytes
end

#do_write(io) ⇒ Object



98
99
100
101
# File 'lib/bindata/primitive.rb', line 98

def do_write(io)
  set(_value)
  @struct.do_write(io)
end

#initialize_instanceObject



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

def initialize_instance
  super
  @struct = BinData::Struct.new(get_parameter(:struct_params), self)
end

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

:nodoc:

Returns:

  • (Boolean)


76
77
78
# File 'lib/bindata/primitive.rb', line 76

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