class BinData::SanitizedParameters
at a single time.
is to recursively sanitize the parameters of an entire BinData object chain
SanitizedParameters is a hash-like collection of parameters. Its purpose
validation.
The purpose of the sanitizing code is to eliminate the duplicated
such as an array of records, there is much duplicated sanitizing.
are valid. When instantiating many objects with identical parameters,
behaviour. These parameters must be sanitized to ensure their values
BinData objects are instantiated with parameters to determine their
def create_sanitized_choices(choices)
def create_sanitized_choices(choices) SanitizedChoices.new(choices, hints) end
def create_sanitized_endian(endian)
def create_sanitized_endian(endian) if endian == :big BIG_ENDIAN elsif endian == :little LITTLE_ENDIAN elsif endian == :big_and_little raise ArgumentError, "endian: :big or endian: :little is required" else raise ArgumentError, "unknown value for endian '#{endian}'" end end
def create_sanitized_fields
def create_sanitized_fields SanitizedFields.new(hints) end
def create_sanitized_object_prototype(obj_type, obj_params)
def create_sanitized_object_prototype(obj_type, obj_params) SanitizedPrototype.new(obj_type, obj_params, hints) end
def create_sanitized_params(params, the_class)
def create_sanitized_params(params, the_class) SanitizedParameters.new(params, the_class, hints) end
def ensure_mandatory_parameters_exist
def ensure_mandatory_parameters_exist @the_class.mandatory_parameters.each do |key| unless has_parameter?(key) raise ArgumentError, "parameter '#{key}' must be specified in #{@the_class}" end end end
def ensure_mutual_exclusion_of_parameters
def ensure_mutual_exclusion_of_parameters return if length < 2 @the_class.mutually_exclusive_parameters.each do |key1, key2| if has_parameter?(key1) && has_parameter?(key2) raise ArgumentError, "params '#{key1}' and '#{key2}' " \ "are mutually exclusive in #{@the_class}" end end end
def ensure_no_nil_values
def ensure_no_nil_values each do |key, value| if value.nil? raise ArgumentError, "parameter '#{key}' has nil value in #{@the_class}" end end end
def has_at_least_one_of?(*keys)
def has_at_least_one_of?(*keys) keys.each do |key| return true if has_parameter?(key) end false end
def hints
def hints { endian: self[:endian], search_prefix: self[:search_prefix] } end
def initialize(parameters, the_class, hints)
def initialize(parameters, the_class, hints) parameters.each_pair { |key, value| self[key.to_sym] = value } @the_class = the_class if hints[:endian] self[:endian] ||= hints[:endian] end if hints[:search_prefix] && !hints[:search_prefix].empty? self[:search_prefix] = Array(self[:search_prefix]).concat(Array(hints[:search_prefix])) end sanitize! end
def merge_default_parameters!
def merge_default_parameters! @the_class.default_parameters.each do |key, value| self[key] = value unless has_parameter?(key) end end
def must_be_integer(*keys)
def must_be_integer(*keys) keys.each do |key| if has_parameter?(key) parameter = self[key] unless Symbol === parameter || parameter.respond_to?(:arity) || parameter.respond_to?(:to_int) raise ArgumentError, "parameter '#{key}' in #{@the_class} must " \ "evaluate to an integer, got #{parameter.class}" end end end end
def needs_sanitizing?(key)
def needs_sanitizing?(key) has_parameter?(key) && !self[key].is_a?(SanitizedParameter) end
def rename_parameter(old_key, new_key)
def rename_parameter(old_key, new_key) if has_parameter?(old_key) self[new_key] = delete(old_key) end end
def sanitize(parameters, the_class)
def sanitize(parameters, the_class) if SanitizedParameters === parameters parameters else SanitizedParameters.new(parameters, the_class, {}) end end
def sanitize(key, &block)
def sanitize(key, &block) if needs_sanitizing?(key) self[key] = yield(self[key]) end end
def sanitize!
def sanitize! ensure_no_nil_values merge_default_parameters! @the_class.arg_processor.sanitize_parameters!(@the_class, self) ensure_mandatory_parameters_exist ensure_mutual_exclusion_of_parameters end
def sanitize_choices(key, &block)
def sanitize_choices(key, &block) sanitize(key) do |obj| create_sanitized_choices(yield(obj)) end end
def sanitize_endian(key)
def sanitize_endian(key) sanitize(key) { |endian| create_sanitized_endian(endian) } end
def sanitize_fields(key, &block)
def sanitize_fields(key, &block) sanitize(key) do |fields| sanitized_fields = create_sanitized_fields yield(fields, sanitized_fields) sanitized_fields end end
def sanitize_object_prototype(key)
def sanitize_object_prototype(key) sanitize(key) do |obj_type, obj_params| create_sanitized_object_prototype(obj_type, obj_params) end end
def warn_replacement_parameter(bad_key, suggested_key)
def warn_replacement_parameter(bad_key, suggested_key) if has_parameter?(bad_key) Kernel.warn ":#{bad_key} is not used with #{@the_class}. " \ "You probably want to change this to :#{suggested_key}" end end