Class: BinData::Base

Inherits:
Object
  • Object
show all
Extended by:
AcceptedParametersPlugin
Includes:
CheckOrAdjustOffsetPlugin, Framework, RegisterNamePlugin
Defined in:
lib/bindata/base.rb,
lib/bindata/struct.rb,
lib/bindata/warnings.rb

Overview

This is the abstract base class for all data objects.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from AcceptedParametersPlugin

accepted_parameters, default_parameters, mandatory_parameters, mutually_exclusive_parameters, optional_parameters

Methods included from RegisterNamePlugin

included, #initialize_shared_instance

Methods included from CheckOrAdjustOffsetPlugin

included, #initialize_shared_instance

Methods included from Framework

#assign, #clear?, #debug_name_of, #offset_of, #snapshot

Instance Attribute Details

#parentObject

Returns the value of attribute parent.



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

def parent
  @parent
end

Class Method Details

.arg_processor(name = nil) ⇒ Object

The arg processor for this class.



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/bindata/base.rb', line 28

def arg_processor(name = nil)
  if name
    @arg_processor = "#{name}_arg_processor".gsub(/(?:^|_)(.)/) { $1.upcase }.to_sym
  elsif @arg_processor.is_a? Symbol
    @arg_processor = BinData::const_get(@arg_processor).new
  elsif @arg_processor.nil?
    @arg_processor = superclass.arg_processor
  else
    @arg_processor
  end
end

.bindata_nameObject

The name of this class as used by Records, Arrays etc.



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

def bindata_name
  RegisteredClasses.underscore_name(self.name)
end

.read(io, *args) ⇒ Object

Instantiates this class and reads from io, returning the newly created data object. args will be used when instantiating.



21
22
23
24
25
# File 'lib/bindata/base.rb', line 21

def read(io, *args)
  obj = self.new(*args)
  obj.read(io)
  obj
end

.register_subclassesObject

Registers all subclasses of this class for use



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

def register_subclasses #:nodoc:
  define_singleton_method(:inherited) do |subclass|
    RegisteredClasses.register(subclass.name, subclass)
    register_subclasses
  end
end

.unregister_selfObject

Call this method if this class is abstract and not to be used.



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

def unregister_self
  RegisteredClasses.unregister(name)
end

Instance Method Details

#==(other) ⇒ Object

:nodoc:



238
239
240
241
# File 'lib/bindata/base.rb', line 238

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

#=~(other) ⇒ Object

Override and delegate =~ as it is defined in Object.



206
207
208
# File 'lib/bindata/base.rb', line 206

def =~(other)
  snapshot =~ other
end

#abs_offsetObject

Returns the offset (in bytes) of this object with respect to its most distant ancestor.



221
222
223
224
225
226
227
# File 'lib/bindata/base.rb', line 221

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

#clearObject

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



136
137
138
# File 'lib/bindata/base.rb', line 136

def clear
  initialize_instance
end

#debug_nameObject

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



211
212
213
214
215
216
217
# File 'lib/bindata/base.rb', line 211

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

#eval_parameter(key, overrides = nil) ⇒ 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.



109
110
111
112
113
114
115
116
# File 'lib/bindata/base.rb', line 109

def eval_parameter(key, overrides = nil)
  value = get_parameter(key)
  if value.is_a?(Symbol) or value.respond_to?(:arity)
    lazy_evaluator.lazy_eval(value, overrides)
  else
    value
  end
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.



126
127
128
# File 'lib/bindata/base.rb', line 126

def get_parameter(key)
  @params[key]
end

#has_parameter?(key) ⇒ Boolean

Returns whether key exists in the parameters hash.

Returns:

  • (Boolean)


131
132
133
# File 'lib/bindata/base.rb', line 131

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

#initialize_instance(*args) ⇒ Object



26
27
28
29
30
# File 'lib/bindata/warnings.rb', line 26

def initialize_instance(*args)
  unless args.empty?
    fail "#{caller[0]} remove the call to super in #initialize_instance"
  end
end

#initialize_with_warning(*args) ⇒ Object Also known as: initialize



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/bindata/warnings.rb', line 13

def initialize_with_warning(*args)
  owner = method(:initialize).owner
  if owner != BinData::Base
    msg = "Don't override #initialize on #{owner}."
    if %w(BinData::Base BinData::BasePrimitive).include? self.class.superclass.name
      msg += "\nrename #initialize to #initialize_instance."
    end
    fail msg
  end
  initialize_without_warning(*args)
end

#inspectObject

Return a human readable representation of this data object.



191
192
193
# File 'lib/bindata/base.rb', line 191

def inspect
  snapshot.inspect
end

#lazy_evaluatorObject

Returns a lazy evaluator for this object.



119
120
121
# File 'lib/bindata/base.rb', line 119

def lazy_evaluator #:nodoc:
  @lazy ||= LazyEvaluator.new(self)
end

#new(value = nil, parent = nil) ⇒ Object

Creates a new data object based on this instance.

All parameters will be be duplicated. Use this method when creating multiple objects with the same parameters.



94
95
96
97
98
99
100
101
# File 'lib/bindata/base.rb', line 94

def new(value = nil, parent = nil)
  obj = clone
  obj.parent = parent if parent
  obj.initialize_instance
  obj.assign(value) if value

  obj
end

#num_bytesObject

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



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

def num_bytes
  do_num_bytes.ceil
end

#offsetObject

#offset has been renamed to #abs_offset. Eventually #rel_offset will be renamed to #offset.



34
35
36
37
# File 'lib/bindata/warnings.rb', line 34

def offset
  warn "#offset is deprecated in #{debug_name}. Use #abs_offset instead"
  abs_offset
end

#pretty_print(pp) ⇒ Object

Work with Ruby’s pretty-printer library.



201
202
203
# File 'lib/bindata/base.rb', line 201

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

#read(io) ⇒ Object

Reads data into this data object.



141
142
143
144
145
146
147
148
149
150
# File 'lib/bindata/base.rb', line 141

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

  @in_read = true
  clear
  do_read(io)
  @in_read = false

  self
end

#rel_offsetObject

Returns the offset (in bytes) of this object with respect to its parent.



230
231
232
233
234
235
236
# File 'lib/bindata/base.rb', line 230

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

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

A version of respond_to? used by the lazy evaluator. It doesn’t reinvoke the evaluator so as to avoid infinite evaluation loops.

Returns:

  • (Boolean)


245
246
247
# File 'lib/bindata/base.rb', line 245

def safe_respond_to?(symbol, include_private = false) #:nodoc:
  respond_to?(symbol, include_private)
end

#to_binary_sObject

Returns the string representation of this data object.



178
179
180
181
182
183
# File 'lib/bindata/base.rb', line 178

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

#to_hexObject

Returns the hexadecimal string representation of this data object.



186
187
188
# File 'lib/bindata/base.rb', line 186

def to_hex
  to_binary_s.unpack('H*')[0]
end

#to_sObject

Return a string representing this data object.



196
197
198
# File 'lib/bindata/base.rb', line 196

def to_s
  snapshot.to_s
end

#write(io) ⇒ Object

Writes the value for this data object to io.



164
165
166
167
168
169
170
# File 'lib/bindata/base.rb', line 164

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

  do_write(io)
  io.flush
  self
end