bistro 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/bistro.rb +55 -17
- data/lib/bistro/version.rb +1 -1
- data/spec/accum_spec.rb +29 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '083a2a52e47ed66b526780f8bcfe4d3cb270a1dde098c496497bd6b5f4b8f774'
|
4
|
+
data.tar.gz: 9388db96083be467a06e1e0b8032454f7e26095bf6b8a4594b58b4b01d124b0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4efee30bc303d5dd3725f69ffc16d544a1376b314e8d05d9c5aa9d7e2ef82d73aa45112d7f7ed3698bd9be5da2b65ddfc7e1583b7f3757b6e9f5f35a8521476a
|
7
|
+
data.tar.gz: 217c4ce2ddbb989d49da962d39d20c720be4c34c4e7fefd3186365661757ae1dab3852b52e13a91fdd85eb48fcf4e5c1b708e616bd42eafa363d5cc1ed90a398
|
data/lib/bistro.rb
CHANGED
@@ -60,10 +60,13 @@ class Bistro
|
|
60
60
|
else
|
61
61
|
value = value.to_a.map(&:reverse).flatten if value.kind_of?(Hash)
|
62
62
|
value = Array(value)
|
63
|
+
|
63
64
|
self.class.validate_definition(value)
|
64
65
|
@definition = value
|
65
66
|
end
|
66
|
-
|
67
|
+
|
68
|
+
@size = @decode_types = @decode_formats =
|
69
|
+
@decode_names = @decode_counts = nil
|
67
70
|
end
|
68
71
|
|
69
72
|
def size
|
@@ -81,15 +84,27 @@ class Bistro
|
|
81
84
|
|
82
85
|
def decode_to_array(data, num = 1)
|
83
86
|
raise ArgumentError, "data cannot be nil" if data.nil?
|
84
|
-
@
|
85
|
-
|
87
|
+
@decode_types, @decode_formats,
|
88
|
+
@decode_names, @decode_counts =
|
89
|
+
self.class.prep_decode(@definition) if @decode_formats.nil?
|
90
|
+
|
91
|
+
format = (num == 1) ? @decode_formats : @decode_formats * num
|
86
92
|
return data.unpack(format)
|
87
93
|
end
|
88
94
|
|
89
95
|
def decoded_array_to_hash!(array)
|
90
96
|
hash = {}
|
91
|
-
@decode_names.
|
92
|
-
|
97
|
+
@decode_names.each_with_index do |k,i|
|
98
|
+
c = @decode_counts[i].to_i
|
99
|
+
t = @decode_types[i]
|
100
|
+
|
101
|
+
v = nil
|
102
|
+
if !STRING_FORMATS.include?(t) && c != 1
|
103
|
+
v = 0.upto(c-1).collect { array.shift }
|
104
|
+
else
|
105
|
+
v = array.shift
|
106
|
+
end
|
107
|
+
|
93
108
|
next if k.nil?
|
94
109
|
hash[k] = v
|
95
110
|
end
|
@@ -107,12 +122,15 @@ class Bistro
|
|
107
122
|
def encode_hash(hash)
|
108
123
|
data = ""
|
109
124
|
@definition.each_slice(2) do |format, name|
|
110
|
-
raise "member not found: #{name}" unless name.nil? ||
|
125
|
+
raise "member not found: #{name}" unless name.nil? ||
|
126
|
+
hash.has_key?(name)
|
127
|
+
|
111
128
|
value = unless name.nil?
|
112
129
|
hash[name]
|
113
130
|
else
|
114
131
|
STRING_FORMATS.include?(format[0, 1]) ? '0' : 0
|
115
132
|
end
|
133
|
+
|
116
134
|
data << [value].pack(format)
|
117
135
|
end
|
118
136
|
return data
|
@@ -151,14 +169,19 @@ class Bistro
|
|
151
169
|
private
|
152
170
|
|
153
171
|
def self.struct_by_definition(definition)
|
154
|
-
@@structs_by_definition[definition] ||= definition.kind_of?(self) ?
|
172
|
+
@@structs_by_definition[definition] ||= definition.kind_of?(self) ?
|
173
|
+
definition :
|
174
|
+
self.new(definition)
|
155
175
|
end
|
156
176
|
|
157
177
|
def self.validate_definition(definition)
|
158
|
-
raise "definition must be an array of format/name pairs" if definition.empty? ||
|
178
|
+
raise "definition must be an array of format/name pairs" if definition.empty? ||
|
179
|
+
definition.length % 2 != 0
|
180
|
+
|
159
181
|
definition.each_slice(2) do |format, _|
|
160
|
-
|
161
|
-
modifier, modcount =
|
182
|
+
type, count = format[0, 1], format[1..-1]
|
183
|
+
modifier, modcount = count[0, 1], count[1..-1]
|
184
|
+
|
162
185
|
validate_definition_entry_type(type)
|
163
186
|
if valid_definition_entry_modifier?(modifier)
|
164
187
|
validate_definition_endian_modifier(modifier, type)
|
@@ -171,7 +194,7 @@ class Bistro
|
|
171
194
|
|
172
195
|
def self.validate_definition_entry_type(type)
|
173
196
|
raise "unrecognized format: #{type}" unless SIZES.has_key?(type)
|
174
|
-
raise "unsupported format: #{type}"
|
197
|
+
raise "unsupported format: #{type}" if SIZES[type].nil?
|
175
198
|
return true
|
176
199
|
end
|
177
200
|
|
@@ -192,7 +215,8 @@ class Bistro
|
|
192
215
|
|
193
216
|
def self.validate_definition_endian_modifier(modifier, type)
|
194
217
|
if ENDIAN_MODIFIERS.include? modifier
|
195
|
-
raise "unsupported type attribute #{type}
|
218
|
+
raise "unsupported type attribute #{type} "\
|
219
|
+
"for endian modifier #{modifier}" unless ENDIAN_FORMATS.include? type
|
196
220
|
return true
|
197
221
|
end
|
198
222
|
false
|
@@ -200,11 +224,13 @@ class Bistro
|
|
200
224
|
|
201
225
|
def self.get_size(definition)
|
202
226
|
size = 0
|
227
|
+
|
203
228
|
definition.each_slice(2) do |format, _|
|
204
|
-
|
205
|
-
modifier, modcount =
|
229
|
+
type, count = format[0, 1], format[1..-1]
|
230
|
+
modifier, modcount = count[0, 1], count[1..-1]
|
206
231
|
count = modcount if valid_definition_entry_modifier?(modifier)
|
207
232
|
count = count.empty? ? 1 : count.to_i
|
233
|
+
|
208
234
|
size +=
|
209
235
|
if BIT_FORMATS.include?(type)
|
210
236
|
(count / 8.0).ceil
|
@@ -214,16 +240,28 @@ class Bistro
|
|
214
240
|
count * SIZES[type]
|
215
241
|
end
|
216
242
|
end
|
243
|
+
|
217
244
|
size
|
218
245
|
end
|
219
246
|
|
220
247
|
def self.prep_decode(definition)
|
221
248
|
formats = ""
|
222
|
-
|
249
|
+
types = []
|
250
|
+
names = []
|
251
|
+
counts = []
|
252
|
+
|
223
253
|
definition.each_slice(2) do |format, name|
|
254
|
+
type, count = format[0, 1], format[1..-1]
|
255
|
+
modifier, modcount = count[0, 1], count[1..-1]
|
256
|
+
count = modcount if valid_definition_entry_modifier?(modifier)
|
257
|
+
count = 1 if count.empty?
|
258
|
+
|
259
|
+
types << type
|
224
260
|
formats << format
|
225
|
-
|
261
|
+
names << name
|
262
|
+
counts << count
|
226
263
|
end
|
227
|
-
|
264
|
+
|
265
|
+
return types, formats, names, counts
|
228
266
|
end
|
229
267
|
end
|
data/lib/bistro/version.rb
CHANGED
data/spec/accum_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
describe Bistro do
|
2
|
+
ACCUM_STRUCT_DEF = [
|
3
|
+
'C', 'first',
|
4
|
+
'C2', 'second',
|
5
|
+
'H', 'third',
|
6
|
+
'H2', 'fourth',
|
7
|
+
'b', 'fifth',
|
8
|
+
'b2', 'sixth',
|
9
|
+
'i', 'seventh',
|
10
|
+
'i2', 'eighth',
|
11
|
+
]
|
12
|
+
|
13
|
+
ACCUM_STRUCT_ENCODED_STR = "\0\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0\1\2\3\4\5\6\7\8\9\0"
|
14
|
+
|
15
|
+
ACCUM_STRUCT_DECODED_HASH = {
|
16
|
+
"first"=>0,
|
17
|
+
"second"=>[1, 2],
|
18
|
+
"third"=>"0",
|
19
|
+
"fourth"=>"04",
|
20
|
+
"fifth"=>"1",
|
21
|
+
"sixth"=>"01",
|
22
|
+
"seventh"=>3749895,
|
23
|
+
"eighth"=>[67305985, 939984389]
|
24
|
+
}
|
25
|
+
|
26
|
+
it "accumulates numerical values" do
|
27
|
+
expect(Bistro.new(ACCUM_STRUCT_DEF).decode(ACCUM_STRUCT_ENCODED_STR)).to eq(ACCUM_STRUCT_DECODED_HASH)
|
28
|
+
end
|
29
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bistro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dev Null Productions
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-04-
|
11
|
+
date: 2019-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- README.md
|
65
65
|
- lib/bistro.rb
|
66
66
|
- lib/bistro/version.rb
|
67
|
+
- spec/accum_spec.rb
|
67
68
|
- spec/bistro_spec.rb
|
68
69
|
- spec/data/test.gif
|
69
70
|
- spec/endian_spec.rb
|
@@ -94,6 +95,7 @@ signing_key:
|
|
94
95
|
specification_version: 4
|
95
96
|
summary: Bistro is a class for dealing with BInary STRuctured data.
|
96
97
|
test_files:
|
98
|
+
- spec/accum_spec.rb
|
97
99
|
- spec/bistro_spec.rb
|
98
100
|
- spec/data/test.gif
|
99
101
|
- spec/endian_spec.rb
|