bin_struct 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|