bin_struct 0.3.0 → 0.4.0
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 +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +83 -0
- data/lib/bin_struct/abstract_tlv.rb +63 -9
- data/lib/bin_struct/array.rb +10 -5
- data/lib/bin_struct/bit_attr.rb +6 -4
- data/lib/bin_struct/cstring.rb +2 -2
- data/lib/bin_struct/enum.rb +11 -10
- data/lib/bin_struct/int.rb +1 -1
- data/lib/bin_struct/int_string.rb +7 -0
- data/lib/bin_struct/string.rb +3 -3
- data/lib/bin_struct/struct.rb +10 -1
- data/lib/bin_struct/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aeb290e624ce4004c20cfaf40fc60ae43938c80eab8fd1df1e8aa908a75e26cf
|
4
|
+
data.tar.gz: 8cb5dd0abdce7421b8269a4d35c14886f57cc6440a50c924b0937e5b30fe20ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecf6acc2f5c406556598212d22ad6257d22ed646c1128a145cff1730dc537bb7acfd40903f211aad28b11fa30c11324a98b98ecebb70ad7b84ea991bcf181f25
|
7
|
+
data.tar.gz: 1dcfbb20a54f7c08d2794e0e8391b70c633d65f6ccbc41c372e46c77da6fb036fbfa9d1548462030b86603e3e41b132019da70b3c2d603f7f21116bdc842ec14
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,17 @@
|
|
3
3
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
4
4
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
5
5
|
|
6
|
+
## 0.4.0 - 2025-02-13
|
7
|
+
|
8
|
+
### Added
|
9
|
+
|
10
|
+
- Add `Struct#attribute?` to check existence of an attribute.
|
11
|
+
- Add `AbstractTLV.derive` to derive a new subclass from a concrete TLV class.
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
|
15
|
+
- Update and fix Yard documentation.
|
16
|
+
|
6
17
|
## 0.3.0 - 2024-12-02
|
7
18
|
|
8
19
|
### Added
|
data/README.md
CHANGED
@@ -19,6 +19,89 @@ Or add it to a Gemfile:
|
|
19
19
|
gem 'bin_struct'
|
20
20
|
```
|
21
21
|
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
### Create a struct
|
25
|
+
|
26
|
+
To create a BinStruct, create a new class inheriting from `BinStruct::Struct`. Then, defines struct attributes using `.define_attr`. `.define_bit_attr` may also be used to define bit field attributes.
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'bin_struct'
|
30
|
+
|
31
|
+
class IPHeader < BinStruct::Struct
|
32
|
+
# Define a bir field, defaulting to 0x45, and splitted in 2 sub-fields: version and ihl,
|
33
|
+
# 4-bit size each
|
34
|
+
define_bit_attr :u8, default: 0x45, version: 4, ihl: 4
|
35
|
+
# Define a 8-bit unsigned integer named tos
|
36
|
+
# 1st argument: a symbol to define attribute name
|
37
|
+
# 2nd argument: a class to define attribute type. May be a type provided by BinStruct,
|
38
|
+
# or a user-defined class inheriting from one of these classes
|
39
|
+
# others arguments: options. Here, :default defines a default value for the attribute.
|
40
|
+
define_attr :tos, BinStruct::Int8, default: 0
|
41
|
+
# Define a 16-bit unsigned integer named length. Default to 20.
|
42
|
+
define_attr :length, BinStruct::Int16, default: 20
|
43
|
+
# Define a 16-bir unsigned integer named id. It is initialized with a random number
|
44
|
+
define_attr :id, BinStruct::Int16, default: ->(_) { rand(65_535) }
|
45
|
+
# Define a bit field composed of 4 subfields of 1, 1, 1 and 13 bit, respectively
|
46
|
+
define_bit_attr :frag, flag_rsv: 1, flag_df: 1, flag_mf: 1, fragment_offset: 13
|
47
|
+
# Define TTL field, a 8-bit unsigned integer, default to 64
|
48
|
+
define_attr :ttl, BinStruct::Int8, default: 64
|
49
|
+
# Define protocol field (8-bit unsigned integer)
|
50
|
+
define_attr :protocol, BinStruct::Int8
|
51
|
+
# Define checksum field (16-bit unsigned integer), default to 0
|
52
|
+
define_attr :checksum, BinStruct::Int16, default: 0
|
53
|
+
# Source and destination addresses, defined as array of 4 8-bit unsigned integers
|
54
|
+
define_attr :src, BinStruct::ArrayOfInt8, length_from: -> { 4 }
|
55
|
+
define_attr :dst, BinStruct::ArrayOfInt8, length_from: -> { 4 }
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
### Parse a binary string
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
# Initialize struct from a binary string
|
63
|
+
ip = IPHeader.new.read("\x45\x00\x00\x14\x43\x21\x00\x00\x40\x01\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01".b)
|
64
|
+
|
65
|
+
# Access some fields
|
66
|
+
p ip.version #=> 4
|
67
|
+
p ip.ihl #=> 5
|
68
|
+
p ip.id.to_s(16) #=> "4321"
|
69
|
+
p ip.protocol #=> 1
|
70
|
+
p ip.src.map { |byte| byte.to_i }.join('.') #=> "127.0.0.1"
|
71
|
+
```
|
72
|
+
|
73
|
+
```text
|
74
|
+
> p IPHeader.new.read("\x45\x00\x00\x14\x43\x21\x00\x00\x40\x01\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01")
|
75
|
+
-- IPHeader -----------------------------------------------------------
|
76
|
+
BitAttr8 u8: 69 (0x45)
|
77
|
+
version:4 ihl:5
|
78
|
+
Int8 tos: 0 (0x00)
|
79
|
+
Int16 length: 20 (0x0014)
|
80
|
+
Int16 id: 17185 (0x4321)
|
81
|
+
BitAttr16 frag: 0 (0x0000)
|
82
|
+
flag_rsv:0 flag_df:0 flag_mf:0 fragment_offset:0
|
83
|
+
Int8 ttl: 64 (0x40)
|
84
|
+
Int8 protocol: 1 (0x01)
|
85
|
+
Int16 checksum: 0 (0x0000)
|
86
|
+
ArrayOfInt8 src: 127,0,0,1
|
87
|
+
ArrayOfInt8 dst: 127,0,0,1
|
88
|
+
|
89
|
+
```
|
90
|
+
|
91
|
+
### Generate a binary string
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
# Create a new struct with some fields initialized
|
95
|
+
ip = IPHeader.new(tos: 42, id: 0x1234)
|
96
|
+
|
97
|
+
# Initialize fields after creation
|
98
|
+
ip.src = [192, 168, 1, 1]
|
99
|
+
ip.dst = [192, 168, 1, 2]
|
100
|
+
|
101
|
+
# Generate binary string
|
102
|
+
ip.to_s
|
103
|
+
```
|
104
|
+
|
22
105
|
## License
|
23
106
|
|
24
107
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -13,7 +13,7 @@ module BinStruct
|
|
13
13
|
#
|
14
14
|
# ===Usage
|
15
15
|
# To simply define a new TLV class, do:
|
16
|
-
# MyTLV =
|
16
|
+
# MyTLV = BinStruct::AbstractTLV.create
|
17
17
|
# MyTLV.define_type_enum 'one' => 1, 'two' => 2
|
18
18
|
# This will define a new +MyTLV+ class, subclass of {AbstractTLV}. This class will
|
19
19
|
# define 3 attributes:
|
@@ -32,9 +32,9 @@ module BinStruct
|
|
32
32
|
#
|
33
33
|
# ===Advanced usage
|
34
34
|
# Each attribute's type may be changed at generating TLV class:
|
35
|
-
# MyTLV =
|
36
|
-
#
|
37
|
-
#
|
35
|
+
# MyTLV = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16,
|
36
|
+
# length_class: BinStruct::Int16,
|
37
|
+
# value_class: PacketGen::Header::IP::Addr)
|
38
38
|
# tlv = MyTLV.new(type: 1, value: '1.2.3.4')
|
39
39
|
# tlv.type #=> 1
|
40
40
|
# tlv.length #=> 4
|
@@ -43,9 +43,9 @@ module BinStruct
|
|
43
43
|
#
|
44
44
|
# Some aliases may also be defined. For example, to create a TLV type
|
45
45
|
# whose +type+ attribute should be named +code+:
|
46
|
-
# MyTLV =
|
47
|
-
#
|
48
|
-
#
|
46
|
+
# MyTLV = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16,
|
47
|
+
# length_class: BinStruct::Int16,
|
48
|
+
# aliases: { code: :type })
|
49
49
|
# tlv = MyTLV.new(code: 1, value: 'abcd')
|
50
50
|
# tlv.code #=> 1
|
51
51
|
# tlv.type #=> 1
|
@@ -77,11 +77,12 @@ module BinStruct
|
|
77
77
|
# in the desired order.
|
78
78
|
# @param [::String] attr_in_length give attributes to compute length on.
|
79
79
|
# @return [Class]
|
80
|
+
# @raise [Error] Called on {AbstractTLV} subclass
|
80
81
|
def create(type_class: Int8Enum, length_class: Int8, value_class: String,
|
81
82
|
aliases: {}, attr_order: 'TLV', attr_in_length: 'V')
|
82
83
|
unless equal?(AbstractTLV)
|
83
84
|
raise Error,
|
84
|
-
'.create cannot be called on a subclass of
|
85
|
+
'.create cannot be called on a subclass of BinStruct::AbstractTLV'
|
85
86
|
end
|
86
87
|
|
87
88
|
klass = Class.new(self)
|
@@ -91,7 +92,7 @@ module BinStruct
|
|
91
92
|
check_attr_in_length(attr_in_length)
|
92
93
|
check_attr_order(attr_order)
|
93
94
|
generate_attributes(klass, attr_order, type_class, length_class, value_class)
|
94
|
-
|
95
|
+
generate_aliases_for(klass, aliases)
|
95
96
|
aliases.each do |al, orig|
|
96
97
|
klass.instance_eval do
|
97
98
|
alias_method al, orig if klass.method_defined?(orig)
|
@@ -103,6 +104,50 @@ module BinStruct
|
|
103
104
|
end
|
104
105
|
# rubocop:enable Metrics/ParameterLists
|
105
106
|
|
107
|
+
# On inheritage, copy aliases and attr_in_length
|
108
|
+
# @param [Class] klass inheriting class
|
109
|
+
# @return [void]
|
110
|
+
# @since 0.4.0
|
111
|
+
# @author LemonTree55
|
112
|
+
def inherited(klass)
|
113
|
+
super
|
114
|
+
|
115
|
+
aliases = @aliases.clone
|
116
|
+
attr_in_length = @attr_in_length.clone
|
117
|
+
|
118
|
+
klass.class_eval do
|
119
|
+
@aliases = aliases
|
120
|
+
@attr_in_length = attr_in_length
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Derive a new TLV class from an existing one
|
125
|
+
# @param [Class,nil] type_class New class to use for +type+. Unchanged if +nil+.
|
126
|
+
# @param [Class,nil] length_class New class to use for +length+. Unchanged if +nil+.
|
127
|
+
# @param [Class,nil] value_class New class to use for +value+. Unchanged if +nil+.
|
128
|
+
# @return [Class]
|
129
|
+
# @raise [Error] Called on {AbstractTLV} class
|
130
|
+
# @since 0.4.0
|
131
|
+
# @author LemonTree55
|
132
|
+
# @example
|
133
|
+
# # TLV with type and length on 16 bits, value is a BinStruct::String
|
134
|
+
# FirstTLV = BinStruct::AbstractTLV.create(type_class: BinStruct::Int16, length_class: BinStruct::Int16)
|
135
|
+
# # TLV with same type and length classes than FirstTLV, but value is an array of Int8
|
136
|
+
# SecondTLV = FirstTLV.derive(value_class: BinStruct::ArrayOfInt8)
|
137
|
+
def derive(type_class: nil, length_class: nil, value_class: nil, aliases: {})
|
138
|
+
raise Error, ".derive cannot be called on #{name}" if equal?(AbstractTLV)
|
139
|
+
|
140
|
+
klass = Class.new(self)
|
141
|
+
klass.aliases.merge!(aliases)
|
142
|
+
generate_aliases_for(klass, aliases)
|
143
|
+
|
144
|
+
klass.attr_defs[:type].type = type_class unless type_class.nil?
|
145
|
+
klass.attr_defs[:length].type = length_class unless length_class.nil?
|
146
|
+
klass.attr_defs[:value].type = value_class unless value_class.nil?
|
147
|
+
|
148
|
+
klass
|
149
|
+
end
|
150
|
+
|
106
151
|
# @!attribute type
|
107
152
|
# @abstract
|
108
153
|
# Type attribute for real TLV class
|
@@ -168,6 +213,15 @@ module BinStruct
|
|
168
213
|
end
|
169
214
|
end
|
170
215
|
end
|
216
|
+
|
217
|
+
def generate_aliases_for(klass, aliases)
|
218
|
+
aliases.each do |al, orig|
|
219
|
+
klass.instance_eval do
|
220
|
+
alias_method al, orig if klass.method_defined?(orig)
|
221
|
+
alias_method :"#{al}=", :"#{orig}=" if klass.method_defined?(:"#{orig}=")
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
171
225
|
end
|
172
226
|
|
173
227
|
# @!attribute type
|
data/lib/bin_struct/array.rb
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
require 'forwardable'
|
10
10
|
|
11
11
|
module BinStruct
|
12
|
-
# @abstract Base class to define set of {
|
12
|
+
# @abstract Base class to define set of {Structable} subclasses.
|
13
13
|
#
|
14
14
|
# This class mimics regular Ruby Array, but it is {Structable} and responds to {LengthFrom}.
|
15
15
|
#
|
@@ -44,10 +44,11 @@ module BinStruct
|
|
44
44
|
# @!method clear
|
45
45
|
# Clear array.
|
46
46
|
# @return [void]
|
47
|
+
# @see #clear!
|
47
48
|
# @!method each
|
48
49
|
# Calls the given block once for each element in self, passing that
|
49
|
-
# element as a parameter. Returns the array itself.
|
50
|
-
# @return [::Array]
|
50
|
+
# element as a parameter. Returns the array itself, or an enumerator if no block is given.
|
51
|
+
# @return [::Array, Enumerator]
|
51
52
|
# @method empty?
|
52
53
|
# Return +true+ if contains no element.
|
53
54
|
# @return [Boolean]
|
@@ -112,6 +113,7 @@ module BinStruct
|
|
112
113
|
|
113
114
|
# Clear array. Reset associated counter, if any.
|
114
115
|
# @return [void]
|
116
|
+
# @see #clear
|
115
117
|
def clear!
|
116
118
|
@array.clear
|
117
119
|
@counter&.from_human(0)
|
@@ -137,7 +139,8 @@ module BinStruct
|
|
137
139
|
|
138
140
|
# @abstract depend on private method +#record_from_hash+ which should be
|
139
141
|
# declared by subclasses.
|
140
|
-
# Add an object to this array. Do not update associated counter.
|
142
|
+
# Add an object to this array. Do not update associated counter. If associated must be incremented, use
|
143
|
+
# {#<<}
|
141
144
|
# @param [Object] obj type depends on subclass
|
142
145
|
# @return [self]
|
143
146
|
# @see #<<
|
@@ -154,9 +157,11 @@ module BinStruct
|
|
154
157
|
|
155
158
|
# @abstract depend on private method +#record_from_hash+ which should be
|
156
159
|
# declared by subclasses.
|
157
|
-
# Add an object to this array, and increment associated counter, if any
|
160
|
+
# Add an object to this array, and increment associated counter, if any. If associated counter must not be
|
161
|
+
# incremented, use {#push}.
|
158
162
|
# @param [Object] obj type depends on subclass
|
159
163
|
# @return [self]
|
164
|
+
# @see #push
|
160
165
|
def <<(obj)
|
161
166
|
push(obj)
|
162
167
|
@counter&.from_human(@counter.to_i + 1)
|
data/lib/bin_struct/bit_attr.rb
CHANGED
@@ -15,13 +15,14 @@ module BinStruct
|
|
15
15
|
# define_attr :int32, BinStruct::BitAttr.create(width: 32, a: 16, b: 4, c: 4, d:8)
|
16
16
|
# end
|
17
17
|
# @since 0.3.0
|
18
|
+
# @abstract Subclasses must de derived using {.create}.
|
18
19
|
# @author LemonTree55
|
19
20
|
class BitAttr
|
20
21
|
include Structable
|
21
22
|
|
22
23
|
# @return [Integer] width in bits of bit attribute
|
23
24
|
attr_reader :width
|
24
|
-
# @return [Array[Symbol]]
|
25
|
+
# @return [::Array[Symbol]]
|
25
26
|
attr_reader :bit_methods
|
26
27
|
|
27
28
|
# @private
|
@@ -79,9 +80,10 @@ module BinStruct
|
|
79
80
|
# @param [Hash{Symbol=>Integer}] opts initialization values for fields, where keys are field names and values are
|
80
81
|
# initialization values
|
81
82
|
# @return [self]
|
83
|
+
# @raise [NotImplementedError] raised when called on {BitAttr} class
|
82
84
|
def initialize(opts = {})
|
83
85
|
parameters = self.class.parameters
|
84
|
-
raise NotImplementedError,
|
86
|
+
raise NotImplementedError, "#initialize may only be called on subclass of #{self.class}" if parameters.nil?
|
85
87
|
|
86
88
|
@width = parameters.width
|
87
89
|
@fields = parameters.fields
|
@@ -110,7 +112,7 @@ module BinStruct
|
|
110
112
|
end
|
111
113
|
|
112
114
|
# Populate bit attribute from +str+
|
113
|
-
# @param [
|
115
|
+
# @param [#to_s,nil] str
|
114
116
|
# @return [self]
|
115
117
|
def read(str)
|
116
118
|
return self if str.nil?
|
@@ -175,7 +177,7 @@ module BinStruct
|
|
175
177
|
if size == 1
|
176
178
|
instance_eval "def #{name}?; @data[#{name.inspect}] != 0; end\n", __FILE__, __LINE__
|
177
179
|
instance_eval "def #{name}=(val); v = case val when TrueClass; 1 when FalseClass; 0 else val end; " \
|
178
|
-
"@data[#{name.inspect}] = v; end", __FILE__, __LINE__ -
|
180
|
+
"@data[#{name.inspect}] = v; end", __FILE__, __LINE__ - 1
|
179
181
|
bit_methods << :"#{name}?"
|
180
182
|
else
|
181
183
|
instance_eval "def #{name}=(val); @data[#{name.inspect}] = val; end", __FILE__, __LINE__
|
data/lib/bin_struct/cstring.rb
CHANGED
@@ -76,14 +76,14 @@ module BinStruct
|
|
76
76
|
|
77
77
|
# @param [Hash] options
|
78
78
|
# @option options [Integer] :static_length set a static length for this string
|
79
|
-
# @option options [::String] :value string value (default to +
|
79
|
+
# @option options [::String] :value string value (default to +""+)
|
80
80
|
def initialize(options = {})
|
81
81
|
register_internal_string(options[:value] || +'')
|
82
82
|
@static_length = options[:static_length]
|
83
83
|
end
|
84
84
|
|
85
85
|
# Populate self from binary string
|
86
|
-
# @param [
|
86
|
+
# @param [#to_s] str
|
87
87
|
# @return [self]
|
88
88
|
def read(str)
|
89
89
|
s = str.to_s
|
data/lib/bin_struct/enum.rb
CHANGED
@@ -13,19 +13,20 @@ module BinStruct
|
|
13
13
|
# and named values.
|
14
14
|
#
|
15
15
|
# == Simple example
|
16
|
-
#
|
16
|
+
# enum = Int8Enum.new('low' => 0, 'medium' => 1, 'high' => 2})
|
17
17
|
# In this example, +enum+ is a 8-bit attribute which may take one
|
18
18
|
# among three values: +low+, +medium+ or +high+:
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
# Setting an unknown
|
25
|
-
#
|
26
|
-
#
|
27
|
-
# But {#read} will not raise when reading an outbound value. This
|
19
|
+
# enum.value = 'high'
|
20
|
+
# enum.value # => 2
|
21
|
+
# enum.value = 1
|
22
|
+
# enum.value # => 1
|
23
|
+
# enum.to_human # => "medium"
|
24
|
+
# Setting an unknown name will raise an exception:
|
25
|
+
# enum.value = 'unknown' # => raise!
|
26
|
+
# But {#read} and {#value=} will not raise when reading/setting an out-of-bound integer. This
|
28
27
|
# to enable decoding (or forging) of bad packets.
|
28
|
+
# enum.read("\x05".b).value # => 5
|
29
|
+
# enum.value = 4 # => 4
|
29
30
|
# @author Sylvain Daubert (2016-2024)
|
30
31
|
# @author LemonTree55
|
31
32
|
class Enum < Int
|
data/lib/bin_struct/int.rb
CHANGED
@@ -55,7 +55,7 @@ module BinStruct
|
|
55
55
|
|
56
56
|
# @abstract
|
57
57
|
# @return [::String]
|
58
|
-
# @raise [Error] This is an
|
58
|
+
# @raise [Error] This is an abstract method and must be redefined
|
59
59
|
def to_s
|
60
60
|
raise Error, 'BinStruct::Int#to_s is abstract' unless defined? @packstr
|
61
61
|
|
@@ -9,6 +9,13 @@
|
|
9
9
|
module BinStruct
|
10
10
|
# Provides a class for creating strings preceeded by their length as an {Int}.
|
11
11
|
# By default, a null string will have one byte length (length byte set to 0).
|
12
|
+
# == Examples
|
13
|
+
# # IntString with 8-bit length
|
14
|
+
# is8 = BinStruct::IntString.new(value: "abcd")
|
15
|
+
# is8.to_s # => "\x04abcd"
|
16
|
+
# # IntString with 16-bit length
|
17
|
+
# is16 = BinStruct::IntString.new(length_type: BinStruct::Int16le, value: "abcd")
|
18
|
+
# is16.to_s # => "\x04\x00abcd"
|
12
19
|
# @author Sylvain Daubert (2016-2024)
|
13
20
|
# @author LemonTree55
|
14
21
|
class IntString
|
data/lib/bin_struct/string.rb
CHANGED
@@ -32,7 +32,7 @@ module BinStruct
|
|
32
32
|
# @option options [Int,Proc] :length_from object or proc from which
|
33
33
|
# takes length when reading
|
34
34
|
# @option options [Integer] :static_length set a static length for this string
|
35
|
-
# @option options [::String] :value string value (default to +
|
35
|
+
# @option options [::String] :value string value (default to +""+)
|
36
36
|
def initialize(options = {})
|
37
37
|
register_internal_string(options[:value] || +'')
|
38
38
|
initialize_length_from(options)
|
@@ -47,7 +47,7 @@ module BinStruct
|
|
47
47
|
end
|
48
48
|
|
49
49
|
# Populate String from a binary String. Limit length using {LengthFrom} or {#static_length}, if one is set.
|
50
|
-
# @param [::String] str
|
50
|
+
# @param [::String,nil] str
|
51
51
|
# @return [self]
|
52
52
|
def read(str)
|
53
53
|
s = read_with_length_from(str)
|
@@ -87,7 +87,7 @@ module BinStruct
|
|
87
87
|
self
|
88
88
|
end
|
89
89
|
|
90
|
-
# Generate binary string
|
90
|
+
# Generate "binary" string
|
91
91
|
# @return [::String]
|
92
92
|
def to_s
|
93
93
|
@string
|
data/lib/bin_struct/struct.rb
CHANGED
@@ -401,6 +401,15 @@ module BinStruct
|
|
401
401
|
@attributes[attr] = obj
|
402
402
|
end
|
403
403
|
|
404
|
+
# Say if struct has given attribute
|
405
|
+
# @param [Symbol] attr attribute name
|
406
|
+
# @return [Boolean]
|
407
|
+
# @since 0.4.0
|
408
|
+
# @author LemonTree55
|
409
|
+
def attribute?(attr)
|
410
|
+
@attributes.key?(attr)
|
411
|
+
end
|
412
|
+
|
404
413
|
# Get all attribute names
|
405
414
|
# @return [Array<Symbol>]
|
406
415
|
def attributes
|
@@ -575,7 +584,7 @@ module BinStruct
|
|
575
584
|
# @return [String]
|
576
585
|
def inspect_titleize
|
577
586
|
title = self.class.to_s
|
578
|
-
|
587
|
+
"-- #{title} #{'-' * (66 - title.length)}\n"
|
579
588
|
end
|
580
589
|
|
581
590
|
# @param [:Symbol] attr
|
data/lib/bin_struct/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bin_struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LemonTree55
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'BinStruct is a binary dissector and generator. It eases manipulating
|
14
14
|
complex binary data.
|
@@ -58,7 +58,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 3.0.0
|
62
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
64
|
- - ">="
|