Class: Ruckus::Vector
Overview
A vector of count elements of the same class, as in
- elt0
- elt1
-
… [eltN]
Constant Summary
Constants inherited from Parsel
Instance Attribute Summary
Attributes inherited from Parsel
#name, #parent, #rendered_offset, #rendering, #tag, #value
Instance Method Summary collapse
- #capture(str) ⇒ Object
-
#initialize(opts = {}) ⇒ Vector
constructor
Options include: *
:class
the class of each element *:e_opts
opts to pass when creating each element (:name is always deleted) *:count
the number of elements of class :class in the vector. - #to_s(off = nil) ⇒ Object
Methods inherited from Parsel
bytes_for_bits, coerce, #each_matching_selector, endian?, factory?, #find_containing, #find_tag, #find_tag_struct, #fixup, #in, #incomplete!, #index_for_selectors, #inspect, #matches_selector?, #method_missing, #native?, native?, #next, #out, #parent_structure, #permute, #prev, #resolve, #respond_to?, #root, #size, #visit, #where_am_i?
Constructor Details
#initialize(opts = {}) ⇒ Vector
Options include:
-
:class
the class of each element -
:e_opts
opts to pass when creating each element (:name is always deleted) -
:count
the number of elements of class :class in the vector. Can be a reference to another field
via :from_field
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/ruckus/vector.rb', line 12 def initialize(opts={}) opts[:count] = 0x1fffffff if opts[:count] == :unlimited # grotesque hack XXX opts[:e_opts] ||= {} raise "need a class" if not opts[:class] and not opts[:classes_from] if opts[:classes_from] if not opts[:keys_from] raise "need a module to pull keys from (protocol numbers, command IDs, whatever) as :keys_from" end begin @keys = (m = opts[:keys_from]).constants. select {|x| m.const_get(x).kind_of? Numeric}. map {|x| [m.const_get(x), x]}. to_hash rescue => e raise "can't look up keys:\n #{ e }" end begin @classes = (m = opts[:classes_from]).constants. select {|x| m.const_get(x).kind_of? Class}. map do |x| name = (klass = m.const_get(x)). to_s. underscore. upcase name = name[name.rindex(":")+1..-1] [ name, klass ] end.to_hash rescue => e raise "can't generate class dictionary:\n #{ e }" end raise "need a :key_field or :key_finder" if not opts[:key_field] and not opts[:key_finder] end super(opts) @value = Blob.new @value.parent = self end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Ruckus::Parsel
Instance Method Details
#capture(str) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/ruckus/vector.rb', line 55 def capture(str) count = resolve(@count) if not count raise "You need to provide a :count value to parse a vector; did you give it :size by mistake?" end count.downto(1) do |i| break if not str or str.empty? if @class o = @class.new(@e_opts.merge(:parent => self)) str = o.capture(str) @value << o else if @key_field key = parent_struct.send(@key_field) end if @key_finder key = @key_finder.call(str) end begin o = @classes[@keys[key]].new(@e_opts.merge(:parent => self)) str = o.capture(str) @value << o rescue => e raise "couldn't create an object from key:\n#{ e }" end end end @count = @value.count str end |
#to_s(off = nil) ⇒ Object
90 91 92 93 |
# File 'lib/ruckus/vector.rb', line 90 def to_s(off=nil) @rendered_offset = off || 0 (@value)? @value.to_s(off) : "" end |