Class: BinStruct::Array Abstract

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
LengthFrom, Structable, Enumerable
Defined in:
lib/bin_struct/array.rb

Overview

This class is abstract.

Base class to define set of Structable subclasses.

This class mimics regular Ruby Array, but it is Structable and responds to LengthFrom.

Concrete subclasses may define 2 private methods:

#record_from_hash

This method is called by #push and #<< to add an object to the set.

A default method is defined by Array: it calls constructor of class defined by Array.set_of.

#real_type

Subclasses should define private method #real_type if Array.set_of type may be subclassed. This method should return real class to use. It takes an only argument, which is of type given by Array.set_of.

Default behaviour of this method is to return argument’s class.

Constant Summary collapse

HUMAN_SEPARATOR =

Separator used in #to_human. May be overriden by subclasses

','

Constants included from LengthFrom

LengthFrom::MAX_SZ_TO_READ

Class Method Summary collapse

Instance Method Summary collapse

Methods included from LengthFrom

#initialize_length_from, #read_with_length_from, #sz_to_read

Methods included from Structable

#format_inspect, #type_name

Constructor Details

#initialize(options = {}) ⇒ Array

Returns a new instance of Array.

Examples:

counter example

# Define a counter
counter = BinStruct::Int8.new
counter.to_i # => 0

# Define an array with associated counter
ary = BinStruct::ArrayOfInt8.new(counter: counter)
# Add 2 elements to arry, increment counter twice
ary.read([1, 2])
counter.to_i #=> 2
# Add a third element
ary << BinStruct::Int8.new(value: 42)
counter.to_i #=> 3

# push does not increment the counter
ary.push(BinStruct::Int8.new(value: 100))
counter.to_i #=> 3

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • counter (Int)

    Int object used as a counter for this set



107
108
109
110
111
# File 'lib/bin_struct/array.rb', line 107

def initialize(options = {})
  @counter = options[:counter]
  @array = []
  initialize_length_from(options)
end

Class Method Details

.set_of(klass) ⇒ void

This method returns an undefined value.

Define type of objects in set. Used by #read and #push.

Parameters:

  • klass (Class)


82
83
84
# File 'lib/bin_struct/array.rb', line 82

def set_of(klass)
  @klass = klass
end

.set_of_klassClass

Get class set with set_of.

Returns:

  • (Class)


75
76
77
# File 'lib/bin_struct/array.rb', line 75

def set_of_klass
  @klass
end

Instance Method Details

#<<(obj) ⇒ self

This method is abstract.

depend on private method #record_from_hash which should be declared by subclasses.

Add an object to this array, and increment associated counter, if any. If associated counter must not be incremented, use #push.

Parameters:

  • obj (Object)

    type depends on subclass

Returns:

  • (self)

See Also:



183
184
185
186
187
# File 'lib/bin_struct/array.rb', line 183

def <<(obj)
  push(obj)
  @counter&.from_human(@counter.to_i + 1)
  self
end

#==(other) ⇒ Boolean

Check equality. Equality is checked on underlying array.

Parameters:

  • other (Object)

Returns:

  • (Boolean)


123
124
125
126
127
128
129
130
# File 'lib/bin_struct/array.rb', line 123

def ==(other)
  @array == case other
            when Array
              other.to_a
            else
              other
            end
end

#[](index) ⇒ Object

Return the element at index.

Parameters:

  • index (Integer)

Returns:

  • (Object)


64
# File 'lib/bin_struct/array.rb', line 64

def_delegators :@array, :[], :clear, :each, :empty?, :first, :last, :size

#clearvoid

This method returns an undefined value.

Clear array.

See Also:



64
# File 'lib/bin_struct/array.rb', line 64

def_delegators :@array, :[], :clear, :each, :empty?, :first, :last, :size

#clear!void

This method returns an undefined value.

Clear array. Reset associated counter, if any.

See Also:



135
136
137
138
# File 'lib/bin_struct/array.rb', line 135

def clear!
  @array.clear
  @counter&.from_human(0)
end

#delete(obj) ⇒ Object

Delete an object from this array. Update associated counter if any

Parameters:

  • obj (Object)

Returns:

  • (Object)

    deleted object



143
144
145
146
147
# File 'lib/bin_struct/array.rb', line 143

def delete(obj)
  deleted = @array.delete(obj)
  @counter.from_human(@counter.to_i - 1) if @counter && deleted
  deleted
end

#delete_at(index) ⇒ Object?

Delete element at index. Update associated counter if any

Parameters:

  • index (Integer)

Returns:

  • (Object, nil)

    deleted object



152
153
154
155
156
# File 'lib/bin_struct/array.rb', line 152

def delete_at(index)
  deleted = @array.delete_at(index)
  @counter.from_human(@counter.to_i - 1) if @counter && deleted
  deleted
end

#each::Array, Enumerator

Calls the given block once for each element in self, passing that element as a parameter. Returns the array itself, or an enumerator if no block is given.

Returns:

  • (::Array, Enumerator)


64
# File 'lib/bin_struct/array.rb', line 64

def_delegators :@array, :[], :clear, :each, :empty?, :first, :last, :size

#empty?Boolean

Return true if contains no element.

Returns:

  • (Boolean)


64
# File 'lib/bin_struct/array.rb', line 64

def_delegators :@array, :[], :clear, :each, :empty?, :first, :last, :size

#firstObject

Return first element

Returns:

  • (Object)


64
# File 'lib/bin_struct/array.rb', line 64

def_delegators :@array, :[], :clear, :each, :empty?, :first, :last, :size

#initialize_copyObject

Note:

Associated counter, if any, is not duplicated

Initialize array for copy:

  • duplicate internal array.



116
117
118
# File 'lib/bin_struct/array.rb', line 116

def initialize_copy(*)
  @array = @array.dup
end

#lastObject

Return last element.

Returns:

  • (Object)


64
# File 'lib/bin_struct/array.rb', line 64

def_delegators :@array, :[], :clear, :each, :empty?, :first, :last, :size

#push(obj) ⇒ self

This method is abstract.

depend on private method #record_from_hash which should be declared by subclasses.

Add an object to this array. Do not update associated counter. If associated must be incremented, use #<<

Parameters:

  • obj (Object)

    type depends on subclass

Returns:

  • (self)

See Also:



165
166
167
168
169
170
171
172
173
174
# File 'lib/bin_struct/array.rb', line 165

def push(obj)
  obj = case obj
        when Hash
          record_from_hash(obj)
        else
          obj
        end
  @array << obj
  self
end

#read(data) ⇒ self

Populate object from a string or from an array of hashes

Parameters:

  • data (::String, ::Array<Hash>)

Returns:

  • (self)


192
193
194
195
196
197
198
199
200
201
# File 'lib/bin_struct/array.rb', line 192

def read(data)
  clear
  case data
  when ::Array
    read_from_array(data)
  else
    read_from_string(data)
  end
  self
end

#sizeInteger Also known as: length

Get number of element in array

Returns:

  • (Integer)


64
# File 'lib/bin_struct/array.rb', line 64

def_delegators :@array, :[], :clear, :each, :empty?, :first, :last, :size

#szInteger

Get size in bytes

Returns:

  • (Integer)


205
206
207
# File 'lib/bin_struct/array.rb', line 205

def sz
  to_s.size
end

#to_a::Array

Return underlying Ruby Array

Returns:

  • (::Array)


211
212
213
# File 'lib/bin_struct/array.rb', line 211

def to_a
  @array
end

#to_human::String

Get a human readable string

Returns:

  • (::String)


223
224
225
# File 'lib/bin_struct/array.rb', line 223

def to_human
  @array.map(&:to_human).join(self.class::HUMAN_SEPARATOR)
end

#to_s::String

Get binary string

Returns:

  • (::String)


217
218
219
# File 'lib/bin_struct/array.rb', line 217

def to_s
  @array.map(&:to_s).join
end