Class: BinData::Base
- Inherits:
-
Object
- Object
- BinData::Base
- Extended by:
- AcceptedParametersPlugin
- Includes:
- Framework, RegisterNamePlugin
- Defined in:
- lib/bindata/base.rb,
lib/bindata/struct.rb,
lib/bindata/warnings.rb,
lib/bindata/delayed_io.rb
Overview
This is the abstract base class for all data objects.
Direct Known Subclasses
Array, BasePrimitive, Buffer, Choice, DelayedIO, ResumeByteAlignment, Section, Struct
Defined Under Namespace
Modules: AutoCallDelayedIO
Instance Attribute Summary collapse
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
Class Method Summary collapse
-
.arg_processor(name = nil) ⇒ Object
The arg processor for this class.
-
.auto_call_delayed_io ⇒ Object
The
auto_call_delayed_iokeyword sets a data object tree to perform multi pass I/O automatically. -
.bindata_name ⇒ Object
The name of this class as used by Records, Arrays etc.
-
.read(io, *args, &block) ⇒ Object
Instantiates this class and reads from
io, returning the newly created data object. -
.register_subclasses ⇒ Object
Registers all subclasses of this class for use.
-
.unregister_self ⇒ Object
Call this method if this class is abstract and not to be used.
Instance Method Summary collapse
-
#==(other) ⇒ Object
:nodoc:.
-
#=~(other) ⇒ Object
Override and delegate =~ as it is defined in Object.
-
#abs_offset ⇒ Object
Returns the offset (in bytes) of this object with respect to its most distant ancestor.
-
#clear ⇒ Object
Resets the internal state to that of a newly created object.
-
#debug_name ⇒ Object
Returns a user friendly name of this object for debugging purposes.
-
#eval_parameter(key, overrides = nil) ⇒ Object
Returns the result of evaluating the parameter identified by
key. -
#get_parameter(key) ⇒ Object
Returns the parameter referenced by
key. -
#has_parameter?(key) ⇒ Boolean
Returns whether
keyexists in theparametershash. - #initialize_instance(*args) ⇒ Object
- #initialize_with_warning(*args) ⇒ Object (also: #initialize)
-
#inspect ⇒ Object
Return a human readable representation of this data object.
-
#lazy_evaluator ⇒ Object
Returns a lazy evaluator for this object.
-
#new(value = nil, parent = nil) ⇒ Object
Creates a new data object based on this instance.
-
#num_bytes ⇒ Object
Returns the number of bytes it will take to write this data object.
-
#pretty_print(pp) ⇒ Object
Work with Ruby's pretty-printer library.
-
#read(io, &block) ⇒ Object
Reads data into this data object.
-
#rel_offset ⇒ Object
Returns the offset (in bytes) of this object with respect to its parent.
-
#safe_respond_to?(symbol, include_private = false) ⇒ Boolean
A version of
respond_to?used by the lazy evaluator. -
#to_binary_s(&block) ⇒ Object
Returns the string representation of this data object.
-
#to_hex(&block) ⇒ Object
Returns the hexadecimal string representation of this data object.
-
#to_s ⇒ Object
Return a string representing this data object.
-
#write(io, &block) ⇒ Object
Writes the value for this data object to
io.
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 Framework
#assign, #bit_aligned?, #clear?, #debug_name_of, #offset_of, #snapshot
Instance Attribute Details
#parent ⇒ Object
Returns the value of attribute parent.
95 96 97 |
# File 'lib/bindata/base.rb', line 95 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_io ⇒ Object
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 176 |
# File 'lib/bindata/delayed_io.rb', line 161 def auto_call_delayed_io include AutoCallDelayedIO return if DelayedIO.method_defined? :initialize_instance_without_record_io 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_name ⇒ Object
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 = new(*args) obj.read(io, &block) obj end |
.register_subclasses ⇒ Object
Registers all subclasses of this class for use
55 56 57 58 59 60 61 62 63 64 |
# File 'lib/bindata/base.rb', line 55 def register_subclasses # :nodoc: singleton_class.send(:undef_method, :inherited) define_singleton_method(:inherited) do |subclass| m = /(.*)::([^:].*)/.match(subclass.name) namespace = m ? m[1] : "" shortname = m ? m[2] : subclass RegisteredClasses.register(namespace, shortname, subclass) register_subclasses end end |
.unregister_self ⇒ Object
Call this method if this class is abstract and not to be used.
46 47 48 49 50 51 52 |
# File 'lib/bindata/base.rb', line 46 def unregister_self m = /(.*)::([^:].*)/.match(name) namespace = m ? m[1] : "" shortname = m ? m[2] : name RegisteredClasses.unregister(namespace, shortname) end |
Instance Method Details
#==(other) ⇒ Object
:nodoc:
228 229 230 231 |
# File 'lib/bindata/base.rb', line 228 def ==(other) # :nodoc: # double dispatch other == snapshot end |
#=~(other) ⇒ Object
Override and delegate =~ as it is defined in Object.
208 209 210 |
# File 'lib/bindata/base.rb', line 208 def =~(other) snapshot =~ other end |
#abs_offset ⇒ Object
Returns the offset (in bytes) of this object with respect to its most distant ancestor.
219 220 221 |
# File 'lib/bindata/base.rb', line 219 def abs_offset @parent ? @parent.abs_offset + @parent.offset_of(self) : 0 end |
#clear ⇒ Object
Resets the internal state to that of a newly created object.
146 147 148 |
# File 'lib/bindata/base.rb', line 146 def clear initialize_instance end |
#debug_name ⇒ Object
Returns a user friendly name of this object for debugging purposes.
213 214 215 |
# File 'lib/bindata/base.rb', line 213 def debug_name @parent ? @parent.debug_name_of(self) : 'obj' 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.
119 120 121 122 123 124 125 126 |
# File 'lib/bindata/base.rb', line 119 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.
136 137 138 |
# File 'lib/bindata/base.rb', line 136 def get_parameter(key) @params[key] end |
#has_parameter?(key) ⇒ Boolean
Returns whether key exists in the parameters hash.
141 142 143 |
# File 'lib/bindata/base.rb', line 141 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 |
#inspect ⇒ Object
Return a human readable representation of this data object.
193 194 195 |
# File 'lib/bindata/base.rb', line 193 def inspect snapshot.inspect end |
#lazy_evaluator ⇒ Object
Returns a lazy evaluator for this object.
129 130 131 |
# File 'lib/bindata/base.rb', line 129 def lazy_evaluator # :nodoc: @lazy_evaluator ||= LazyEvaluator.new(self) end |
#new(value = nil, parent = nil) ⇒ Object
Creates a new data object based on this instance.
This implements the prototype design pattern.
All parameters will be be duplicated. Use this method when creating multiple objects with the same parameters.
104 105 106 107 108 109 110 111 |
# File 'lib/bindata/base.rb', line 104 def new(value = nil, parent = nil) obj = clone obj.parent = parent if parent obj.initialize_instance obj.assign(value) if value obj end |
#num_bytes ⇒ Object
Returns the number of bytes it will take to write this data object.
176 177 178 |
# File 'lib/bindata/base.rb', line 176 def num_bytes do_num_bytes.ceil end |
#pretty_print(pp) ⇒ Object
Work with Ruby's pretty-printer library.
203 204 205 |
# File 'lib/bindata/base.rb', line 203 def pretty_print(pp) # :nodoc: pp.pp(snapshot) end |
#read(io, &block) ⇒ Object
Reads data into this data object.
151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/bindata/base.rb', line 151 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_offset ⇒ Object
Returns the offset (in bytes) of this object with respect to its parent.
224 225 226 |
# File 'lib/bindata/base.rb', line 224 def rel_offset @parent ? @parent.offset_of(self) : 0 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.
235 236 237 |
# File 'lib/bindata/base.rb', line 235 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.
181 182 183 184 185 |
# File 'lib/bindata/base.rb', line 181 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.
188 189 190 |
# File 'lib/bindata/base.rb', line 188 def to_hex(&block) to_binary_s(&block).unpack1('H*') end |
#to_s ⇒ Object
Return a string representing this data object.
198 199 200 |
# File 'lib/bindata/base.rb', line 198 def to_s snapshot.to_s end |
#write(io, &block) ⇒ Object
Writes the value for this data object to io.
164 165 166 167 168 169 170 171 172 173 |
# File 'lib/bindata/base.rb', line 164 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 |