Class: BitStruct::Vector

Inherits:
String
  • Object
show all
Includes:
Enumerable
Defined in:
lib/bit-struct/vector.rb

Overview

A Vector is, like a BitStruct, a String. It retains all of the String methods, except for #[], #[]=, and #each. These methods operate on entries instead of chars. Other methods, including #length and #slice, are unchanged. Hence a Vector can be used directly with sockets, binary files, etc.

Note that Vector is not a subclass of BitStruct. It cannot be used in a #nest declaration in a BitStruct. Instead, use the #vector declaration. See BitStruct::VectorField.

Different instances of the same Vector class may have different lengths, and a single instance can change its length. The length should always be a multiple of the struct size.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(arg) {|_self| ... } ⇒ Vector

arg can be an integer (number of entries) or a string (binary data, such as another Vector of the same size).

Yields:

  • (_self)

Yield Parameters:



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/bit-struct/vector.rb', line 99

def initialize arg   # :yields: instance
  case arg
  when Integer
    super(struct_class.initial_value * arg)
  
  else
    begin
      super arg
    rescue NameError
      raise ArgumentError, "must be string or integer: #{arg.inspect}"
    end
  end 

  yield self if block_given?
end

Class Method Details

.default_options(h = nil) ⇒ Object

Get or set the hash of default options for the class, which apply to all fields in the entries. If h is provided, update the default options with that hash. Default options are inherited.

This is especially useful with the :endian => val option.



63
64
65
66
67
68
69
70
71
72
# File 'lib/bit-struct/vector.rb', line 63

def default_options h = nil
  @default_options ||= superclass.default_options.dup
  if h
    @default_options.merge! h
    if @struct_class
      @struct_class.default_options h
    end
  end
  @default_options
end

.describe(*args) ⇒ Object



74
75
76
77
78
79
80
81
82
# File 'lib/bit-struct/vector.rb', line 74

def describe(*args)
  fmt = args[0] || BitStruct.describe_format
  if block_given?
    struct_class.describe(*args){|desc| yield desc}
    yield ["..."]*5
  else
    struct_class.describe(*args) + [fmt % (["..."]*5)]
  end
end

.inherited(cl) ⇒ Object



20
21
22
23
24
# File 'lib/bit-struct/vector.rb', line 20

def inherited cl
  cl.instance_eval do
    @struct_class = nil
  end
end

.method_missing(*a, &block) ⇒ Object

:nodoc:



49
50
51
# File 'lib/bit-struct/vector.rb', line 49

def method_missing(*a, &block)  # :nodoc:
  struct_class.send(*a, &block)
end

.orig_respond_to?Object



53
# File 'lib/bit-struct/vector.rb', line 53

alias :orig_respond_to? :respond_to?

.respond_to?(*m) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


54
55
56
# File 'lib/bit-struct/vector.rb', line 54

def respond_to?(*m)  # :nodoc:
  orig_respond_to?(*m) || struct_class.respond_to?(*m)
end

.struct_class(cl = nil) ⇒ Object

Called as a class method with a single argument in a user-defined subclass to specify a particular BitStruct class to use for each entry, instead of generating an anonymous class. Called without arguments to access the struct class, generating an anonymous one if needed. The struct_class inherits from the struct_class of the parent Vector class.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/bit-struct/vector.rb', line 32

def struct_class cl = nil
  if cl
    if @struct_class
      warn "changing struct_class in #{self} to #{cl}"
    end
    @struct_class = cl
    @struct_class.default_options default_options
  else
    unless @struct_class
      @struct_class = self == BitStruct::Vector ? BitStruct : 
        Class.new(superclass.struct_class)
      @struct_class.default_options default_options
    end
  end
  @struct_class
end

Instance Method Details

#[](i) ⇒ Object

Get the i-th entry. Returns a copy of the entry. If you want to use this copy to modify the entry, you must modify the copy and then use #[]= to replace the entry with the copy.



118
119
120
121
122
123
124
125
126
127
# File 'lib/bit-struct/vector.rb', line 118

def [](i)
  sc = self.class.struct_class
  entry_length = sc.round_byte_length

  unless (0...(length / entry_length)).include? i
    raise ArgumentError, "index out of range: #{i}"
  end
  
  sc.new slice(entry_length * i, entry_length)
end

#[]=(i, val) ⇒ Object

Set the i-th entry to val.



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/bit-struct/vector.rb', line 132

def []=(i,val)
  entry_length = struct_class_length
  
  unless (0...(length / entry_length)).include? i
    raise ArgumentError, "index out of range: #{i}"
  end
  
  unless val.length == entry_length
    raise ArgumentError, "wrong entry length: #{val.length} != #{entry_length}"
  end
  
  _old_replace_substr(entry_length * i, entry_length, val)
end

#_old_replace_substrObject



129
# File 'lib/bit-struct/vector.rb', line 129

alias _old_replace_substr []=

#eachObject

Iterate over entries.



149
150
151
152
153
154
# File 'lib/bit-struct/vector.rb', line 149

def each
  entry_length = struct_class_length
  (length / entry_length).times do |i|
    yield self[i]
  end
end

#inspect(opts = BitStruct::DEFAULT_INSPECT_OPTS) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/bit-struct/vector.rb', line 156

def inspect(opts = BitStruct::DEFAULT_INSPECT_OPTS)
  if opts[:include_class]
    opts = opts.dup
    opts[:include_class] = false
    s = self.class.inspect + ": "
  else
    s = ""
  end
  
  s << entries.map{|entry| entry.inspect(opts)}.join(opts[:separator])
  lb, rb = opts[:brackets]
  [lb, s, rb].join
end

#inspect_detailedObject



170
171
172
# File 'lib/bit-struct/vector.rb', line 170

def inspect_detailed
  inspect(BitStruct::DETAILED_INSPECT_OPTS)
end

#struct_classObject

Convenience method for instances. Returns the BitStruct class that describes each entry.



87
88
89
# File 'lib/bit-struct/vector.rb', line 87

def struct_class
  self.class.struct_class
end

#struct_class_lengthObject

Convenience method for instances. Returns the string length in bytes of each entry in the vector.



93
94
95
# File 'lib/bit-struct/vector.rb', line 93

def struct_class_length
  self.class.struct_class.round_byte_length
end