Class: BinData::Base

Inherits:
Object
  • Object
show all
Includes:
AcceptedParametersMixin
Defined in:
lib/bindata/base.rb,
lib/bindata/deprecated.rb

Overview

This is the abstract base class for all data objects.

Parameters

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

:check_offset

Raise an error if the current IO offset doesn’t meet this criteria. A boolean return indicates success or failure. Any other return is compared to the current offset. The variable offset is made available to any lambda assigned to this parameter. This parameter is only checked before reading.

:adjust_offset

Ensures that the current IO offset is at this position before reading. This is like :check_offset, except that it will adjust the IO offset instead of raising an error.

Direct Known Subclasses

Array, BasePrimitive, Choice, Struct, Wrapper

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from AcceptedParametersMixin

included

Constructor Details

#initialize(parameters = {}, parent = nil) ⇒ Base

Creates a new data object.

parameters is a hash containing symbol keys. Some parameters may reference callable objects (methods or procs).

parent is the parent data object (e.g. struct, array, choice) this object resides under.



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

def initialize(parameters = {}, parent = nil)
  @params = Sanitizer.sanitize(parameters, self.class)
  @parent = parent
end

Instance Attribute Details

#parentObject (readonly)

Returns the value of attribute parent.



79
80
81
# File 'lib/bindata/base.rb', line 79

def parent
  @parent
end

Class Method Details

.read(io) ⇒ Object

Instantiates this class and reads from io, returning the newly created data object.



40
41
42
43
44
# File 'lib/bindata/base.rb', line 40

def read(io)
  data = self.new
  data.read(io)
  data
end

.register(name, class_to_register) ⇒ Object



4
5
6
7
8
9
10
11
12
13
# File 'lib/bindata/deprecated.rb', line 4

def register(name, class_to_register)
  if class_to_register == self
    warn "#{caller[0]} `register(name, class_to_register)' is deprecated as of BinData 1.2.0.  Replace with `register_self'"
  elsif /inherited/ =~ caller[0]
    warn "#{caller[0]} `def self.inherited(subclass); register(subclass.name, subclass); end' is deprecated as of BinData 1.2.0.  Replace with `register_subclasses'"
  else
    warn "#{caller[0]} `register(name, class_to_register)' is deprecated as of BinData 1.2.0.  Replace with `register_class(class_to_register)'"
  end
  register_class(class_to_register)
end

.register_class(class_to_register) ⇒ Object

:nodoc:



60
61
62
# File 'lib/bindata/base.rb', line 60

def register_class(class_to_register) #:nodoc:
  RegisteredClasses.register(class_to_register.name, class_to_register)
end

.register_selfObject

Registers this class for use.



47
48
49
# File 'lib/bindata/base.rb', line 47

def register_self
  register_class(self)
end

.register_subclassesObject

Registers all subclasses of this class for use



52
53
54
55
56
57
58
# File 'lib/bindata/base.rb', line 52

def register_subclasses
  class << self
    define_method(:inherited) do |subclass|
      register_class(subclass)
    end
  end
end

Instance Method Details

#==(other) ⇒ Object

:nodoc:



208
209
210
211
# File 'lib/bindata/base.rb', line 208

def ==(other) #:nodoc:
  # double dispatch
  other == snapshot
end

#assign(val) ⇒ Object

Assigns the value of val to this data object. Note that val will always be deep copied to ensure no aliasing problems can occur.



149
150
151
# File 'lib/bindata/base.rb', line 149

def assign(val)
  _assign(val)
end

#clearObject

Resets the internal state to that of a newly created object.

Raises:

  • (NotImplementedError)


262
263
264
# File 'lib/bindata/base.rb', line 262

def clear
  raise NotImplementedError
end

#clear?Boolean

Returns true if the object has not been changed since creation.

Returns:

  • (Boolean)

Raises:

  • (NotImplementedError)


267
268
269
# File 'lib/bindata/base.rb', line 267

def clear?
  raise NotImplementedError
end

#debug_nameObject

Returns a user friendly name of this object for debugging purposes.



182
183
184
185
186
187
188
# File 'lib/bindata/base.rb', line 182

def debug_name
  if @parent
    @parent.debug_name_of(self)
  else
    "obj"
  end
end

#debug_name_of(child) ⇒ Object

Returns the debug name of child. This only needs to be implemented by objects that contain child objects.



273
274
275
# File 'lib/bindata/base.rb', line 273

def debug_name_of(child) #:nodoc:
  debug_name
end

#eval_parameter(key, overrides = {}) ⇒ Object

Returns the result of evaluating the parameter identified by key.

overrides is an optional parameters like hash that allow the parameters given at object construction to be overridden.

Returns nil if key does not refer to any parameter.



87
88
89
# File 'lib/bindata/base.rb', line 87

def eval_parameter(key, overrides = {})
  LazyEvaluator.eval(self, get_parameter(key), overrides)
end

#get_parameter(key) ⇒ Object

Returns the parameter referenced by key. Use this method if you are sure the parameter is not to be evaluated. You most likely want #eval_parameter.



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

def get_parameter(key)
  @params[key]
end

#has_parameter?(key) ⇒ Boolean

Returns whether key exists in the parameters hash.

Returns:

  • (Boolean)


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

def has_parameter?(key)
  @params.has_parameter?(key)
end

#inspectObject

Return a human readable representation of this data object.



167
168
169
# File 'lib/bindata/base.rb', line 167

def inspect
  snapshot.inspect
end

#num_bytesObject

Returns the number of bytes it will take to write this data object.



138
139
140
# File 'lib/bindata/base.rb', line 138

def num_bytes
  do_num_bytes.ceil
end

#offsetObject

Returns the offset of this object wrt to its most distant ancestor.



191
192
193
194
195
196
197
# File 'lib/bindata/base.rb', line 191

def offset
  if @parent
    @parent.offset + @parent.offset_of(self)
  else
    0
  end
end

#offset_of(child) ⇒ Object

Returns the offset of child. This only needs to be implemented by objects that contain child objects.



279
280
281
# File 'lib/bindata/base.rb', line 279

def offset_of(child) #:nodoc:
  0
end

#pretty_print(pp) ⇒ Object

Work with Ruby’s pretty-printer library.



177
178
179
# File 'lib/bindata/base.rb', line 177

def pretty_print(pp) #:nodoc:
  pp.pp(snapshot)
end

#read(io) ⇒ Object

Reads data into this data object.



104
105
106
107
108
109
110
# File 'lib/bindata/base.rb', line 104

def read(io)
  io = BinData::IO.new(io) unless BinData::IO === io

  do_read(io)
  done_read
  self
end

#rel_offsetObject

Returns the offset of this object wrt to its parent.



200
201
202
203
204
205
206
# File 'lib/bindata/base.rb', line 200

def rel_offset
  if @parent
    @parent.offset_of(self)
  else
    0
  end
end

#snapshotObject

Returns a snapshot of this data object.



154
155
156
# File 'lib/bindata/base.rb', line 154

def snapshot
  _snapshot
end

#to_binary_sObject

Returns the string representation of this data object.



159
160
161
162
163
164
# File 'lib/bindata/base.rb', line 159

def to_binary_s
  io = BinData::IO.create_string_io
  write(io)
  io.rewind
  io.read
end

#to_sObject

Return a string representing this data object.



172
173
174
# File 'lib/bindata/base.rb', line 172

def to_s
  snapshot.to_s
end

#write(io) ⇒ Object

Writes the value for this data object to io.



124
125
126
127
128
129
130
# File 'lib/bindata/base.rb', line 124

def write(io)
  io = BinData::IO.new(io) unless BinData::IO === io

  do_write(io)
  io.flush
  self
end