Class: BinData::Base
- Inherits:
-
Object
- Object
- BinData::Base
- Defined in:
- lib/bindata/base.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 params are:
:readwrite
-
If false, calls to #read or #write will not perform any I/O. Default is true.
: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.
Class Method Summary collapse
-
.accepted_parameters ⇒ Object
Returns a list of parameters that are accepted by this object.
-
.default_parameters(params = {}) ⇒ Object
(also: default_parameter)
Returns the default parameters used by this class.
-
.lookup(name, endian = nil) ⇒ Object
Returns the class matching a previously registered
name
. -
.mandatory_parameters(*args) ⇒ Object
(also: mandatory_parameter)
Returns the mandatory parameters used by this class.
-
.mutually_exclusive_parameters(*args) ⇒ Object
Returns the pairs of mutually exclusive parameters used by this class.
-
.optional_parameters(*args) ⇒ Object
(also: optional_parameter)
Returns the optional parameters used by this class.
-
.read(io) ⇒ Object
Instantiates this class and reads from
io
. -
.register(name, klass) ⇒ Object
Registers the mapping of
name
toklass
. -
.sanitize_parameters(params, *args) ⇒ Object
Returns a sanitized
params
that is of the form expected by #initialize.
Instance Method Summary collapse
-
#clear ⇒ Object
Resets the internal state to that of a newly created object.
-
#do_read(io) ⇒ Object
Reads the value for this data from
io
. -
#done_read ⇒ Object
To be called after calling #do_read.
-
#field_names ⇒ Object
Returns a list of the names of all fields accessible through this object.
-
#initialize(params = {}, env = nil) ⇒ Base
constructor
Creates a new data object.
-
#inspect ⇒ Object
Return a human readable representation of this object.
-
#num_bytes(what = nil) ⇒ Object
Returns the number of bytes it will take to write this data.
-
#read(io) ⇒ Object
Reads data into this data object by calling #do_read then #done_read.
-
#single_value? ⇒ Boolean
Returns whether this data object contains a single value.
-
#snapshot ⇒ Object
Returns a snapshot of this data object.
-
#to_s ⇒ Object
Returns the string representation of this data object.
-
#write(io) ⇒ Object
Writes the value for this data to
io
.
Constructor Details
#initialize(params = {}, env = nil) ⇒ Base
Creates a new data object.
params
is a hash containing symbol keys. Some params may reference callable objects (methods or procs). env
is the environment that these callable objects are evaluated in.
186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/bindata/base.rb', line 186 def initialize(params = {}, env = nil) unless SanitizedParameters === params params = SanitizedParameters.new(self.class, params) end @params = params.accepted_parameters # set up the environment @env = env || LazyEvalEnv.new @env.params = params.extra_parameters @env.data_object = self end |
Class Method Details
.accepted_parameters ⇒ Object
Returns a list of parameters that are accepted by this object
110 111 112 |
# File 'lib/bindata/base.rb', line 110 def accepted_parameters (mandatory_parameters + optional_parameters + default_parameters.keys).uniq end |
.default_parameters(params = {}) ⇒ Object Also known as: default_parameter
Returns the default parameters used by this class. Any given args are appended to the parameters list. The parameters for a class will include the parameters of its ancestors.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/bindata/base.rb', line 75 def default_parameters(params = {}) unless defined? @default_parameters @default_parameters = {} ancestors[1..-1].each do |parent| if parent.respond_to?(:default_parameters) @default_parameters = @default_parameters.merge(parent.default_parameters) end end end if not params.empty? @default_parameters = @default_parameters.merge(params) end @default_parameters end |
.lookup(name, endian = nil) ⇒ Object
Returns the class matching a previously registered name
.
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/bindata/base.rb', line 159 def lookup(name, endian = nil) name = name.to_s klass = Registry.instance.lookup(name) if klass.nil? and endian != nil # lookup failed so attempt endian lookup if /^u?int\d{1,3}$/ =~ name new_name = name + ((endian == :little) ? "le" : "be") klass = Registry.instance.lookup(new_name) elsif ["float", "double"].include?(name) new_name = name + ((endian == :little) ? "_le" : "_be") klass = Registry.instance.lookup(new_name) end end klass end |
.mandatory_parameters(*args) ⇒ Object Also known as: mandatory_parameter
Returns the mandatory parameters used by this class. Any given args are appended to the parameters list. The parameters for a class will include the parameters of its ancestors.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/bindata/base.rb', line 35 def mandatory_parameters(*args) unless defined? @mandatory_parameters @mandatory_parameters = [] ancestors[1..-1].each do |parent| if parent.respond_to?(:mandatory_parameters) @mandatory_parameters.concat(parent.mandatory_parameters) end end end if not args.empty? args.each { |arg| @mandatory_parameters << arg.to_sym } @mandatory_parameters.uniq! end @mandatory_parameters end |
.mutually_exclusive_parameters(*args) ⇒ Object
Returns the pairs of mutually exclusive parameters used by this class. Any given args are appended to the parameters list. The parameters for a class will include the parameters of its ancestors.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/bindata/base.rb', line 94 def mutually_exclusive_parameters(*args) unless defined? @mutually_exclusive_parameters @mutually_exclusive_parameters = [] ancestors[1..-1].each do |parent| if parent.respond_to?(:mutually_exclusive_parameters) @mutually_exclusive_parameters.concat(parent.mutually_exclusive_parameters) end end end if not args.empty? @mutually_exclusive_parameters << [args[0].to_sym, args[1].to_sym] end @mutually_exclusive_parameters end |
.optional_parameters(*args) ⇒ Object Also known as: optional_parameter
Returns the optional parameters used by this class. Any given args are appended to the parameters list. The parameters for a class will include the parameters of its ancestors.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/bindata/base.rb', line 55 def optional_parameters(*args) unless defined? @optional_parameters @optional_parameters = [] ancestors[1..-1].each do |parent| if parent.respond_to?(:optional_parameters) @optional_parameters.concat(parent.optional_parameters) end end end if not args.empty? args.each { |arg| @optional_parameters << arg.to_sym } @optional_parameters.uniq! end @optional_parameters end |
.read(io) ⇒ Object
Instantiates this class and reads from io
. For single value objects just the value is returned, otherwise the newly created data object is returned.
146 147 148 149 150 |
# File 'lib/bindata/base.rb', line 146 def read(io) data = self.new data.read(io) data.single_value? ? data.value : data end |
.register(name, klass) ⇒ Object
Registers the mapping of name
to klass
.
153 154 155 |
# File 'lib/bindata/base.rb', line 153 def register(name, klass) Registry.instance.register(name, klass) end |
.sanitize_parameters(params, *args) ⇒ Object
Returns a sanitized params
that is of the form expected by #initialize.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/bindata/base.rb', line 116 def sanitize_parameters(params, *args) params = params.dup # add default parameters default_parameters.each do |k,v| params[k] = v unless params.has_key?(k) end # ensure mandatory parameters exist mandatory_parameters.each do |prm| if not params.has_key?(prm) raise ArgumentError, "parameter ':#{prm}' must be specified " + "in #{self}" end end # ensure mutual exclusion mutually_exclusive_parameters.each do |param1, param2| if params.has_key?(param1) and params.has_key?(param2) raise ArgumentError, "params #{param1} and #{param2} " + "are mutually exclusive" end end params end |
Instance Method Details
#clear ⇒ Object
Resets the internal state to that of a newly created object.
316 317 318 |
# File 'lib/bindata/base.rb', line 316 def clear raise NotImplementedError end |
#do_read(io) ⇒ Object
Reads the value for this data from io
.
218 219 220 221 222 |
# File 'lib/bindata/base.rb', line 218 def do_read(io) clear check_offset(io) _do_read(io) if eval_param(:readwrite) != false end |
#done_read ⇒ Object
To be called after calling #do_read.
326 327 328 |
# File 'lib/bindata/base.rb', line 326 def done_read raise NotImplementedError end |
#field_names ⇒ Object
Returns a list of the names of all fields accessible through this object.
353 354 355 |
# File 'lib/bindata/base.rb', line 353 def field_names raise NotImplementedError end |
#inspect ⇒ Object
Return a human readable representation of this object.
243 244 245 |
# File 'lib/bindata/base.rb', line 243 def inspect snapshot.inspect end |
#num_bytes(what = nil) ⇒ Object
Returns the number of bytes it will take to write this data.
238 239 240 |
# File 'lib/bindata/base.rb', line 238 def num_bytes(what = nil) (eval_param(:readwrite) != false) ? _num_bytes(what) : 0 end |
#read(io) ⇒ Object
Reads data into this data object by calling #do_read then #done_read.
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/bindata/base.rb', line 200 def read(io) # wrap strings in a StringIO io = StringIO.new(io) if io.respond_to?(:to_str) # remove previous method to prevent warnings class << io remove_method(:bindata_mark) if method_defined?(:bindata_mark) end # remember the current position in the IO object io.instance_eval "def bindata_mark; #{io.pos}; end" do_read(io) done_read self end |
#single_value? ⇒ Boolean
Returns whether this data object contains a single value. Single value data objects respond to #value
and #value=
.
347 348 349 |
# File 'lib/bindata/base.rb', line 347 def single_value? raise NotImplementedError end |
#snapshot ⇒ Object
Returns a snapshot of this data object.
341 342 343 |
# File 'lib/bindata/base.rb', line 341 def snapshot raise NotImplementedError end |
#to_s ⇒ Object
Returns the string representation of this data object.
230 231 232 233 234 235 |
# File 'lib/bindata/base.rb', line 230 def to_s io = StringIO.new write(io) io.rewind io.read end |
#write(io) ⇒ Object
Writes the value for this data to io
.
225 226 227 |
# File 'lib/bindata/base.rb', line 225 def write(io) _write(io) if eval_param(:readwrite) != false end |