module BitStream::ClassMethods
Public Class Methods
add_type(type, method_name = nil, bs = self)
click to toggle source
# File lib/bitstream.rb, line 303 def self.add_type(type, method_name = nil, bs = self) bs.instance_eval do define_method(method_name) do |*args| name = args.shift.intern #if respond_to? name # raise "#{name} has already defined." #end props = @instance.bitstream_properties fields = props.fields queue = props.eval_queue user_props = props.user_props case props.mode when :field_def type_instance = get_type(method_name, user_props, *args) field = FieldReader.new(type_instance, @instance) queue.enq(field) name_in_method = name @instance.singleton_class.instance_eval do define_method name do field.value end end instance = @instance singleton_class.instance_eval do define_method name_in_method do instance.send(name_in_method) end end end end end end
alias_type(alias_name, aliasee)
click to toggle source
# File lib/bitstream.rb, line 286 def self.alias_type(alias_name, aliasee) @types[alias_name] = @types[aliasee] alias_method(alias_name, aliasee) end
register_type(type, name = nil)
click to toggle source
# File lib/bitstream.rb, line 275 def self.register_type(type, name = nil) if name.nil? name = Utils.class2symbol type end @types = {} if @types.nil? @types[name] = type add_type(type, name, self) end
register_types(types)
click to toggle source
# File lib/bitstream.rb, line 269 def self.register_types(types) types.each do |t| register_type(t, nil) end end
types()
click to toggle source
# File lib/bitstream.rb, line 265 def self.types @types end
Public Instance Methods
add_type(type, name = nil)
click to toggle source
# File lib/bitstream.rb, line 448 def add_type(type, name = nil) if name.nil? name = Utils.class2symbol(type) end @types[name] = type ClassMethods.add_type(type, name, self.singleton_class) end
array(name, size, type_name, *type_args)
click to toggle source
# File lib/bitstream.rb, line 341 def array(name, size, type_name, *type_args) name = name.intern props = @instance.bitstream_properties queue = props.eval_queue user_props = props.user_props type_instance = get_type(type_name, user_props, *type_args) case props.mode when :field_def field = ArrayProxy.new(@instance) if size.respond_to?(:to_int) && size >= 0 size.times do field_element = FieldReader.new(type_instance, @instance) field.add_field(field_element) queue.enq(field_element) end else queue.peek_back.index unless queue.empty? while props.curr_offset < props.raw_data.bytesize * 8 field_element = FieldReader.new(type_instance, @instance) field.add_field(field_element) queue.enq(field_element) field_element.index #puts "curr_offset:#{props.curr_offset} bytesize:#{props.raw_data.bytesize}" end end @instance.singleton_class.instance_eval do define_method name do field end end name_in_method = name instance = @instance singleton_class.instance_eval do define_method name do instance.send(name_in_method) end end end end
byte_order(order)
click to toggle source
# File lib/bitstream.rb, line 295 def byte_order(order) @class_props[:byte_order] = order.intern end
create(s, props = {})
click to toggle source
# File lib/bitstream.rb, line 460 def create(s, props = {}) create_with_offset(s, 0, props) end
create_with_offset(s, offset, props = {})
click to toggle source
# File lib/bitstream.rb, line 464 def create_with_offset(s, offset, props = {}) props[:nest_chain] = [] unless props.include?(:nest_chain) klass = Class.new(self) instance = klass.new instance.initialize_properties(s, offset) instance.bitstream_properties.user_props = props initialize_instance(s, instance) instance.initialize_with_fields return instance end
dyn_array(name, type_name, *type_args)
click to toggle source
# File lib/bitstream.rb, line 385 def dyn_array(name, type_name, *type_args) name = name.intern props = @instance.bitstream_properties fields = props.fields queue = props.eval_queue user_props = props.user_props type_instance = get_type(type_name, user_props, *type_args) case props.mode when :field_def if fields[name].nil? fields[name] = ArrayProxy.new(@instance) end field = FieldReader.new(type_instance, @instance) fields[name].add_field(field) queue.enq(field) name_in_method = name @instance.singleton_class.instance_eval do define_method name do return fields[name_in_method] end end instance = @instance singleton_class.instance_eval do define_method name do instance.send(name_in_method) end end end end
fields(&field_def)
click to toggle source
# File lib/bitstream.rb, line 233 def fields(&field_def) @field_defs << field_def end
initialize_for_class_methods(types)
click to toggle source
# File lib/bitstream.rb, line 222 def initialize_for_class_methods(types) @field_defs = [] @fields = {} @types = types.dup @index = 0 @singleton_props = {} @class_props = {} @class_props_chain = [@class_props] @bitstream_mutex = Mutex.new end
initialize_instance(raw_data, instance)
click to toggle source
# File lib/bitstream.rb, line 237 def initialize_instance(raw_data, instance) props = instance.bitstream_properties props.mode = :field_def user_props = props.user_props @class_props_chain.each do |class_props| user_props.merge!(class_props) end user_props[:nest_chain] = user_props[:nest_chain] + [instance] @bitstream_mutex.synchronize do @instance = instance @field_defs.each do |field_def| field_def.call end end substream_types = @singleton_props[:substream_types] substreams = props.substreams unless substream_types.nil? substreams.keys.each do |id| # TODO: Support multi type substreams. substreams[id] = substream_types[0].instance.read(substreams[id]) end end end
instance(inherited_props, user_props = {})
click to toggle source
# File lib/bitstream.rb, line 486 def instance(inherited_props, user_props = {}) NestWrapper.new(self, inherited_props, user_props) end
method_missing(name, *args)
click to toggle source
Calls superclass method
# File lib/bitstream.rb, line 475 def method_missing(name, *args) field_name = args.shift aliasee = resolve_alias(name, args) args.unshift(field_name) if aliasee.nil? super name, *args else return send(aliasee, *args) end end
props()
click to toggle source
# File lib/bitstream.rb, line 291 def props @instance.bitstream_properties.user_props end
separate_substream(id)
click to toggle source
# File lib/bitstream.rb, line 441 def separate_substream(id) # TODO: Refactor here. top_stream = @instance.bitstream_properties.user_props[:nest_chain].first substreams = top_stream.bitstream_properties.substreams substreams[id] << LazyString.new end
substream(name, id, length)
click to toggle source
# File lib/bitstream.rb, line 420 def substream(name, id, length) name = name.intern props = @instance.bitstream_properties user_props = props.user_props raw_data = props.raw_data queue = props.eval_queue top_stream = @instance.bitstream_properties.user_props[:nest_chain].first substreams = top_stream.bitstream_properties.substreams case props.mode when :field_def type_instance = SubStreamPacket.instance(length) field = FieldReader.new(type_instance, @instance) queue.enq(field) field.read substreams[id] << LazyString.new if substreams[id].empty? substreams[id].last << field.value end end
substream_types(*types)
click to toggle source
# File lib/bitstream.rb, line 299 def substream_types(*types) @singleton_props[:substream_types] = types end
Private Instance Methods
get_type(type_name, props, *args)
click to toggle source
# File lib/bitstream.rb, line 506 def get_type(type_name, props, *args) type = @types[type_name.intern] if type.nil? aliasee = resolve_alias(type_name, args) if aliasee.nil? raise BitStreamError, "There is no type named \"#{type_name}\"" else type = @types[aliasee] end end return type.instance(props, *args) end
resolve_alias(type_name, args)
click to toggle source
# File lib/bitstream.rb, line 491 def resolve_alias(type_name, args) type_s = type_name.to_s if type_s =~ /^uint(\d+)$/ bit_width = Regexp.last_match[1].to_i args.unshift(bit_width) return :unsigned elsif type_s =~ /^int(\d+)$/ bit_width = Regexp.last_match[1].to_i args.unshift(bit_width) return :signed else return nil end end