bin_struct 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d5412a49a789a410de1120e6cbcbf55a7bd07783846a4e2f4cf9bc14eac76bfd
4
- data.tar.gz: 9ae9eabeb7c3fe672e8ba229bc116c9a72bf26c7b1fd9eace52bb0f8036f0fea
3
+ metadata.gz: df710325cf6aa4414fc997d77033b8bea34d4dc80e571ceb184462b2aa047eb3
4
+ data.tar.gz: aa372402e27bc5b254b7e4e82cb7d9b2178823c84adc3c1bda17bba7806ff05e
5
5
  SHA512:
6
- metadata.gz: 8fa11b03a84dca208c63d23358187b575982f5331d5c1da7fdd7c2343505ed932bc884a440b23589943d4eb5d9f78f942d77e8b271bef919277536a0ab9ab3b7
7
- data.tar.gz: ecd4e847f6dc8392b759b8ef7a23df05191c697bb471a1ef8c685e12009be544b2dac4f8d77a944190a607b26216d90bd034742c95f9b2034b2701c4ec726602
6
+ metadata.gz: 6ef8207d1fc62509bda66a0caa779ec2b6b95e2a7805fb10199423bcf1300a7f05dd5c5b595f33f8b6605b93277e485a5a18f80a83b7c6954339eea0541f6073
7
+ data.tar.gz: b47f00bd2497c5330eeb6a01721b3cbd4a305d624e6df7dce2fd13b8f996c61e287ab92df393ea0fcb67fece0396497354220e9a56cb50bf617fa0d9b3ccdaff
data/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
- ## [Unreleased]
1
+ # Changelog
2
2
 
3
- ## [0.1.0] - 2024-07-13
3
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
4
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
+
6
+ ## 0.2.1 - 2024-11-25
7
+
8
+ ### Added
9
+
10
+ - `CString` and `String` initializers now accepts `:value` option to set string initial value.
11
+
12
+ ### Changed
13
+
14
+ - `IntString` initializer option `:string` is renamed into `:value`.
15
+
16
+ ## 0.2.0 - 2024-07-21
17
+
18
+ ### Changed
19
+
20
+ - `BinStruct::Fields` renamed into `BinStruct::Struct`, and `*field*` methods are renamed into `*attr*` or `*attributes*`.
21
+ - `BinStruct::Struct#inspect`: add a title line.
22
+
23
+ ### Fixed
24
+
25
+ - Fix `BinStruct::ArrayOfInt#read_from_array` by using `value:` option.
26
+ - Fix `BinStruct::IntString#calc_length` by using `#from_human` instead of `#read`.
27
+ - `BinStruct::String#to_s`: force binary encoding.
28
+ - `BinStruct::String#<<`: force binary encoding on argument before catenating.
29
+
30
+ ## 0.1.0 - 2024-07-13
4
31
 
5
32
  - Initial release
data/README.md CHANGED
@@ -1,14 +1,20 @@
1
+ [![Gem Version](https://badge.fury.io/rb/bin_struct.svg)](https://badge.fury.io/rb/bin_struct)
2
+ [![Specs](https://github.com/lemontree55/bin_struct/actions/workflows/main.yml/badge.svg)](https://github.com/lemontree55/bin_struct/actions/workflows/main.yml)
3
+
1
4
  # BinStruct
2
5
 
3
- BinStruct provides a simple ways to create and dissect binary data. It is an extraction from [PacketGen](https://github.com/lemontree55/packetgen) fields.
6
+ BinStruct provides a simple way to create and dissect binary data. It is an extraction from [PacketGen](https://github.com/lemontree55/packetgen) 3.x Fields.
4
7
 
5
8
  ## Installation
6
9
 
7
10
  Installation using RubyGems is easy:
8
11
 
9
- $ gem install bin_struct
12
+ ```shell
13
+ gem install bin_struct
14
+ ```
10
15
 
11
16
  Or add it to a Gemfile:
17
+
12
18
  ```ruby
13
19
  gem 'bin_struct'
14
20
  ```
@@ -2,28 +2,28 @@
2
2
 
3
3
  # This file is part of BinStruct
4
4
  # See https://github.com/lemontree55/bin_struct for more informations
5
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
5
6
  # Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
6
7
  # This program is published under MIT license.
7
8
 
9
+ # BinStruct module
10
+ # @author LemonTree55
8
11
  module BinStruct
9
- # This class is an abstract class to define type-length-value data.
10
- #
11
- # This class supersedes {TLV} class, which is not well defined on some corner
12
- # cases.
12
+ # @abstract Base class to define type-length-value data.
13
13
  #
14
14
  # ===Usage
15
15
  # To simply define a new TLV class, do:
16
16
  # MyTLV = PacketGen::Types::AbstractTLV.create
17
17
  # MyTLV.define_type_enum 'one' => 1, 'two' => 2
18
- # This will define a new +MyTLV+ class, subclass of {Fields}. This class will
19
- # define 3 fields:
18
+ # This will define a new +MyTLV+ class, subclass of {AbstractTLV}. This class will
19
+ # define 3 attributes:
20
20
  # * +#type+, as a {Int8Enum} by default,
21
21
  # * +#length+, as a {Int8} by default,
22
22
  # * and +#value+, as a {String} by default.
23
23
  # +.define_type_enum+ is, here, necessary to define enum hash to be used
24
24
  # for +#type+ accessor, as this one is defined as an {Enum}.
25
25
  #
26
- # This class may then be used as older {TLV} class:
26
+ # This new defined class may now be easily used:
27
27
  # tlv = MyTLV.new(type: 1, value: 'abcd') # automagically set #length from value
28
28
  # tlv.type #=> 1
29
29
  # tlv.human_type #=> 'one'
@@ -31,7 +31,7 @@ module BinStruct
31
31
  # tlv.value #=> "abcd"
32
32
  #
33
33
  # ===Advanced usage
34
- # Each field's type may be changed at generating TLV class:
34
+ # Each attribute's type may be changed at generating TLV class:
35
35
  # MyTLV = PacketGen::Types::AbstractTLV.create(type_class: PacketGen::Types::Int16,
36
36
  # length_class: PacketGen::Types::Int16,
37
37
  # value_class: PacketGen::Header::IP::Addr)
@@ -42,7 +42,7 @@ module BinStruct
42
42
  # tlv.to_s #=> "\x00\x01\x00\x04\x01\x02\x03\x04"
43
43
  #
44
44
  # Some aliases may also be defined. For example, to create a TLV type
45
- # whose +type+ field should be named +code+:
45
+ # whose +type+ attribute should be named +code+:
46
46
  # MyTLV = PacketGen::Types::AbstractTLV.create(type_class: PacketGen::Types::Int16,
47
47
  # length_class: PacketGen::Types::Int16,
48
48
  # aliases: { code: :type })
@@ -52,20 +52,20 @@ module BinStruct
52
52
  # tlv.length #=> 4
53
53
  # tlv.value #=> 'abcd'
54
54
  #
55
- # @author Sylvain Daubert
56
- # @since 3.1.0
57
- # @since 3.1.1 add +:aliases+ keyword to {#initialize}
58
- class AbstractTLV < Fields
59
- include Fieldable
55
+ # @author Sylvain Daubert (2016-2024)
56
+ # @author LemonTree55
57
+ class AbstractTLV < Struct
58
+ include Structable
60
59
 
61
60
  # @private
62
- FIELD_TYPES = { 'T' => :type, 'L' => :length, 'V' => :value }.freeze
61
+ ATTR_TYPES = { 'T' => :type, 'L' => :length, 'V' => :value }.freeze
63
62
 
64
63
  class << self
64
+ # Aliases defined in {.create}
65
65
  # @return [Hash]
66
66
  attr_accessor :aliases
67
67
  # @private
68
- attr_accessor :field_in_length
68
+ attr_accessor :attr_in_length
69
69
 
70
70
  # rubocop:disable Metrics/ParameterLists
71
71
 
@@ -73,14 +73,12 @@ module BinStruct
73
73
  # @param [Class] type_class Class to use for +type+
74
74
  # @param [Class] length_class Class to use for +length+
75
75
  # @param [Class] value_class Class to use for +value+
76
- # @param [String] field_order give field order. Each character in [T,L,V] MUST be present once,
76
+ # @param [::String] attr_order gives attribute order. Each character in [T,L,V] MUST be present once,
77
77
  # in the desired order.
78
- # @param [String] field_in_length give fields to compute length on.
78
+ # @param [::String] attr_in_length give attributes to compute length on.
79
79
  # @return [Class]
80
- # @since 3.1.4 Add +header_in_length+ parameter
81
- # @since 3.3.1 Add +field_order+ and +field_in_length' parameters. Deprecate +header_in_length+ parameter.
82
80
  def create(type_class: Int8Enum, length_class: Int8, value_class: String,
83
- aliases: {}, field_order: 'TLV', field_in_length: 'V')
81
+ aliases: {}, attr_order: 'TLV', attr_in_length: 'V')
84
82
  unless equal?(AbstractTLV)
85
83
  raise Error,
86
84
  '.create cannot be called on a subclass of PacketGen::Types::AbstractTLV'
@@ -88,11 +86,11 @@ module BinStruct
88
86
 
89
87
  klass = Class.new(self)
90
88
  klass.aliases = aliases
91
- klass.field_in_length = field_in_length
89
+ klass.attr_in_length = attr_in_length
92
90
 
93
- check_field_in_length(field_in_length)
94
- check_field_order(field_order)
95
- generate_fields(klass, field_order, type_class, length_class, value_class)
91
+ check_attr_in_length(attr_in_length)
92
+ check_attr_order(attr_order)
93
+ generate_attributes(klass, attr_order, type_class, length_class, value_class)
96
94
 
97
95
  aliases.each do |al, orig|
98
96
  klass.instance_eval do
@@ -106,87 +104,93 @@ module BinStruct
106
104
  # rubocop:enable Metrics/ParameterLists
107
105
 
108
106
  # @!attribute type
109
- # @abstract Type attribute for real TLV class
107
+ # @abstract
108
+ # Type attribute for real TLV class
110
109
  # @return [Integer]
111
110
  # @!attribute length
112
- # @abstract Length attribute for real TLV class
111
+ # @abstract
112
+ # Length attribute for real TLV class
113
113
  # @return [Integer]
114
114
  # @!attribute value
115
- # @abstract Value attribute for real TLV class
115
+ # @abstract
116
+ # Value attribute for real TLV class
116
117
  # @return [Object]
117
118
 
118
119
  # @abstract Should only be called on real TLV classes, created by {.create}.
119
- # Set enum hash for {#type} field.
120
- # @param [Hash{String, Symbol => Integer}] hsh enum hash
120
+ # Set enum hash for {#type} attribute.
121
+ # @param [Hash{::String, Symbol => Integer}] hsh enum hash
121
122
  # @return [void]
122
123
  def define_type_enum(hsh)
123
- field_defs[:type][:options][:enum].clear
124
- field_defs[:type][:options][:enum].merge!(hsh)
124
+ attr_defs[:type][:options][:enum].clear
125
+ attr_defs[:type][:options][:enum].merge!(hsh)
125
126
  end
126
127
 
127
128
  # @abstract Should only be called on real TLV classes, created by {.create}.
128
- # Set default value for {#type} field.
129
- # @param [Integer,String,Symbol,nil] default default value from +hsh+ for type
129
+ # Set default value for {#type} attribute.
130
+ # @param [Integer,::String,Symbol,nil] default default value from +hsh+ for type
130
131
  # @return [void]
131
- # @since 3.4.0
132
132
  def define_type_default(default)
133
- field_defs[:type][:default] = default
133
+ attr_defs[:type][:default] = default
134
134
  end
135
135
 
136
136
  private
137
137
 
138
- def check_field_in_length(field_in_length)
139
- return if /^[TLV]{1,3}$/.match?(field_in_length)
138
+ def check_attr_in_length(attr_in_length)
139
+ return if /^[TLV]{1,3}$/.match?(attr_in_length)
140
140
 
141
- raise 'field_in_length must only contain T, L and/or V characters'
141
+ raise 'attr_in_length must only contain T, L and/or V characters'
142
142
  end
143
143
 
144
- def check_field_order(field_order)
145
- if field_order.match(/^[TLV]{3,3}$/) &&
146
- (field_order[0] != field_order[1]) &&
147
- (field_order[0] != field_order[2]) &&
148
- (field_order[1] != field_order[2])
144
+ def check_attr_order(attr_order)
145
+ if attr_order.match(/^[TLV]{3,3}$/) &&
146
+ (attr_order[0] != attr_order[1]) &&
147
+ (attr_order[0] != attr_order[2]) &&
148
+ (attr_order[1] != attr_order[2])
149
149
  return
150
150
  end
151
151
 
152
- raise 'field_order must contain all three letters TLV, each once'
152
+ raise 'attr_order must contain all three letters TLV, each once'
153
153
  end
154
154
 
155
- def generate_fields(klass, field_order, type_class, length_class, value_class)
156
- field_order.each_char do |field_type|
157
- case field_type
155
+ def generate_attributes(klass, attr_order, type_class, length_class, value_class)
156
+ attr_order.each_char do |attr_type|
157
+ case attr_type
158
158
  when 'T'
159
159
  if type_class < Enum
160
- klass.define_field(:type, type_class, enum: {})
160
+ klass.define_attr(:type, type_class, enum: {})
161
161
  else
162
- klass.define_field(:type, type_class)
162
+ klass.define_attr(:type, type_class)
163
163
  end
164
164
  when 'L'
165
- klass.define_field(:length, length_class)
165
+ klass.define_attr(:length, length_class)
166
166
  when 'V'
167
- klass.define_field(:value, value_class)
167
+ klass.define_attr(:value, value_class)
168
168
  end
169
169
  end
170
170
  end
171
171
  end
172
172
 
173
173
  # @!attribute type
174
- # @abstract Type attribute
174
+ # @abstract
175
+ # Type attribute
175
176
  # @return [Integer]
176
177
  # @!attribute length
177
- # @abstract Length
178
+ # @abstract
179
+ # Length attribute
178
180
  # @return [Integer]
179
181
  # @!attribute value
180
- # @abstract Value attribute
182
+ # @abstract
183
+ # Value attribute
181
184
  # @return [Object]enum
182
185
 
183
186
  # @abstract Should only be called on real TLV classes, created by {.create}.
187
+ # Return a new instance of a real TLV class.
184
188
  # @param [Hash] options
185
189
  # @option options [Integer] :type
186
190
  # @option options [Integer] :length
187
191
  # @option options [Object] :value
188
192
  def initialize(options = {})
189
- @field_in_length = self.class.field_in_length
193
+ @attr_in_length = self.class.attr_in_length
190
194
  self.class.aliases.each do |al, orig|
191
195
  options[orig] = options[al] if options.key?(al)
192
196
  end
@@ -199,17 +203,17 @@ module BinStruct
199
203
 
200
204
  # @abstract Should only be called on real TLV class instances.
201
205
  # Populate object from a binary string
202
- # @param [String,nil] str
203
- # @return [Fields] self
206
+ # @param [::String,nil] str
207
+ # @return [AbstractTLV] self
204
208
  def read(str)
205
209
  return self if str.nil?
206
210
 
207
211
  idx = 0
208
- fields.each do |field_name|
209
- field = self[field_name]
210
- length = field_name == :value ? real_length : field.sz
211
- field.read(str[idx, length])
212
- idx += field.sz
212
+ attributes.each do |attr_name|
213
+ attr = self[attr_name]
214
+ length = attr_name == :value ? real_length : attr.sz
215
+ attr.read(str[idx, length])
216
+ idx += attr.sz
213
217
  end
214
218
 
215
219
  self
@@ -219,7 +223,6 @@ module BinStruct
219
223
  # Set +value+. May set +length+ if value is a {Types::String}.
220
224
  # @param [Object] val
221
225
  # @return [Object]
222
- # @since 3.4.0 Base on field's +#from_human+ method
223
226
  def value=(val)
224
227
  if val.is_a?(self[:value].class)
225
228
  self[:value] = val
@@ -233,27 +236,26 @@ module BinStruct
233
236
 
234
237
  # @abstract Should only be called on real TLV class instances.
235
238
  # Get human-readable type
236
- # @return [String]
239
+ # @return [::String]
237
240
  def human_type
238
241
  self[:type].to_human.to_s
239
242
  end
240
243
 
241
244
  # @abstract Should only be called on real TLV class instances.
242
- # @return [String]
245
+ # @return [::String]
243
246
  def to_human
244
247
  my_value = self[:value].is_a?(String) ? self[:value].inspect : self[:value].to_human
245
248
  'type:%s,length:%u,value:%s' % [human_type, length, my_value]
246
249
  end
247
250
 
248
251
  # Calculate length
249
- # @return [void]
250
- # @since 3.4.0
252
+ # @return [Integer]
251
253
  def calc_length
252
- fil = @field_in_length
254
+ ail = @attr_in_length
253
255
 
254
256
  length = 0
255
- fil.each_char do |field_type|
256
- length += self[FIELD_TYPES[field_type]].sz
257
+ ail.each_char do |attr_type|
258
+ length += self[ATTR_TYPES[attr_type]].sz
257
259
  end
258
260
  self.length = length
259
261
  end
@@ -262,8 +264,8 @@ module BinStruct
262
264
 
263
265
  def real_length
264
266
  length = self.length
265
- length -= self[:type].sz if @field_in_length.include?('T')
266
- length -= self[:length].sz if @field_in_length.include?('L')
267
+ length -= self[:type].sz if @attr_in_length.include?('T')
268
+ length -= self[:length].sz if @attr_in_length.include?('L')
267
269
  length
268
270
  end
269
271
  end
@@ -9,10 +9,15 @@
9
9
  require 'forwardable'
10
10
 
11
11
  module BinStruct
12
- # @abstract Base class to define set of {Fields} subclasses.
12
+ # @abstract Base class to define set of {Struct} subclasses.
13
+ #
14
+ # This class mimics regular Ruby Array, but it is {Structable} and responds to {LengthFrom}.
15
+ #
16
+ # Concrete subclasses may define 2 private methods:
17
+ #
13
18
  # == #record_from_hash
14
- # Subclasses should define private method +#record_from_hash+. This method
15
- # is called by {#push} to add an object to the set.
19
+ # This method
20
+ # is called by {#push} and {#<<} to add an object to the set.
16
21
  #
17
22
  # A default method is defined by {Array}: it calls constructor of class defined
18
23
  # by {.set_of}.
@@ -24,16 +29,17 @@ module BinStruct
24
29
  #
25
30
  # Default behaviour of this method is to return argument's class.
26
31
  #
27
- # @author Sylvain Daubert
32
+ # @author Sylvain Daubert (2016-2024)
33
+ # @author LemonTree55
28
34
  class Array
29
35
  extend Forwardable
30
36
  include Enumerable
31
- include Fieldable
37
+ include Structable
32
38
  include LengthFrom
33
39
 
34
40
  # @!method [](index)
35
41
  # Return the element at +index+.
36
- # @param [integer] index
42
+ # @param [Integer] index
37
43
  # @return [Object]
38
44
  # @!method clear
39
45
  # Clear array.
@@ -41,10 +47,10 @@ module BinStruct
41
47
  # @!method each
42
48
  # Calls the given block once for each element in self, passing that
43
49
  # element as a parameter. Returns the array itself.
44
- # @return [Array]
50
+ # @return [::Array]
45
51
  # @method empty?
46
52
  # Return +true+ if contains no element.
47
- # @return [Booelan]
53
+ # @return [Boolean]
48
54
  # @!method first
49
55
  # Return first element
50
56
  # @return [Object]
@@ -58,14 +64,13 @@ module BinStruct
58
64
  alias length size
59
65
 
60
66
  # Separator used in {#to_human}.
61
- # May be ovverriden by subclasses
67
+ # May be overriden by subclasses
62
68
  HUMAN_SEPARATOR = ','
63
69
 
64
70
  # rubocop:disable Naming/AccessorMethodName
65
71
  class << self
66
72
  # Get class set with {.set_of}.
67
73
  # @return [Class]
68
- # @since 3.0.0
69
74
  def set_of_klass
70
75
  @klass
71
76
  end
@@ -89,10 +94,13 @@ module BinStruct
89
94
 
90
95
  # Initialize array for copy:
91
96
  # * duplicate internal array.
97
+ # @note Associated counter, if any, is not duplicated
92
98
  def initialize_copy(_other)
93
99
  @array = @array.dup
94
100
  end
95
101
 
102
+ # Check equality. Equality is checked on underlying array.
103
+ # @return [Boolean]
96
104
  def ==(other)
97
105
  @array == case other
98
106
  when Array
@@ -118,7 +126,7 @@ module BinStruct
118
126
  deleted
119
127
  end
120
128
 
121
- # Delete element at +index+.
129
+ # Delete element at +index+. Update associated counter if any
122
130
  # @param [Integer] index
123
131
  # @return [Object,nil] deleted object
124
132
  def delete_at(index)
@@ -129,13 +137,14 @@ module BinStruct
129
137
 
130
138
  # @abstract depend on private method +#record_from_hash+ which should be
131
139
  # declared by subclasses.
132
- # Add an object to this array
140
+ # Add an object to this array. Do not update associated counter.
133
141
  # @param [Object] obj type depends on subclass
134
- # @return [Array] self
142
+ # @return [self]
143
+ # @see #<<
135
144
  def push(obj)
136
145
  obj = case obj
137
146
  when Hash
138
- record_from_hash obj
147
+ record_from_hash(obj)
139
148
  else
140
149
  obj
141
150
  end
@@ -147,15 +156,15 @@ module BinStruct
147
156
  # declared by subclasses.
148
157
  # Add an object to this array, and increment associated counter, if any
149
158
  # @param [Object] obj type depends on subclass
150
- # @return [Array] self
159
+ # @return [self]
151
160
  def <<(obj)
152
- push obj
161
+ push(obj)
153
162
  @counter&.from_human(@counter.to_i + 1)
154
163
  self
155
164
  end
156
165
 
157
166
  # Populate object from a string or from an array of hashes
158
- # @param [String, Array<Hash>] data
167
+ # @param [::String, ::Array<Hash>] data
159
168
  # @return [self]
160
169
  def read(data)
161
170
  clear
@@ -174,20 +183,20 @@ module BinStruct
174
183
  to_s.size
175
184
  end
176
185
 
177
- # Return an Array
186
+ # Return underlying Ruby Array
178
187
  # @return [::Array]
179
188
  def to_a
180
189
  @array
181
190
  end
182
191
 
183
192
  # Get binary string
184
- # @return [String]
193
+ # @return [::String]
185
194
  def to_s
186
195
  @array.map(&:to_s).join
187
196
  end
188
197
 
189
198
  # Get a human readable string
190
- # @return [String]
199
+ # @return [::String]
191
200
  def to_human
192
201
  @array.map(&:to_human).join(self.class::HUMAN_SEPARATOR)
193
202
  end
@@ -251,36 +260,36 @@ module BinStruct
251
260
  return self if ary.empty?
252
261
 
253
262
  ary.each do |i|
254
- self << self.class.set_of_klass.new(i)
263
+ self << self.class.set_of_klass.new(value: i)
255
264
  end
256
265
  end
257
266
  end
258
267
 
259
- # Specialized array to handle serie of {Int8}.
268
+ # Specialized {Array} to handle serie of {Int8}.
260
269
  class ArrayOfInt8 < Array
261
270
  include ArrayOfIntMixin
262
271
  set_of Int8
263
272
  end
264
273
 
265
- # Specialized array to handle serie of {Int16}.
274
+ # Specialized {Array} to handle serie of {Int16}.
266
275
  class ArrayOfInt16 < Array
267
276
  include ArrayOfIntMixin
268
277
  set_of Int16
269
278
  end
270
279
 
271
- # Specialized array to handle serie of {Int16le}.
280
+ # Specialized {Array} to handle serie of {Int16le}.
272
281
  class ArrayOfInt16le < Array
273
282
  include ArrayOfIntMixin
274
283
  set_of Int16le
275
284
  end
276
285
 
277
- # Specialized array to handle serie of {Int32}.
286
+ # Specialized {Array} to handle serie of {Int32}.
278
287
  class ArrayOfInt32 < BinStruct::Array
279
288
  include ArrayOfIntMixin
280
289
  set_of Int32
281
290
  end
282
291
 
283
- # Specialized array to handle serie of {Int32le}.
292
+ # Specialized {Array} to handle serie of {Int32le}.
284
293
  class ArrayOfInt32le < BinStruct::Array
285
294
  include ArrayOfIntMixin
286
295
  set_of Int32le