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 +4 -4
- data/CHANGELOG.md +29 -2
- data/README.md +8 -2
- data/lib/bin_struct/abstract_tlv.rb +75 -73
- data/lib/bin_struct/array.rb +35 -26
- data/lib/bin_struct/cstring.rb +64 -12
- data/lib/bin_struct/enum.rb +35 -25
- data/lib/bin_struct/int.rb +59 -77
- data/lib/bin_struct/int_string.rb +20 -13
- data/lib/bin_struct/length_from.rb +6 -6
- data/lib/bin_struct/oui.rb +13 -10
- data/lib/bin_struct/string.rb +26 -13
- data/lib/bin_struct/struct.rb +628 -0
- data/lib/bin_struct/{fieldable.rb → structable.rb} +15 -15
- data/lib/bin_struct/version.rb +2 -1
- data/lib/bin_struct.rb +2 -2
- metadata +4 -4
- data/lib/bin_struct/fields.rb +0 -612
data/lib/bin_struct/cstring.rb
CHANGED
@@ -10,30 +10,81 @@ require 'forwardable'
|
|
10
10
|
|
11
11
|
module BinStruct
|
12
12
|
# This class handles null-terminated strings (aka C strings).
|
13
|
-
# @author Sylvain Daubert
|
14
|
-
# @
|
13
|
+
# @author Sylvain Daubert (2016-2024)
|
14
|
+
# @author LemonTree55
|
15
15
|
class CString
|
16
16
|
extend Forwardable
|
17
|
-
include
|
18
|
-
|
17
|
+
include Structable
|
18
|
+
|
19
|
+
# @!method [](index)
|
20
|
+
# @overload [](index)
|
21
|
+
# Return the character at +index+.
|
22
|
+
# @param [Integer] index
|
23
|
+
# @overload [](start, length)
|
24
|
+
# Return the substring starting at +start+ with +length+ length.
|
25
|
+
# @param [Integer] start
|
26
|
+
# @param [Integer] length
|
27
|
+
# @return [::String,nil]
|
28
|
+
# @!method length
|
29
|
+
# Return string length (without null-terminator)
|
30
|
+
# @return [Integer]
|
31
|
+
# @method size
|
32
|
+
# Return string length (without null-terminator)
|
33
|
+
# @return [Integer]
|
34
|
+
# @see #length
|
35
|
+
# @!method ==
|
36
|
+
# Check equality with underlying Ruby String
|
37
|
+
# @return [Boolean]
|
38
|
+
# @!method unpack
|
39
|
+
# Apply unpack on underlying Ruby String
|
40
|
+
# @see ::String#unpack
|
41
|
+
# @return [::Array]
|
42
|
+
# @!method force_encoding
|
43
|
+
# @see ::String#force_encoding
|
44
|
+
# @!method encoding
|
45
|
+
# @see ::String#encoding
|
46
|
+
# @return [Encoding]
|
47
|
+
# @!method index(substring, offset = 0)
|
48
|
+
# Returns the Integer index of the first occurrence of the given substring, or +nil+ if none found.
|
49
|
+
# @param [::String] substring
|
50
|
+
# @param [Integer] offset
|
51
|
+
# @return [Integer,nil]
|
52
|
+
# @!method empty?
|
53
|
+
# Return +true+ is string is empty.
|
54
|
+
# @return [Boolean]
|
55
|
+
# @!method encode(encoding, **options)
|
56
|
+
# @return [::String]
|
57
|
+
# @see ::String#encode
|
58
|
+
# @!method slice(*args)
|
59
|
+
# Returns the substring of +self+ specified by the arguments.
|
60
|
+
# @see ::String#slice
|
61
|
+
# @return [String,nil]
|
62
|
+
# @!method slice!(*args)
|
63
|
+
# Removes the substring of +self+ specified by the arguments; returns the removed substring.
|
64
|
+
# @see ::String#slice!
|
65
|
+
# @return [String,nil]
|
19
66
|
def_delegators :@string, :[], :length, :size, :inspect, :==,
|
20
67
|
:unpack, :force_encoding, :encoding, :index, :empty?,
|
21
68
|
:encode, :slice, :slice!
|
22
69
|
|
70
|
+
# Underlying Ruby String
|
23
71
|
# @return [::String]
|
24
72
|
attr_reader :string
|
25
|
-
#
|
73
|
+
# Static length, if any
|
74
|
+
# @return [Integer,nil]
|
26
75
|
attr_reader :static_length
|
27
76
|
|
28
77
|
# @param [Hash] options
|
29
78
|
# @option options [Integer] :static_length set a static length for this string
|
79
|
+
# @option options [::String] :value string value (default to +''+)
|
30
80
|
def initialize(options = {})
|
31
|
-
register_internal_string(+'')
|
81
|
+
register_internal_string(options[:value] || +'')
|
32
82
|
@static_length = options[:static_length]
|
33
83
|
end
|
34
84
|
|
85
|
+
# Populate self from binary string
|
35
86
|
# @param [::String] str
|
36
|
-
# @return [
|
87
|
+
# @return [self]
|
37
88
|
def read(str)
|
38
89
|
s = str.to_s
|
39
90
|
s = s[0, static_length] if static_length?
|
@@ -42,8 +93,8 @@ module BinStruct
|
|
42
93
|
self
|
43
94
|
end
|
44
95
|
|
45
|
-
#
|
46
|
-
# @return [String]
|
96
|
+
# Get null-terminated string
|
97
|
+
# @return [::String]
|
47
98
|
def to_s
|
48
99
|
if static_length?
|
49
100
|
s = string[0, static_length - 1]
|
@@ -63,6 +114,7 @@ module BinStruct
|
|
63
114
|
self
|
64
115
|
end
|
65
116
|
|
117
|
+
# Get C String size in bytes
|
66
118
|
# @return [Integer]
|
67
119
|
def sz
|
68
120
|
if static_length?
|
@@ -74,19 +126,19 @@ module BinStruct
|
|
74
126
|
|
75
127
|
# Say if a static length is defined
|
76
128
|
# @return [Boolean]
|
77
|
-
# @since 3.1.6
|
78
129
|
def static_length?
|
79
130
|
!static_length.nil?
|
80
131
|
end
|
81
132
|
|
82
133
|
# Populate CString from a human readable string
|
83
|
-
# @param [String] str
|
134
|
+
# @param [::String] str
|
84
135
|
# @return [self]
|
85
136
|
def from_human(str)
|
86
137
|
read str
|
87
138
|
end
|
88
139
|
|
89
|
-
#
|
140
|
+
# Get human-readable string
|
141
|
+
# @return [::String]
|
90
142
|
def to_human
|
91
143
|
string
|
92
144
|
end
|
data/lib/bin_struct/enum.rb
CHANGED
@@ -9,12 +9,12 @@
|
|
9
9
|
module BinStruct
|
10
10
|
# @abstract Base enum class to handle binary integers with limited
|
11
11
|
# authorized values
|
12
|
-
# An {Enum} type is used to handle an {Int}
|
12
|
+
# An {Enum} type is used to handle an {Int} attribute with limited
|
13
13
|
# and named values.
|
14
14
|
#
|
15
15
|
# == Simple example
|
16
16
|
# enum = Int8Enum.new('low' => 0, 'medium' => 1, 'high' => 2})
|
17
|
-
# In this example, +enum+ is a 8-bit
|
17
|
+
# In this example, +enum+ is a 8-bit attribute which may take one
|
18
18
|
# among three values: +low+, +medium+ or +high+:
|
19
19
|
# enum.value = 'high'
|
20
20
|
# enum.value # => 2
|
@@ -26,16 +26,18 @@ module BinStruct
|
|
26
26
|
# enum.value = 'unknown' # => raise!
|
27
27
|
# But {#read} will not raise when reading an outbound value. This
|
28
28
|
# to enable decoding (or forging) of bad packets.
|
29
|
-
# @author Sylvain Daubert
|
29
|
+
# @author Sylvain Daubert (2016-2024)
|
30
|
+
# @author LemonTree55
|
30
31
|
class Enum < Int
|
31
|
-
#
|
32
|
+
# Enumerated values
|
33
|
+
# @return [Hash{::String => Integer}]
|
32
34
|
attr_reader :enum
|
33
35
|
|
34
36
|
# @param [Hash] options
|
35
37
|
# @see Int#initialize
|
36
|
-
# @option options [Hash] enum enumerated values. Default value is taken from
|
38
|
+
# @option options [Hash{::String => Integer}] :enum enumerated values. Default value is taken from
|
37
39
|
# first element unless given. This option is mandatory.
|
38
|
-
# @option options [Integer
|
40
|
+
# @option options [Integer,::String] :default
|
39
41
|
# @author LemonTree55
|
40
42
|
def initialize(options = {})
|
41
43
|
enum = options[:enum]
|
@@ -69,11 +71,13 @@ module BinStruct
|
|
69
71
|
alias from_human value=
|
70
72
|
|
71
73
|
# Get human readable value (enum name)
|
72
|
-
# @return [String]
|
74
|
+
# @return [::String]
|
73
75
|
def to_human
|
74
76
|
@enum.key(to_i) || "<unknown:#{@value}>"
|
75
77
|
end
|
76
78
|
|
79
|
+
# Format Enum type when inspecting Struct
|
80
|
+
# @return [::String]
|
77
81
|
def format_inspect
|
78
82
|
format_str % [to_human, to_i]
|
79
83
|
end
|
@@ -83,7 +87,8 @@ module BinStruct
|
|
83
87
|
# @author LemonTree55
|
84
88
|
class Int8Enum < Enum
|
85
89
|
# @param [Hash] options
|
86
|
-
# @option options [Hash] :enum
|
90
|
+
# @option options [Hash{::String => Integer}] :enum enumerated values. Default value is taken from
|
91
|
+
# first element unless given. This option is mandatory.
|
87
92
|
# @option options [Integer,::String] :value
|
88
93
|
# @option options [Integer,::String] :default
|
89
94
|
def initialize(options = {})
|
@@ -99,7 +104,8 @@ module BinStruct
|
|
99
104
|
# @author LemonTree55
|
100
105
|
class Int16Enum < Enum
|
101
106
|
# @param [Hash] options
|
102
|
-
# @option options [Hash] :enum
|
107
|
+
# @option options [Hash{::String => Integer}] :enum enumerated values. Default value is taken from
|
108
|
+
# first element unless given. This option is mandatory.
|
103
109
|
# @option options [:big,:little] :endian
|
104
110
|
# @option options [Integer,::String] :value
|
105
111
|
# @option options [Integer,::String] :default
|
@@ -113,15 +119,16 @@ module BinStruct
|
|
113
119
|
end
|
114
120
|
|
115
121
|
# Enumeration on big endian 2-byte integer. See {Enum}.
|
116
|
-
# @author Sylvain Daubert
|
122
|
+
# @author Sylvain Daubert (2016-2024)
|
123
|
+
# @author LemonTree55
|
117
124
|
class Int16beEnum < Int16Enum
|
118
125
|
undef endian=
|
119
126
|
|
120
127
|
# @param [Hash] options
|
121
|
-
# @option options [Hash] :enum
|
128
|
+
# @option options [Hash{::String => Integer}] :enum enumerated values. Default value is taken from
|
129
|
+
# first element unless given. This option is mandatory.
|
122
130
|
# @option options [Integer,::String] :value
|
123
131
|
# @option options [Integer,::String] :default
|
124
|
-
# @author LemonTree55
|
125
132
|
def initialize(options = {})
|
126
133
|
opts = options.slice(:enum, :default, :value)
|
127
134
|
opts[:endian] = :big
|
@@ -129,16 +136,17 @@ module BinStruct
|
|
129
136
|
end
|
130
137
|
end
|
131
138
|
|
132
|
-
# Enumeration on
|
133
|
-
# @author Sylvain Daubert
|
139
|
+
# Enumeration on little endian 2-byte integer. See {Enum}.
|
140
|
+
# @author Sylvain Daubert (2016-2024)
|
141
|
+
# @author LemonTree55
|
134
142
|
class Int16leEnum < Int16Enum
|
135
143
|
undef endian=
|
136
144
|
|
137
145
|
# @param [Hash] options
|
138
|
-
# @option options [Hash] :enum
|
146
|
+
# @option options [Hash{::String => Integer}] :enum enumerated values. Default value is taken from
|
147
|
+
# first element unless given. This option is mandatory.
|
139
148
|
# @option options [Integer,::String] :value
|
140
149
|
# @option options [Integer,::String] :default
|
141
|
-
# @author LemonTree55
|
142
150
|
def initialize(options = {})
|
143
151
|
opts = options.slice(:enum, :default, :value)
|
144
152
|
opts[:endian] = :little
|
@@ -150,7 +158,8 @@ module BinStruct
|
|
150
158
|
# @author LemonTree55
|
151
159
|
class Int32Enum < Enum
|
152
160
|
# @param [Hash] options
|
153
|
-
# @option options [Hash] :enum
|
161
|
+
# @option options [Hash{::String => Integer}] :enum enumerated values. Default value is taken from
|
162
|
+
# first element unless given. This option is mandatory.
|
154
163
|
# @option options [:big,:little] :endian
|
155
164
|
# @option options [Integer,::String] :value
|
156
165
|
# @option options [Integer,::String] :default
|
@@ -164,15 +173,16 @@ module BinStruct
|
|
164
173
|
end
|
165
174
|
|
166
175
|
# Enumeration on big endian 4-byte integer. See {Enum}.
|
167
|
-
# @author Sylvain Daubert
|
176
|
+
# @author Sylvain Daubert (2016-2024)
|
177
|
+
# @author LemonTree55
|
168
178
|
class Int32beEnum < Int32Enum
|
169
179
|
undef endian=
|
170
180
|
|
171
181
|
# @param [Hash] options
|
172
|
-
# @option options [Hash] :enum
|
182
|
+
# @option options [Hash{::String => Integer}] :enum enumerated values. Default value is taken from
|
183
|
+
# first element unless given. This option is mandatory.
|
173
184
|
# @option options [Integer,::String] :value
|
174
185
|
# @option options [Integer,::String] :default
|
175
|
-
# @author LemonTree55
|
176
186
|
def initialize(options = {})
|
177
187
|
opts = options.slice(:enum, :default, :value)
|
178
188
|
opts[:endian] = :big
|
@@ -180,17 +190,17 @@ module BinStruct
|
|
180
190
|
end
|
181
191
|
end
|
182
192
|
|
183
|
-
# Enumeration on
|
184
|
-
# @author Sylvain Daubert
|
185
|
-
# @
|
193
|
+
# Enumeration on little endian 4-byte integer. See {Enum}.
|
194
|
+
# @author Sylvain Daubert (2016-2024)
|
195
|
+
# @author LemonTree55
|
186
196
|
class Int32leEnum < Int32Enum
|
187
197
|
undef endian=
|
188
198
|
|
189
199
|
# @param [Hash] options
|
190
|
-
# @option options [Hash] :enum
|
200
|
+
# @option options [Hash{::String => Integer}] :enum enumerated values. Default value is taken from
|
201
|
+
# first element unless given. This option is mandatory.
|
191
202
|
# @option options [Integer,::String] :value
|
192
203
|
# @option options [Integer,::String] :default
|
193
|
-
# @author LemonTree55
|
194
204
|
def initialize(options = {})
|
195
205
|
opts = options.slice(:enum, :default, :value)
|
196
206
|
opts[:endian] = :little
|