binary_struct 1.0.1 → 2.0.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.
- data/.rspec +2 -1
- data/README.md +2 -0
- data/lib/binary_struct/version.rb +1 -1
- data/lib/binary_struct.rb +27 -4
- data/spec/binary_struct_spec.rb +35 -38
- data/spec/endian_spec.rb +192 -0
- data/spec/gif_spec.rb +11 -14
- data/spec/spec_helper.rb +72 -6
- metadata +12 -20
- data/.gitignore +0 -17
- data/Gemfile +0 -4
- data/Rakefile +0 -6
- data/binary_struct.gemspec +0 -30
- data/travis.yml +0 -9
data/.rspec
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# BinaryStruct
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/binary_struct)
|
3
4
|
[](https://travis-ci.org/ManageIQ/binary_struct)
|
4
5
|
[](https://codeclimate.com/github/ManageIQ/binary_struct)
|
5
6
|
[](https://coveralls.io/r/ManageIQ/binary_struct)
|
7
|
+
[](https://gemnasium.com/ManageIQ/binary_struct)
|
6
8
|
|
7
9
|
BinaryStruct is a class for dealing with binary structured data. It simplifies
|
8
10
|
expressing what the binary structure looks like, with the ability to name the
|
data/lib/binary_struct.rb
CHANGED
@@ -39,7 +39,10 @@ class BinaryStruct
|
|
39
39
|
'Z' => 1, # String with trailing NULs removed
|
40
40
|
}
|
41
41
|
|
42
|
-
STRING_FORMATS
|
42
|
+
STRING_FORMATS = %w(A a M m u)
|
43
|
+
ENDIAN_FORMATS = %w(I i L l Q q S s)
|
44
|
+
ENDIAN_MODIFIERS = %w(> <)
|
45
|
+
MODIFIERS = ENDIAN_MODIFIERS
|
43
46
|
|
44
47
|
def initialize(definition = nil)
|
45
48
|
self.definition = definition unless definition.nil?
|
@@ -152,8 +155,14 @@ class BinaryStruct
|
|
152
155
|
raise "definition must be an array of format/name pairs" if definition.empty? || definition.length % 2 != 0
|
153
156
|
definition.each_slice(2) do |format, _|
|
154
157
|
type, count = format[0, 1], format[1..-1]
|
158
|
+
modifier, modcount = count[0, 1], count[1..-1]
|
155
159
|
validate_definition_entry_type(type)
|
156
|
-
|
160
|
+
if valid_definition_entry_modifier?(modifier)
|
161
|
+
validate_definition_endian_modifier(modifier, type)
|
162
|
+
validate_definition_entry_count(modcount)
|
163
|
+
else
|
164
|
+
validate_definition_entry_count(count)
|
165
|
+
end
|
157
166
|
end
|
158
167
|
end
|
159
168
|
|
@@ -174,14 +183,28 @@ class BinaryStruct
|
|
174
183
|
raise "unsupported count: #{count}" if count < 0
|
175
184
|
end
|
176
185
|
|
186
|
+
def self.valid_definition_entry_modifier?(modifier)
|
187
|
+
MODIFIERS.include? modifier
|
188
|
+
end
|
189
|
+
|
190
|
+
def self.validate_definition_endian_modifier(modifier, type)
|
191
|
+
if ENDIAN_MODIFIERS.include? modifier
|
192
|
+
raise "unsupported type attribute #{type} for endian modifier #{modifier}" unless ENDIAN_FORMATS.include? type
|
193
|
+
return true
|
194
|
+
end
|
195
|
+
false
|
196
|
+
end
|
197
|
+
|
177
198
|
def self.get_size(definition)
|
178
199
|
size = 0
|
179
200
|
definition.each_slice(2) do |format, _|
|
180
|
-
type, count
|
201
|
+
type, count = format[0, 1], format[1..-1]
|
202
|
+
modifier, modcount = count[0, 1], count[1..-1]
|
203
|
+
count = modcount if valid_definition_entry_modifier?(modifier)
|
181
204
|
count = count.empty? ? 1 : count.to_i
|
182
205
|
size += (count * SIZES[type])
|
183
206
|
end
|
184
|
-
|
207
|
+
size
|
185
208
|
end
|
186
209
|
|
187
210
|
def self.prep_decode(definition)
|
data/spec/binary_struct_spec.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
2
|
-
|
3
|
-
require 'binary_struct'
|
4
|
-
|
5
1
|
describe BinaryStruct do
|
6
2
|
STRUCT_DEF = [
|
7
3
|
'Q', :quad,
|
@@ -22,89 +18,90 @@ describe BinaryStruct do
|
|
22
18
|
STRUCT_DEF_UNSUPPORTED_COUNT_NEG = ['a-1', nil]
|
23
19
|
STRUCT_DEF_UNSUPPORTED_COUNT_INV = ['aX', nil]
|
24
20
|
|
25
|
-
STRUCT_ENCODED_STR = "\000\111\222\333\444\555\666\777\000\111\222\333\000\111\0000BC"
|
21
|
+
STRUCT_ENCODED_STR = "\000\111\222\333\444\555\666\777\000\111\222\333\000\111\0000BC".force_encoding("ASCII-8BIT")
|
26
22
|
STRUCT_DECODED_HASH = {:quad=>18426034930503010560, "long"=>3683797248, :short=>18688, "bc"=>"BC", "none"=>""}
|
27
23
|
|
28
|
-
it('.new') {
|
29
|
-
it('.new with definition') {
|
30
|
-
it('.new with definition with *') {
|
24
|
+
it('.new') { expect { BinaryStruct.new }.not_to raise_error }
|
25
|
+
it('.new with definition') { expect { BinaryStruct.new(STRUCT_DEF) }.not_to raise_error }
|
26
|
+
it('.new with definition with *') { expect { BinaryStruct.new(STRUCT_DEF_ASTERISK) }.not_to raise_error }
|
31
27
|
it '.new with another BinaryStruct' do
|
32
28
|
s = BinaryStruct.new(STRUCT_DEF)
|
33
29
|
s2 = BinaryStruct.new(s)
|
34
|
-
s2.
|
35
|
-
s2.
|
30
|
+
expect(s2).to eq(s)
|
31
|
+
expect(s2).not_to equal(s)
|
36
32
|
end
|
37
33
|
|
38
|
-
it('.new with unrecognized format') {
|
39
|
-
it('.new with unsupported format') {
|
40
|
-
it('.new with unsupported negative count') {
|
41
|
-
it('.new with unsupported invalid count') {
|
34
|
+
it('.new with unrecognized format') { expect { BinaryStruct.new(STRUCT_DEF_UNRECOGNIZED_FORMAT) }.to raise_error(RuntimeError) }
|
35
|
+
it('.new with unsupported format') { expect { BinaryStruct.new(STRUCT_DEF_UNSUPPORTED_FORMAT) }.to raise_error(RuntimeError) }
|
36
|
+
it('.new with unsupported negative count') { expect { BinaryStruct.new(STRUCT_DEF_UNSUPPORTED_COUNT_NEG) }.to raise_error(RuntimeError) }
|
37
|
+
it('.new with unsupported invalid count') { expect { BinaryStruct.new(STRUCT_DEF_UNSUPPORTED_COUNT_INV) }.to raise_error(RuntimeError) }
|
42
38
|
|
43
|
-
it('#definition=') {
|
44
|
-
it('#definition= with definition with *') {
|
39
|
+
it('#definition=') { expect { BinaryStruct.new.definition = STRUCT_DEF }.not_to raise_error }
|
40
|
+
it('#definition= with definition with *') { expect { BinaryStruct.new.definition = STRUCT_DEF_ASTERISK }.not_to raise_error }
|
45
41
|
|
46
|
-
it('#definition= with unrecognized format') {
|
47
|
-
it('#definition= with unsupported format') {
|
48
|
-
it('#definition= with unsupported negative count') {
|
49
|
-
it('#definition= with unsupported invalid count') {
|
42
|
+
it('#definition= with unrecognized format') { expect { BinaryStruct.new.definition = STRUCT_DEF_UNRECOGNIZED_FORMAT }.to raise_error(RuntimeError) }
|
43
|
+
it('#definition= with unsupported format') { expect { BinaryStruct.new.definition = STRUCT_DEF_UNSUPPORTED_FORMAT }.to raise_error(RuntimeError) }
|
44
|
+
it('#definition= with unsupported negative count') { expect { BinaryStruct.new.definition = STRUCT_DEF_UNSUPPORTED_COUNT_NEG }.to raise_error(RuntimeError) }
|
45
|
+
it('#definition= with unsupported invalid count') { expect { BinaryStruct.new.definition = STRUCT_DEF_UNSUPPORTED_COUNT_INV }.to raise_error(RuntimeError) }
|
50
46
|
|
51
|
-
it('#size') { BinaryStruct.new(STRUCT_DEF).size.
|
52
|
-
it('#size with definition with *') { BinaryStruct.new(STRUCT_DEF_ASTERISK).size.
|
47
|
+
it('#size') { expect(BinaryStruct.new(STRUCT_DEF).size).to eq(STRUCT_DEF_SIZE) }
|
48
|
+
it('#size with definition with *') { expect(BinaryStruct.new(STRUCT_DEF_ASTERISK).size).to eq(STRUCT_DEF_ASTERISK_SIZE) }
|
53
49
|
|
54
50
|
it '#decode' do
|
55
|
-
BinaryStruct.new(STRUCT_DEF).decode(STRUCT_ENCODED_STR).
|
51
|
+
expect(BinaryStruct.new(STRUCT_DEF).decode(STRUCT_ENCODED_STR)).to eq(STRUCT_DECODED_HASH)
|
56
52
|
end
|
57
53
|
|
58
54
|
it '#decode with definition with *' do
|
59
|
-
BinaryStruct.new(STRUCT_DEF_ASTERISK).decode("Testing").
|
55
|
+
expect(BinaryStruct.new(STRUCT_DEF_ASTERISK).decode("Testing")).to eq(:word => "Testing")
|
60
56
|
end
|
61
57
|
|
62
58
|
it '#decode against multiple records' do
|
63
|
-
BinaryStruct.new(STRUCT_DEF).decode(STRUCT_ENCODED_STR * 10, 10).
|
59
|
+
expect(BinaryStruct.new(STRUCT_DEF).decode(STRUCT_ENCODED_STR * 10, 10)).to eq([STRUCT_DECODED_HASH] * 10)
|
64
60
|
end
|
65
61
|
|
66
62
|
it '#encode' do
|
67
|
-
BinaryStruct.new(STRUCT_DEF).encode(STRUCT_DECODED_HASH).
|
63
|
+
expect(BinaryStruct.new(STRUCT_DEF).encode(STRUCT_DECODED_HASH)).to eq(STRUCT_ENCODED_STR.force_encoding("ASCII-8BIT"))
|
68
64
|
end
|
69
65
|
|
70
66
|
it '#encode with definition with *' do
|
71
|
-
BinaryStruct.new(STRUCT_DEF_ASTERISK).encode(
|
67
|
+
expect(BinaryStruct.new(STRUCT_DEF_ASTERISK).encode(:word => "Testing")).to eq("Testing")
|
72
68
|
end
|
73
69
|
|
74
70
|
it '#encode against multiple records' do
|
75
|
-
BinaryStruct.new(STRUCT_DEF).encode([STRUCT_DECODED_HASH] * 10)
|
71
|
+
s = BinaryStruct.new(STRUCT_DEF).encode([STRUCT_DECODED_HASH] * 10)
|
72
|
+
expect(s).to eq(STRUCT_ENCODED_STR.force_encoding("ASCII-8BIT") * 10)
|
76
73
|
end
|
77
74
|
|
78
75
|
it '#== against another BinaryStruct' do
|
79
|
-
BinaryStruct.new(STRUCT_DEF).
|
80
|
-
BinaryStruct.new(STRUCT_DEF).
|
76
|
+
expect(BinaryStruct.new(STRUCT_DEF)).to eq(BinaryStruct.new(STRUCT_DEF))
|
77
|
+
expect(BinaryStruct.new(STRUCT_DEF)).not_to eq(BinaryStruct.new(STRUCT_DEF_ASTERISK))
|
81
78
|
end
|
82
79
|
|
83
80
|
it '#each will iterate over definition' do
|
84
81
|
dup_def = []
|
85
82
|
BinaryStruct.new(STRUCT_DEF).each { |field, name| dup_def << field << name }
|
86
|
-
dup_def.
|
83
|
+
expect(dup_def).to eq(STRUCT_DEF)
|
87
84
|
end
|
88
85
|
|
89
86
|
context "old style methods" do
|
90
87
|
after(:each) { BinaryStruct.clear_structs_by_definition_cache }
|
91
88
|
|
92
89
|
it '#sizeof' do
|
93
|
-
BinaryStruct.sizeof(STRUCT_DEF).
|
90
|
+
expect(BinaryStruct.sizeof(STRUCT_DEF)).to eq(STRUCT_DEF_SIZE)
|
94
91
|
# Do it twice for consistency reasons
|
95
|
-
BinaryStruct.sizeof(STRUCT_DEF).
|
92
|
+
expect(BinaryStruct.sizeof(STRUCT_DEF)).to eq(STRUCT_DEF_SIZE)
|
96
93
|
end
|
97
94
|
|
98
95
|
it '#decode' do
|
99
|
-
BinaryStruct.decode(STRUCT_ENCODED_STR, STRUCT_DEF).
|
96
|
+
expect(BinaryStruct.decode(STRUCT_ENCODED_STR, STRUCT_DEF)).to eq(STRUCT_DECODED_HASH)
|
100
97
|
# Do it twice for consistency reasons
|
101
|
-
BinaryStruct.decode(STRUCT_ENCODED_STR, STRUCT_DEF).
|
98
|
+
expect(BinaryStruct.decode(STRUCT_ENCODED_STR, STRUCT_DEF)).to eq(STRUCT_DECODED_HASH)
|
102
99
|
end
|
103
100
|
|
104
101
|
it '#encode' do
|
105
|
-
BinaryStruct.encode(STRUCT_DECODED_HASH, STRUCT_DEF).
|
102
|
+
expect(BinaryStruct.encode(STRUCT_DECODED_HASH, STRUCT_DEF)).to eq(STRUCT_ENCODED_STR.force_encoding("ASCII-8BIT"))
|
106
103
|
# Do it twice for consistency reasons
|
107
|
-
BinaryStruct.encode(STRUCT_DECODED_HASH, STRUCT_DEF).
|
104
|
+
expect(BinaryStruct.encode(STRUCT_DECODED_HASH, STRUCT_DEF)).to eq(STRUCT_ENCODED_STR.force_encoding("ASCII-8BIT"))
|
108
105
|
end
|
109
106
|
end
|
110
|
-
end
|
107
|
+
end
|
data/spec/endian_spec.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
describe BinaryStruct do
|
2
|
+
BIG_STRUCT_DEF = [
|
3
|
+
'Q>', :quad,
|
4
|
+
'L>', 'long',
|
5
|
+
'S>', :short,
|
6
|
+
'C', nil,
|
7
|
+
'a0', 'none',
|
8
|
+
'a', nil,
|
9
|
+
'a2', 'bc',
|
10
|
+
]
|
11
|
+
BIG_STRUCT_DEF_SIZE = 18
|
12
|
+
|
13
|
+
BIG_E_QUAD_STRUCT_DEF = ['Q>2', :quad]
|
14
|
+
BIG_E_QUAD_DEF_SIZE = 16
|
15
|
+
|
16
|
+
BIG_STRUCT_DEF_STAR = ['i>*', :word]
|
17
|
+
BIG_STRUCT_DEF_STAR_SIZE = 0 # '*' is ignored
|
18
|
+
|
19
|
+
BIG_STRUCT_DEF_UNRECOG_ENDIAN_FMT = ['Y>', nil]
|
20
|
+
BIG_STRUCT_DEF_UNSUPPORTED_ENDIAN_ATTRIBUTE = ['A>', nil]
|
21
|
+
BIG_STRUCT_DEF_INVALID_ENDIAN_MODIFIER = ['Q_', nil]
|
22
|
+
|
23
|
+
LIL_STRUCT_DEF = [
|
24
|
+
'Q<', :quad,
|
25
|
+
'L<', 'long',
|
26
|
+
'S<', :short,
|
27
|
+
'C', nil,
|
28
|
+
'a0', 'none',
|
29
|
+
'a', nil,
|
30
|
+
'a2', 'bc',
|
31
|
+
]
|
32
|
+
LIL_STRUCT_DEF_SIZE = 18
|
33
|
+
|
34
|
+
LIL_E_QUAD_STRUCT_DEF = ['Q<2', :quad]
|
35
|
+
LIL_E_QUAD_DEF_SIZE = 16
|
36
|
+
|
37
|
+
LIL_STRUCT_DEF_STAR = ['i<*', :word]
|
38
|
+
LIL_STRUCT_DEF_STAR_SIZE = 0 # '*' is ignored
|
39
|
+
|
40
|
+
LIL_STRUCT_DEF_UNRECOG_ENDIAN_FMT = ['Y<', nil]
|
41
|
+
LIL_STRUCT_DEF_UNSUPPORTED_ENDIAN_ATTRIBUTE = ['A<', nil]
|
42
|
+
|
43
|
+
END_STRUCT_ENCODED_STR = "\000\111\222\333\444\555\666\777\000\111\222\333\000\111\0000BC"
|
44
|
+
|
45
|
+
LIL_ENDIAN_STRUCT_DECODED_HASH = {:quad => 18_426_034_930_503_010_560,
|
46
|
+
"long" => 3_683_797_248,
|
47
|
+
:short => 18_688,
|
48
|
+
"bc" => "BC",
|
49
|
+
"none" => ""}
|
50
|
+
BIG_ENDIAN_STRUCT_DECODED_HASH = {:quad => 20_709_143_206_541_055,
|
51
|
+
"long" => 4_821_723,
|
52
|
+
:short => 73,
|
53
|
+
"none" => "",
|
54
|
+
"bc" => "BC"}
|
55
|
+
|
56
|
+
it('.new') { expect { BinaryStruct.new }.not_to raise_error }
|
57
|
+
it('.new with big definition') { expect { BinaryStruct.new(BIG_STRUCT_DEF) }.not_to raise_error }
|
58
|
+
it('.new with little definition') { expect { BinaryStruct.new(LIL_STRUCT_DEF) }.not_to raise_error }
|
59
|
+
it('.new with big definition with *') { expect { BinaryStruct.new(BIG_STRUCT_DEF_STAR) }.not_to raise_error }
|
60
|
+
it('.new with little definition with *') { expect { BinaryStruct.new(LIL_STRUCT_DEF_STAR) }.not_to raise_error }
|
61
|
+
it '.new with another big endian BinaryStruct' do
|
62
|
+
s = BinaryStruct.new(BIG_STRUCT_DEF)
|
63
|
+
s2 = BinaryStruct.new(s)
|
64
|
+
expect(s2).to eq(s)
|
65
|
+
expect(s2).not_to equal(s)
|
66
|
+
end
|
67
|
+
|
68
|
+
it '.new with another little endian BinaryStruct' do
|
69
|
+
s = BinaryStruct.new(LIL_STRUCT_DEF)
|
70
|
+
s2 = BinaryStruct.new(s)
|
71
|
+
expect(s2).to eq(s)
|
72
|
+
expect(s2).not_to equal(s)
|
73
|
+
end
|
74
|
+
|
75
|
+
it '.new big endian BinaryStruct with a little endian one' do
|
76
|
+
s = BinaryStruct.new(BIG_STRUCT_DEF)
|
77
|
+
s2 = BinaryStruct.new(LIL_STRUCT_DEF)
|
78
|
+
expect(s2).not_to eq(s)
|
79
|
+
expect(s2).not_to equal(s)
|
80
|
+
end
|
81
|
+
|
82
|
+
it('.new with unrecognized big e format') do
|
83
|
+
expect { BinaryStruct.new(BIG_STRUCT_DEF_UNRECOG_ENDIAN_FMT) }
|
84
|
+
.to raise_error(RuntimeError)
|
85
|
+
end
|
86
|
+
|
87
|
+
it('.new with unsupported big e attribute') do
|
88
|
+
expect { BinaryStruct.new(BIG_STRUCT_DEF_UNSUPPORTED_ENDIAN_ATTRIBUTE) }
|
89
|
+
.to raise_error(RuntimeError)
|
90
|
+
end
|
91
|
+
|
92
|
+
it('.new with invalid endian modifier') do
|
93
|
+
expect { BinaryStruct.new(BIG_STRUCT_DEF_INVALID_ENDIAN_MODIFIER) }
|
94
|
+
.to raise_error(RuntimeError)
|
95
|
+
end
|
96
|
+
|
97
|
+
it('.new with unrecognized little e format') do
|
98
|
+
expect { BinaryStruct.new(LIL_STRUCT_DEF_UNRECOG_ENDIAN_FMT) }
|
99
|
+
.to raise_error(RuntimeError)
|
100
|
+
end
|
101
|
+
|
102
|
+
it('.new with unsupported little e attribute') do
|
103
|
+
expect { BinaryStruct.new(LIL_STRUCT_DEF_UNSUPPORTED_ENDIAN_ATTRIBUTE) }
|
104
|
+
.to raise_error(RuntimeError)
|
105
|
+
end
|
106
|
+
|
107
|
+
it('#definition= with definition with *') do
|
108
|
+
expect { BinaryStruct.new.definition = BIG_STRUCT_DEF_STAR }
|
109
|
+
.not_to raise_error
|
110
|
+
end
|
111
|
+
|
112
|
+
it('#definition= with unrecognized big e format') do
|
113
|
+
expect { BinaryStruct.new.definition = BIG_STRUCT_DEF_UNRECOG_ENDIAN_FMT }
|
114
|
+
.to raise_error(RuntimeError)
|
115
|
+
end
|
116
|
+
it('#definition= with unsupported big e attribute') do
|
117
|
+
expect { BinaryStruct.new.definition = BIG_STRUCT_DEF_UNSUPPORTED_ENDIAN_ATTRIBUTE }
|
118
|
+
.to raise_error(RuntimeError)
|
119
|
+
end
|
120
|
+
it('#definition= with unrecognized little e format') do
|
121
|
+
expect { BinaryStruct.new.definition = LIL_STRUCT_DEF_UNRECOG_ENDIAN_FMT }
|
122
|
+
.to raise_error(RuntimeError)
|
123
|
+
end
|
124
|
+
it('#definition= with unsupported little e attribute') do
|
125
|
+
expect { BinaryStruct.new.definition = LIL_STRUCT_DEF_UNSUPPORTED_ENDIAN_ATTRIBUTE }
|
126
|
+
.to raise_error(RuntimeError)
|
127
|
+
end
|
128
|
+
|
129
|
+
it('#size') { expect(BinaryStruct.new(BIG_STRUCT_DEF).size).to eq(BIG_STRUCT_DEF_SIZE) }
|
130
|
+
it('#size') { expect(BinaryStruct.new(LIL_STRUCT_DEF).size).to eq(LIL_STRUCT_DEF_SIZE) }
|
131
|
+
it('#size with definition with *') { expect(BinaryStruct.new(BIG_STRUCT_DEF_STAR).size).to eq(BIG_STRUCT_DEF_STAR_SIZE) }
|
132
|
+
it('#size with definition with *') { expect(BinaryStruct.new(LIL_STRUCT_DEF_STAR).size).to eq(LIL_STRUCT_DEF_STAR_SIZE) }
|
133
|
+
|
134
|
+
it '#decode with different endian definitions' do
|
135
|
+
expect(BinaryStruct.new(BIG_STRUCT_DEF).decode(END_STRUCT_ENCODED_STR))
|
136
|
+
.not_to equal(BinaryStruct.new(LIL_STRUCT_DEF).decode(END_STRUCT_ENCODED_STR))
|
137
|
+
end
|
138
|
+
it '#encode with different endian definitions' do
|
139
|
+
big = BinaryStruct.new(BIG_STRUCT_DEF).encode(BIG_ENDIAN_STRUCT_DECODED_HASH)
|
140
|
+
little = BinaryStruct.new(LIL_STRUCT_DEF).encode(LIL_ENDIAN_STRUCT_DECODED_HASH)
|
141
|
+
expect(big).not_to equal(little)
|
142
|
+
end
|
143
|
+
|
144
|
+
it '#decode little endian struct' do
|
145
|
+
expect(BinaryStruct.new(LIL_STRUCT_DEF).decode(END_STRUCT_ENCODED_STR)).to eq(LIL_ENDIAN_STRUCT_DECODED_HASH)
|
146
|
+
end
|
147
|
+
it '#decode big endian struct' do
|
148
|
+
expect(BinaryStruct.new(BIG_STRUCT_DEF).decode(END_STRUCT_ENCODED_STR)).to eq(BIG_ENDIAN_STRUCT_DECODED_HASH)
|
149
|
+
end
|
150
|
+
|
151
|
+
it '#== against another little endian BinaryStruct' do
|
152
|
+
expect(BinaryStruct.new(LIL_STRUCT_DEF)).to eq(BinaryStruct.new(LIL_STRUCT_DEF))
|
153
|
+
end
|
154
|
+
it '#== big endian against another little endian BinaryStruct' do
|
155
|
+
expect(BinaryStruct.new(BIG_STRUCT_DEF)).not_to eq(BinaryStruct.new(LIL_STRUCT_DEF))
|
156
|
+
end
|
157
|
+
it '#== against another big endian BinaryStruct' do
|
158
|
+
expect(BinaryStruct.new(BIG_STRUCT_DEF)).to eq(BinaryStruct.new(BIG_STRUCT_DEF))
|
159
|
+
end
|
160
|
+
|
161
|
+
it '#each will iterate over definition' do
|
162
|
+
dup_def = []
|
163
|
+
BinaryStruct.new(BIG_STRUCT_DEF).each { |field, name| dup_def << field << name }
|
164
|
+
expect(dup_def).to eq(BIG_STRUCT_DEF)
|
165
|
+
end
|
166
|
+
|
167
|
+
it '#each will iterate over definition' do
|
168
|
+
dup_def = []
|
169
|
+
BinaryStruct.new(LIL_STRUCT_DEF).each { |field, name| dup_def << field << name }
|
170
|
+
expect(dup_def).to eq(LIL_STRUCT_DEF)
|
171
|
+
end
|
172
|
+
|
173
|
+
context "old style methods" do
|
174
|
+
after(:each) { BinaryStruct.clear_structs_by_definition_cache }
|
175
|
+
|
176
|
+
it '#sizeof' do
|
177
|
+
expect(BinaryStruct.sizeof(BIG_STRUCT_DEF)).to eq(BIG_STRUCT_DEF_SIZE)
|
178
|
+
end
|
179
|
+
# Do it twice for consistency reasons
|
180
|
+
it '#sizeof' do
|
181
|
+
expect(BinaryStruct.sizeof(BIG_STRUCT_DEF)).to eq(BIG_STRUCT_DEF_SIZE)
|
182
|
+
end
|
183
|
+
|
184
|
+
it '#sizeof' do
|
185
|
+
expect(BinaryStruct.sizeof(LIL_STRUCT_DEF)).to eq(LIL_STRUCT_DEF_SIZE)
|
186
|
+
end
|
187
|
+
# Do it twice for consistency reasons
|
188
|
+
it '#sizeof' do
|
189
|
+
expect(BinaryStruct.sizeof(LIL_STRUCT_DEF)).to eq(LIL_STRUCT_DEF_SIZE)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
data/spec/gif_spec.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
2
|
-
|
3
|
-
require 'binary_struct'
|
4
|
-
|
5
1
|
describe BinaryStruct do
|
6
2
|
let(:gif_header) do
|
7
3
|
BinaryStruct.new([
|
@@ -16,23 +12,24 @@ describe BinaryStruct do
|
|
16
12
|
end
|
17
13
|
|
18
14
|
it "read a gif header" do
|
19
|
-
filename = File.join(File.dirname(__FILE__), %w
|
20
|
-
|
21
|
-
header_size = gif_header.size
|
22
|
-
header = File.open(filename, "rb") { |f| f.read(header_size) }
|
23
|
-
gif_header.decode(header).should == {
|
15
|
+
filename = File.join(File.dirname(__FILE__), %w(data test.gif))
|
16
|
+
decoded_header_hash = {
|
24
17
|
:magic => "GIF",
|
25
18
|
:version => "89a",
|
26
19
|
:width => 16,
|
27
20
|
:height => 16,
|
28
21
|
:flags => "\x80",
|
29
22
|
:bg_color_index => 0,
|
30
|
-
:pixel_aspect_ratio => 0
|
23
|
+
:pixel_aspect_ratio => 0,
|
31
24
|
}
|
25
|
+
encoded_header = gif_header.encode(decoded_header_hash)
|
26
|
+
header_size = gif_header.size
|
27
|
+
header = File.open(filename, "rb") { |f| f.read(header_size) }
|
28
|
+
expect(encoded_header).to eq(header)
|
32
29
|
end
|
33
30
|
|
34
31
|
it "write a gif header" do
|
35
|
-
header = gif_header.encode(
|
32
|
+
header = gif_header.encode(
|
36
33
|
:magic => "GIF",
|
37
34
|
:version => "89a",
|
38
35
|
:width => 16,
|
@@ -40,8 +37,8 @@ describe BinaryStruct do
|
|
40
37
|
:flags => "\x80",
|
41
38
|
:bg_color_index => 0,
|
42
39
|
:pixel_aspect_ratio => 0
|
43
|
-
|
40
|
+
)
|
44
41
|
|
45
|
-
header.
|
42
|
+
expect(header).to eq("GIF89a\x10\x00\x10\x00\x80\x00\x00".force_encoding("ASCII-8BIT"))
|
46
43
|
end
|
47
|
-
end
|
44
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,19 +1,85 @@
|
|
1
1
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
2
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
-
#
|
4
|
-
# loaded
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause this
|
4
|
+
# file to always be loaded, without a need to explicitly require it in any files.
|
5
|
+
#
|
6
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
7
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
8
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
9
|
+
# individual file that may not need all of that loaded. Instead, make a
|
10
|
+
# separate helper file that requires this one and then use it only in the specs
|
11
|
+
# that actually need it.
|
12
|
+
#
|
13
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
14
|
+
# users commonly want.
|
5
15
|
#
|
6
16
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
17
|
RSpec.configure do |config|
|
8
|
-
|
18
|
+
# The settings below are suggested to provide a good initial experience
|
19
|
+
# with RSpec, but feel free to customize to your heart's content.
|
20
|
+
|
21
|
+
# These two settings work together to allow you to limit a spec run
|
22
|
+
# to individual examples or groups you care about by tagging them with
|
23
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
24
|
+
# get run.
|
25
|
+
config.filter_run :focus
|
9
26
|
config.run_all_when_everything_filtered = true
|
10
27
|
|
28
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
29
|
+
# file, and it's useful to allow more verbose output when running an
|
30
|
+
# individual spec file.
|
31
|
+
if config.files_to_run.one?
|
32
|
+
# Use the documentation formatter for detailed output,
|
33
|
+
# unless a formatter has already been configured
|
34
|
+
# (e.g. via a command-line flag).
|
35
|
+
config.default_formatter = 'doc'
|
36
|
+
end
|
37
|
+
|
38
|
+
# Print the 10 slowest examples and example groups at the
|
39
|
+
# end of the spec run, to help surface which specs are running
|
40
|
+
# particularly slow.
|
41
|
+
# config.profile_examples = 10
|
42
|
+
|
11
43
|
# Run specs in random order to surface order dependencies. If you find an
|
12
44
|
# order dependency and want to debug it, you can fix the order by providing
|
13
45
|
# the seed, which is printed after each run.
|
14
46
|
# --seed 1234
|
15
|
-
config.order =
|
47
|
+
config.order = :random
|
48
|
+
|
49
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
50
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
51
|
+
# test failures related to randomization by passing the same `--seed` value
|
52
|
+
# as the one that triggered the failure.
|
53
|
+
Kernel.srand config.seed
|
54
|
+
|
55
|
+
# rspec-expectations config goes here. You can use an alternate
|
56
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
57
|
+
# assertions if you prefer.
|
58
|
+
config.expect_with :rspec do |expectations|
|
59
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
60
|
+
# For more details, see:
|
61
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
62
|
+
expectations.syntax = :expect
|
63
|
+
end
|
64
|
+
|
65
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
66
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
67
|
+
config.mock_with :rspec do |mocks|
|
68
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
69
|
+
# For more details, see:
|
70
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
71
|
+
mocks.syntax = :expect
|
72
|
+
|
73
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
74
|
+
# a real object. This is generally recommended.
|
75
|
+
mocks.verify_partial_doubles = true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
begin
|
80
|
+
require 'coveralls'
|
81
|
+
Coveralls.wear!
|
82
|
+
rescue LoadError
|
16
83
|
end
|
17
84
|
|
18
|
-
require '
|
19
|
-
Coveralls.wear!
|
85
|
+
require 'binary_struct'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: binary_struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2014-07-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -51,7 +51,7 @@ dependencies:
|
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
54
|
+
version: '3.0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
57
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -59,7 +59,7 @@ dependencies:
|
|
59
59
|
requirements:
|
60
60
|
- - ! '>='
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: '0'
|
62
|
+
version: '3.0'
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
64
|
name: coveralls
|
65
65
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,20 +94,16 @@ executables: []
|
|
94
94
|
extensions: []
|
95
95
|
extra_rdoc_files: []
|
96
96
|
files:
|
97
|
-
- .gitignore
|
98
|
-
- .rspec
|
99
|
-
- Gemfile
|
100
|
-
- LICENSE.txt
|
101
|
-
- README.md
|
102
|
-
- Rakefile
|
103
|
-
- binary_struct.gemspec
|
104
97
|
- lib/binary_struct.rb
|
105
98
|
- lib/binary_struct/version.rb
|
99
|
+
- README.md
|
100
|
+
- LICENSE.txt
|
106
101
|
- spec/binary_struct_spec.rb
|
107
102
|
- spec/data/test.gif
|
103
|
+
- spec/endian_spec.rb
|
108
104
|
- spec/gif_spec.rb
|
109
105
|
- spec/spec_helper.rb
|
110
|
-
-
|
106
|
+
- .rspec
|
111
107
|
homepage: http://github.com/ManageIQ/binary_struct
|
112
108
|
licenses:
|
113
109
|
- MIT
|
@@ -120,27 +116,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
120
116
|
requirements:
|
121
117
|
- - ! '>='
|
122
118
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
124
|
-
segments:
|
125
|
-
- 0
|
126
|
-
hash: 944965749837137154
|
119
|
+
version: 1.9.3
|
127
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
121
|
none: false
|
129
122
|
requirements:
|
130
123
|
- - ! '>='
|
131
124
|
- !ruby/object:Gem::Version
|
132
125
|
version: '0'
|
133
|
-
segments:
|
134
|
-
- 0
|
135
|
-
hash: 944965749837137154
|
136
126
|
requirements: []
|
137
127
|
rubyforge_project:
|
138
|
-
rubygems_version: 1.8.
|
128
|
+
rubygems_version: 1.8.23.2
|
139
129
|
signing_key:
|
140
130
|
specification_version: 3
|
141
131
|
summary: BinaryStruct is a class for dealing with binary structured data.
|
142
132
|
test_files:
|
143
133
|
- spec/binary_struct_spec.rb
|
144
134
|
- spec/data/test.gif
|
135
|
+
- spec/endian_spec.rb
|
145
136
|
- spec/gif_spec.rb
|
146
137
|
- spec/spec_helper.rb
|
138
|
+
- .rspec
|
data/.gitignore
DELETED
data/Gemfile
DELETED
data/Rakefile
DELETED
data/binary_struct.gemspec
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'binary_struct/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "binary_struct"
|
8
|
-
spec.version = BinaryStruct::VERSION
|
9
|
-
spec.authors = ["Oleg Barenboim", "Jason Frey"]
|
10
|
-
spec.email = ["chessbyte@gmail.com", "fryguy9@gmail.com"]
|
11
|
-
spec.description = %q{
|
12
|
-
BinaryStruct is a class for dealing with binary structured data. It simplifies
|
13
|
-
expressing what the binary structure looks like, with the ability to name the
|
14
|
-
parts. Given this definition, it is easy to encode/decode the binary structure
|
15
|
-
from/to a Hash.
|
16
|
-
}
|
17
|
-
spec.summary = %q{BinaryStruct is a class for dealing with binary structured data.}
|
18
|
-
spec.homepage = "http://github.com/ManageIQ/binary_struct"
|
19
|
-
spec.license = "MIT"
|
20
|
-
|
21
|
-
spec.files = `git ls-files`.split($/)
|
22
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
|
-
spec.require_paths = ["lib"]
|
25
|
-
|
26
|
-
spec.add_development_dependency "bundler", "~> 1.3"
|
27
|
-
spec.add_development_dependency "rake"
|
28
|
-
spec.add_development_dependency "rspec"
|
29
|
-
spec.add_development_dependency "coveralls"
|
30
|
-
end
|