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.

Author:

  • Sylvain Daubert (2016-2024)

  • LemonTree55

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:



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

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

#==(other) ⇒ Boolean

Check equality. Equality is checked on underlying array.

Returns:

  • (Boolean)


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

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:



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

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



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

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



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

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_copy(_other) ⇒ Object

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(_other)
  @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:



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

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)


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

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)


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

def sz
  to_s.size
end

#to_a::Array

Return underlying Ruby Array

Returns:

  • (::Array)


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

def to_a
  @array
end

#to_human::String

Get a human readable string

Returns:

  • (::String)


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

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

#to_s::String

Get binary string

Returns:

  • (::String)


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

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