Class: BinData::Base

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

Overview

Add auto_call_delayed_io keyword to BinData::Base.

Defined Under Namespace

Modules: AutoCallDelayedIO

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 CheckOrAdjustOffsetPlugin

included, #initialize_shared_instance

Methods included from RegisterNamePlugin

included, #initialize_shared_instance

Methods included from Framework

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

Instance Attribute Details

#parentObject

Returns the value of attribute parent.



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

def parent
  @parent
end

Class Method Details

.arg_processor(name = nil) ⇒ Object

The arg processor for this class.



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

def arg_processor(name = nil)
  @arg_processor ||= 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

.auto_call_delayed_ioObject

The auto_call_delayed_io keyword sets a data object tree to perform multi pass I/O automatically.



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/bindata/delayed_io.rb', line 161

def auto_call_delayed_io
  return if DelayedIO.method_defined? :initialize_instance_without_record_io

  include AutoCallDelayedIO
  DelayedIO.send(:alias_method, :initialize_instance_without_record_io, :initialize_instance)
  DelayedIO.send(:define_method, :initialize_instance) do
    if @parent && !defined? @delayed_io_recorded
      @delayed_io_recorded = true
      list = top_level_get(:delayed_ios)
      list << self if list
    end

    initialize_instance_without_record_io
  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(name)
end

.read(io, *args, &block) ⇒ Object

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



19
20
21
22
23
# File 'lib/bindata/base.rb', line 19

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

.register_subclassesObject

Registers all subclasses of this class for use



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

def register_subclasses #:nodoc:
  singleton_class.send(:undef_method, :inherited)
  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:



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

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

#=~(other) ⇒ Object

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



199
200
201
# File 'lib/bindata/base.rb', line 199

def =~(other)
  snapshot =~ other
end

#abs_offsetObject

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



214
215
216
217
218
219
220
# File 'lib/bindata/base.rb', line 214

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.



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

def clear
  initialize_instance
end

#debug_nameObject

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



204
205
206
207
208
209
210
# File 'lib/bindata/base.rb', line 204

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.



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

def eval_parameter(key, overrides = nil)
  value = get_parameter(key)
  if value.is_a?(Symbol) || 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.



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

def get_parameter(key)
  @params[key]
end

#has_parameter?(key) ⇒ Boolean

Returns whether key exists in the parameters hash.

Returns:

  • (Boolean)


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

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

#initialize_instance(*args) ⇒ Object



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

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



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

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.



184
185
186
# File 'lib/bindata/base.rb', line 184

def inspect
  snapshot.inspect
end

#lazy_evaluatorObject

Returns a lazy evaluator for this object.



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

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.



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

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.



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

def num_bytes
  do_num_bytes.ceil
end

#pretty_print(pp) ⇒ Object

Work with Ruby’s pretty-printer library.



194
195
196
# File 'lib/bindata/base.rb', line 194

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

#read(io, &block) ⇒ Object

Reads data into this data object.



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

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

  start_read do
    clear
    do_read(io)
  end
  block.call(self) if block_given?

  self
end

#rel_offsetObject

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



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

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)


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

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

#to_binary_s(&block) ⇒ Object

Returns the string representation of this data object.



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

def to_binary_s(&block)
  io = BinData::IO.create_string_io
  write(io, &block)
  io.string
end

#to_hex(&block) ⇒ Object

Returns the hexadecimal string representation of this data object.



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

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

#to_sObject

Return a string representing this data object.



189
190
191
# File 'lib/bindata/base.rb', line 189

def to_s
  snapshot.to_s
end

#write(io, &block) ⇒ Object

Writes the value for this data object to io.



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

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

  do_write(io)
  io.flush

  block.call(self) if block_given?

  self
end