class BinData::Array
- to any lambda evaluated as a parameter of that data object.
Each data object in an array has the variableindex
made available
as much data from the stream as possible.
is the symbol :eof, then the array will read
this parameter. If the value of this parameter
are made available to any lambda assigned to
The variablesindex
,element
andarray
read an array until a sentinel value is found.
condition is true. This is typically used to:read_until
- While reading, elements are read until this
:initial_length
- The initial length of the array.
[type_symbol, hash_params]
.
passed to it, then it should be provided as
array elements. If the type is to have params:type
-
The symbol representing the data type of the
an object. These params are:
Parameters may be provided at initialisation to control the behaviour of
== Parameters
obj.read(data) #=> [3, 4, 5, 6, 7, 8, 9]
obj = BinData::Array.new(type: :int8, read_until: :eof)
obj.read(data) #=> [3, 4, 5, 6, 7]
read_until: -> { array + array[index - 1] == 13 })
obj = BinData::Array.new(type: :int8,
obj.read(data) #=> [3, 4, 5, 6]
read_until: -> { element >= 6 })
obj = BinData::Array.new(type: :int8,
obj.read(data) #=> [3, 4]
read_until: -> { index == 1 })
obj = BinData::Array.new(type: :int8,
obj.read(data) #=> [3, 4, 5, 6, 7, 8]
obj = BinData::Array.new(type: :int8, initial_length: 6)
data = “x03x04x05x06x07x08x09”
require ‘bindata’
An Array is a list of data objects of the same type.
- The initial length of the array.
- While reading, elements are read until this
def [](arg1, arg2 = nil)
def [](arg1, arg2 = nil) if arg1.respond_to?(:to_int) && arg2.nil? slice_index(arg1.to_int) elsif arg1.respond_to?(:to_int) && arg2.respond_to?(:to_int) slice_start_length(arg1.to_int, arg2.to_int) elsif arg1.is_a?(Range) && arg2.nil? slice_range(arg1) else raise TypeError, "can't convert #{arg1} into Integer" unless arg1.respond_to?(:to_int) raise TypeError, "can't convert #{arg2} into Integer" unless arg2.respond_to?(:to_int) end end
def []=(index, value)
def []=(index, value) extend_array(index) elements[index].assign(value) end
def append_new_element
def append_new_element element = new_element elements << element element end
def assign(array)
def assign(array) return if self.equal?(array) # prevent self assignment raise ArgumentError, "can't set a nil value for #{debug_name}" if array.nil? @elements = [] concat(array) end
def at(index)
Returns the element at +index+. Unlike +slice+, if +index+ is out
def at(index) elements[index] end
def clear?
def clear? @elements.nil? || elements.all?(&:clear?) end
def concat(array)
def concat(array) insert(-1, *array.to_ary) self end
def debug_name_of(child) # :nodoc:
def debug_name_of(child) # :nodoc: index = find_index_of(child) "#{debug_name}[#{index}]" end
def do_num_bytes # :nodoc:
def do_num_bytes # :nodoc: sum_num_bytes_for_all_elements end
def do_write(io) # :nodoc:
def do_write(io) # :nodoc: elements.each { |el| el.do_write(io) } end
def each
def each elements.each { |el| yield el } end
def elements
def elements @elements ||= [] end
def empty?
def empty? length.zero? end
def extend_array(max_index)
def extend_array(max_index) max_length = max_index + 1 while elements.length < max_length append_new_element end end
def find_index(obj)
def find_index(obj) elements.index(obj) end
def find_index_of(obj)
Returns the first index of +obj+ in self.
def find_index_of(obj) elements.index { |el| el.equal?(obj) } end
def first(n = nil)
If the array is empty, the first form returns nil, and the second
Returns the first element, or the first +n+ elements, of the array.
def first(n = nil) if n.nil? && empty? # explicitly return nil as arrays grow automatically nil elsif n.nil? self[0] else self[0, n] end end
def initialize_instance
def initialize_instance @elements = nil end
def initialize_shared_instance
def initialize_shared_instance @element_prototype = get_parameter(:type) if get_parameter(:read_until) == :eof extend ReadUntilEOFPlugin elsif has_parameter?(:read_until) extend ReadUntilPlugin elsif has_parameter?(:initial_length) extend InitialLengthPlugin end super end
def insert(index, *objs)
def insert(index, *objs) extend_array(index - 1) abs_index = (index >= 0) ? index : index + 1 + length # insert elements before... new_elements = objs.map { new_element } elements.insert(index, *new_elements) # ...assigning values objs.each_with_index do |obj, i| self[abs_index + i] = obj end self end
def last(n = nil)
If the array is empty, the first form returns nil, and the second
Returns the last element, or the last +n+ elements, of the array.
def last(n = nil) if n.nil? self[-1] else n = length if n > length self[-n, n] end end
def length
def length elements.length end
def new_element
def new_element @element_prototype.instantiate(nil, self) end
def offset_of(child) # :nodoc:
def offset_of(child) # :nodoc: index = find_index_of(child) sum = sum_num_bytes_below_index(index) child.bit_aligned? ? sum.floor : sum.ceil end
def push(*args)
def push(*args) insert(-1, *args) self end
def slice_index(index)
def slice_index(index) extend_array(index) at(index) end
def slice_range(range)
def slice_range(range) elements[range] end
def slice_start_length(start, length)
def slice_start_length(start, length) elements[start, length] end
def snapshot
def snapshot elements.collect(&:snapshot) end
def sum_num_bytes_below_index(index)
def sum_num_bytes_below_index(index) (0...index).inject(0) do |sum, i| nbytes = elements[i].do_num_bytes if nbytes.is_a?(Integer) sum.ceil + nbytes else sum + nbytes end end end
def sum_num_bytes_for_all_elements
def sum_num_bytes_for_all_elements sum_num_bytes_below_index(length) end
def to_ary
def to_ary collect { |el| el } end
def unshift(*args)
def unshift(*args) insert(0, *args) self end