lib/bindata/base.rb in bindata-0.9.1 vs lib/bindata/base.rb in bindata-0.9.2
- old
+ new
@@ -1,9 +1,9 @@
require 'bindata/io'
require 'bindata/lazy'
-require 'bindata/sanitize'
require 'bindata/registry'
+require 'bindata/sanitize'
require 'stringio'
module BinData
# Error raised when unexpected results occur when reading data from IO.
class ValidityError < StandardError ; end
@@ -13,15 +13,15 @@
# == Parameters
#
# Parameters may be provided at initialisation to control the behaviour of
# an object. These params are:
#
- # [<tt>:readwrite</tt>] If false, calls to #read or #write will
- # not perform any I/O. Default is true.
- # [<tt>:onlyif</tt>] This is an alias for :readwrite. It is generally
- # used to indicate a data object is optional.
- # not perform any I/O. Default is true.
+ # [<tt>:readwrite</tt>] Deprecated. An alias for :onlyif.
+ # [<tt>:onlyif</tt>] Used to indicate a data object is optional.
+ # if false, calls to #read or #write will not
+ # perform any I/O, #num_bytes will return 0 and
+ # #snapshot will return nil. Default is true.
# [<tt>:check_offset</tt>] 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
@@ -39,11 +39,12 @@
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)
+ pmp = parent.mandatory_parameters
+ @mandatory_parameters.concat(pmp)
end
end
end
if not args.empty?
args.each { |arg| @mandatory_parameters << arg.to_sym }
@@ -59,11 +60,12 @@
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)
+ pop = parent.optional_parameters
+ @optional_parameters.concat(pop)
end
end
end
if not args.empty?
args.each { |arg| @optional_parameters << arg.to_sym }
@@ -79,11 +81,12 @@
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)
+ pdp = parent.default_parameters
+ @default_parameters = @default_parameters.merge(pdp)
end
end
end
if not params.empty?
@default_parameters = @default_parameters.merge(params)
@@ -98,11 +101,12 @@
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)
+ pmep = parent.mutually_exclusive_parameters
+ @mutually_exclusive_parameters.concat(pmep)
end
end
end
if not args.empty?
@mutually_exclusive_parameters << [args[0].to_sym, args[1].to_sym]
@@ -115,16 +119,17 @@
(mandatory_parameters + optional_parameters + default_parameters.keys).uniq
end
# Returns a sanitized +params+ that is of the form expected
# by #initialize.
- def sanitize_parameters(params, *args)
+ def sanitize_parameters(sanitizer, params, *args)
params = params.dup
- # replace :onlyif with :readwrite
- if params.has_key?(:onlyif)
- params[:readwrite] = params.delete(:onlyif)
+ # replace :readwrite with :onlyif
+ if params.has_key?(:readwrite)
+ warn ":readwrite is deprecated. Replacing with :onlyif"
+ params[:onlyif] = params.delete(:readwrite)
end
# add default parameters
default_parameters.each do |k,v|
params[k] = v unless params.has_key?(k)
@@ -161,42 +166,25 @@
# Registers the mapping of +name+ to +klass+.
def register(name, klass)
Registry.instance.register(name, klass)
end
private :register
-
- # Returns the class matching a previously registered +name+.
- 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
end
# Define the parameters we use in this class.
optional_parameters :check_offset, :adjust_offset
- default_parameters :readwrite => true
+ default_parameters :onlyif => true
mutually_exclusive_parameters :check_offset, :adjust_offset
# 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.
def initialize(params = {}, env = nil)
unless SanitizedParameters === params
- params = SanitizedParameters.new(self.class, params)
+ params = Sanitizer.sanitize(self, params)
end
@params = params.accepted_parameters
# set up the environment
@@ -219,11 +207,11 @@
raise ArgumentError, "io must be a BinData::IO" unless BinData::IO === io
clear
check_offset(io)
- if eval_param(:readwrite)
+ if eval_param(:onlyif)
_do_read(io)
end
end
# Writes the value for this data to +io+ by calling #do_write.
@@ -238,11 +226,11 @@
# Writes the value for this data to +io+.
def do_write(io)
raise ArgumentError, "io must be a BinData::IO" unless BinData::IO === io
- if eval_param(:readwrite)
+ if eval_param(:onlyif)
_do_write(io)
end
end
# Returns the number of bytes it will take to write this data by calling
@@ -252,17 +240,27 @@
num.ceil
end
# Returns the number of bytes it will take to write this data.
def do_num_bytes(what = nil)
- if eval_param(:readwrite)
+ if eval_param(:onlyif)
_do_num_bytes(what)
else
0
end
end
+ # Returns a snapshot of this data object.
+ # Returns nil if :onlyif is false
+ def snapshot
+ if eval_param(:onlyif)
+ _snapshot
+ else
+ nil
+ end
+ end
+
# Returns the string representation of this data object.
def to_s
io = StringIO.new
write(io)
io.rewind
@@ -334,38 +332,26 @@
end
###########################################################################
# To be implemented by subclasses
- # Returns a list of the names of all possible field names for an object
- # created with +sanitized_params+.
- def self.all_possible_field_names(sanitized_params)
+ # Resets the internal state to that of a newly created object.
+ def clear
raise NotImplementedError
end
- # Resets the internal state to that of a newly created object.
- def clear
+ # Returns true if the object has not been changed since creation.
+ def clear?(*args)
raise NotImplementedError
end
# Returns whether this data object contains a single value. Single
# value data objects respond to <tt>#value</tt> and <tt>#value=</tt>.
def single_value?
raise NotImplementedError
end
- # Returns a list of the names of all fields accessible through this
- # object.
- def field_names
- raise NotImplementedError
- end
-
- # Returns a snapshot of this data object.
- def snapshot
- raise NotImplementedError
- end
-
# To be called after calling #do_read.
def done_read
raise NotImplementedError
end
@@ -382,12 +368,17 @@
# Returns the number of bytes it will take to write this data.
def _do_num_bytes
raise NotImplementedError
end
+ # Returns a snapshot of this data object.
+ def _snapshot
+ raise NotImplementedError
+ end
+
# Set visibility requirements of methods to implement
- public :clear, :single_value?, :field_names, :snapshot, :done_read
- private :_do_read, :_do_write, :_do_num_bytes
+ public :clear, :clear?, :single_value?, :done_read
+ private :_do_read, :_do_write, :_do_num_bytes, :_snapshot
# End To be implemented by subclasses
###########################################################################
end
end