msgpack 1.5.6 → 1.8.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 +50 -0
- data/README.md +48 -12
- data/ext/java/org/msgpack/jruby/Buffer.java +3 -3
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +11 -20
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +1 -1
- data/ext/java/org/msgpack/jruby/Factory.java +11 -50
- data/ext/java/org/msgpack/jruby/Packer.java +9 -24
- data/ext/java/org/msgpack/jruby/Unpacker.java +15 -32
- data/ext/msgpack/buffer.c +69 -56
- data/ext/msgpack/buffer.h +138 -44
- data/ext/msgpack/buffer_class.c +132 -31
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/extconf.rb +20 -30
- data/ext/msgpack/factory_class.c +75 -86
- data/ext/msgpack/packer.c +13 -16
- data/ext/msgpack/packer.h +24 -21
- data/ext/msgpack/packer_class.c +72 -98
- data/ext/msgpack/packer_class.h +11 -0
- data/ext/msgpack/packer_ext_registry.c +31 -28
- data/ext/msgpack/packer_ext_registry.h +10 -14
- data/ext/msgpack/rbinit.c +1 -1
- data/ext/msgpack/rmem.c +3 -4
- data/ext/msgpack/sysdep.h +5 -2
- data/ext/msgpack/unpacker.c +201 -113
- data/ext/msgpack/unpacker.h +22 -15
- data/ext/msgpack/unpacker_class.c +87 -92
- data/ext/msgpack/unpacker_class.h +11 -0
- data/ext/msgpack/unpacker_ext_registry.c +4 -16
- data/ext/msgpack/unpacker_ext_registry.h +3 -7
- data/lib/msgpack/buffer.rb +9 -0
- data/lib/msgpack/factory.rb +90 -63
- data/lib/msgpack/packer.rb +10 -1
- data/lib/msgpack/unpacker.rb +14 -1
- data/lib/msgpack/version.rb +1 -1
- data/lib/msgpack.rb +1 -0
- data/msgpack.gemspec +8 -3
- metadata +21 -51
- data/.github/workflows/ci.yaml +0 -57
- data/.gitignore +0 -23
- data/.rubocop.yml +0 -36
- data/Gemfile +0 -9
- data/Rakefile +0 -70
- data/appveyor.yml +0 -18
- data/bench/bench.rb +0 -78
- data/doclib/msgpack/buffer.rb +0 -193
- data/doclib/msgpack/core_ext.rb +0 -101
- data/doclib/msgpack/error.rb +0 -19
- data/doclib/msgpack/extension_value.rb +0 -9
- data/doclib/msgpack/factory.rb +0 -145
- data/doclib/msgpack/packer.rb +0 -209
- data/doclib/msgpack/time.rb +0 -22
- data/doclib/msgpack/timestamp.rb +0 -44
- data/doclib/msgpack/unpacker.rb +0 -183
- data/doclib/msgpack.rb +0 -87
- data/msgpack.org.md +0 -46
- data/spec/bigint_spec.rb +0 -26
- data/spec/cases.json +0 -1
- data/spec/cases.msg +0 -0
- data/spec/cases_compact.msg +0 -0
- data/spec/cases_spec.rb +0 -39
- data/spec/cruby/buffer_io_spec.rb +0 -255
- data/spec/cruby/buffer_packer.rb +0 -29
- data/spec/cruby/buffer_spec.rb +0 -575
- data/spec/cruby/buffer_unpacker.rb +0 -19
- data/spec/cruby/unpacker_spec.rb +0 -70
- data/spec/ext_value_spec.rb +0 -99
- data/spec/exttypes.rb +0 -51
- data/spec/factory_spec.rb +0 -688
- data/spec/format_spec.rb +0 -301
- data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
- data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
- data/spec/jruby/unpacker_spec.rb +0 -186
- data/spec/msgpack_spec.rb +0 -214
- data/spec/pack_spec.rb +0 -61
- data/spec/packer_spec.rb +0 -575
- data/spec/random_compat.rb +0 -24
- data/spec/spec_helper.rb +0 -71
- data/spec/timestamp_spec.rb +0 -159
- data/spec/unpack_spec.rb +0 -57
- data/spec/unpacker_spec.rb +0 -859
data/spec/format_spec.rb
DELETED
@@ -1,301 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
require 'spec_helper'
|
3
|
-
|
4
|
-
describe MessagePack do
|
5
|
-
it "nil" do
|
6
|
-
check 1, nil
|
7
|
-
end
|
8
|
-
|
9
|
-
it "true" do
|
10
|
-
check 1, true
|
11
|
-
end
|
12
|
-
|
13
|
-
it "false" do
|
14
|
-
check 1, false
|
15
|
-
end
|
16
|
-
|
17
|
-
it "zero" do
|
18
|
-
check 1, 0
|
19
|
-
end
|
20
|
-
|
21
|
-
it "positive fixnum" do
|
22
|
-
check 1, 1
|
23
|
-
check 1, (1 << 6)
|
24
|
-
check 1, (1 << 7)-1
|
25
|
-
end
|
26
|
-
|
27
|
-
it "positive int 8" do
|
28
|
-
check 1, -1
|
29
|
-
check 2, (1 << 7)
|
30
|
-
check 2, (1 << 8) - 1
|
31
|
-
end
|
32
|
-
|
33
|
-
it "positive int 16" do
|
34
|
-
check 3, (1 << 8)
|
35
|
-
check 3, (1 << 16) - 1
|
36
|
-
end
|
37
|
-
|
38
|
-
it "positive int 32" do
|
39
|
-
check 5, (1 << 16)
|
40
|
-
check 5, (1 << 32) - 1
|
41
|
-
end
|
42
|
-
|
43
|
-
it "positive int 64" do
|
44
|
-
check 9, (1 << 32)
|
45
|
-
#check 9, (1<<64)-1
|
46
|
-
end
|
47
|
-
|
48
|
-
it "negative fixnum" do
|
49
|
-
check 1, -1
|
50
|
-
check 1, -((1 << 5)-1)
|
51
|
-
check 1, -(1 << 5)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "negative int 8" do
|
55
|
-
check 2, -((1 << 5)+1)
|
56
|
-
check 2, -(1 << 7)
|
57
|
-
end
|
58
|
-
|
59
|
-
it "negative int 16" do
|
60
|
-
check 3, -((1 << 7)+1)
|
61
|
-
check 3, -(1 << 15)
|
62
|
-
end
|
63
|
-
|
64
|
-
it "negative int 32" do
|
65
|
-
check 5, -((1 << 15)+1)
|
66
|
-
check 5, -(1 << 31)
|
67
|
-
end
|
68
|
-
|
69
|
-
it "negative int 64" do
|
70
|
-
check 9, -((1 << 31)+1)
|
71
|
-
check 9, -(1 << 63)
|
72
|
-
end
|
73
|
-
|
74
|
-
it "double" do
|
75
|
-
check 9, 1.0
|
76
|
-
check 9, 0.1
|
77
|
-
check 9, -0.1
|
78
|
-
check 9, -1.0
|
79
|
-
end
|
80
|
-
|
81
|
-
it "fixraw" do
|
82
|
-
check_raw 1, 0
|
83
|
-
check_raw 1, (1 << 5)-1
|
84
|
-
end
|
85
|
-
|
86
|
-
it "raw 8" do
|
87
|
-
check_raw 2, (1 << 5)
|
88
|
-
check_raw 2, (1 << 8)-1
|
89
|
-
end
|
90
|
-
|
91
|
-
it "raw 16" do
|
92
|
-
check_raw 3, (1 << 8)
|
93
|
-
check_raw 3, (1 << 16)-1
|
94
|
-
end
|
95
|
-
|
96
|
-
it "raw 32" do
|
97
|
-
check_raw 5, (1 << 16)
|
98
|
-
#check_raw 5, (1 << 32)-1 # memory error
|
99
|
-
end
|
100
|
-
|
101
|
-
it "str encoding is UTF_8" do
|
102
|
-
v = pack_unpack('string'.force_encoding(Encoding::UTF_8))
|
103
|
-
v.encoding.should == Encoding::UTF_8
|
104
|
-
end
|
105
|
-
|
106
|
-
it "str transcode US-ASCII" do
|
107
|
-
v = pack_unpack('string'.force_encoding(Encoding::US_ASCII))
|
108
|
-
v.encoding.should == Encoding::UTF_8
|
109
|
-
end
|
110
|
-
|
111
|
-
it "str transcode UTF-16" do
|
112
|
-
v = pack_unpack('string'.encode(Encoding::UTF_16))
|
113
|
-
v.encoding.should == Encoding::UTF_8
|
114
|
-
v.should == 'string'
|
115
|
-
end
|
116
|
-
|
117
|
-
it "str transcode EUC-JP 7bit safe" do
|
118
|
-
v = pack_unpack('string'.force_encoding(Encoding::EUC_JP))
|
119
|
-
v.encoding.should == Encoding::UTF_8
|
120
|
-
v.should == 'string'
|
121
|
-
end
|
122
|
-
|
123
|
-
it "str transcode EUC-JP 7bit unsafe" do
|
124
|
-
v = pack_unpack([0xa4, 0xa2].pack('C*').force_encoding(Encoding::EUC_JP))
|
125
|
-
v.encoding.should == Encoding::UTF_8
|
126
|
-
v.should == "\xE3\x81\x82".force_encoding('UTF-8')
|
127
|
-
end
|
128
|
-
|
129
|
-
it "symbol to str" do
|
130
|
-
v = pack_unpack(:a)
|
131
|
-
v.should == "a".force_encoding('UTF-8')
|
132
|
-
end
|
133
|
-
|
134
|
-
it "symbol to str with encoding" do
|
135
|
-
a = "\xE3\x81\x82".force_encoding('UTF-8')
|
136
|
-
v = pack_unpack(a.encode('Shift_JIS').to_sym)
|
137
|
-
v.encoding.should == Encoding::UTF_8
|
138
|
-
v.should == a
|
139
|
-
end
|
140
|
-
|
141
|
-
it "symbol to bin" do
|
142
|
-
a = "\xE3\x81\x82".force_encoding('ASCII-8BIT')
|
143
|
-
v = pack_unpack(a.to_sym)
|
144
|
-
v.encoding.should == Encoding::ASCII_8BIT
|
145
|
-
v.should == a
|
146
|
-
end
|
147
|
-
|
148
|
-
it "bin 8" do
|
149
|
-
check_bin 2, (1<<8)-1
|
150
|
-
end
|
151
|
-
|
152
|
-
it "bin 16" do
|
153
|
-
check_bin 3, (1<<16)-1
|
154
|
-
end
|
155
|
-
|
156
|
-
it "bin 32" do
|
157
|
-
check_bin 5, (1<<16)
|
158
|
-
end
|
159
|
-
|
160
|
-
it "bin encoding is ASCII_8BIT" do
|
161
|
-
pack_unpack('string'.force_encoding(Encoding::ASCII_8BIT)).encoding.should == Encoding::ASCII_8BIT
|
162
|
-
end
|
163
|
-
|
164
|
-
it "fixarray" do
|
165
|
-
check_array 1, 0
|
166
|
-
check_array 1, (1 << 4)-1
|
167
|
-
end
|
168
|
-
|
169
|
-
it "array 16" do
|
170
|
-
check_array 3, (1 << 4)
|
171
|
-
#check_array 3, (1 << 16)-1
|
172
|
-
end
|
173
|
-
|
174
|
-
it "array 32" do
|
175
|
-
#check_array 5, (1 << 16)
|
176
|
-
#check_array 5, (1 << 32)-1 # memory error
|
177
|
-
end
|
178
|
-
|
179
|
-
it "nil" do
|
180
|
-
match nil, "\xc0"
|
181
|
-
end
|
182
|
-
|
183
|
-
it "false" do
|
184
|
-
match false, "\xc2"
|
185
|
-
end
|
186
|
-
|
187
|
-
it "true" do
|
188
|
-
match true, "\xc3"
|
189
|
-
end
|
190
|
-
|
191
|
-
it "0" do
|
192
|
-
match 0, "\x00"
|
193
|
-
end
|
194
|
-
|
195
|
-
it "127" do
|
196
|
-
match 127, "\x7f"
|
197
|
-
end
|
198
|
-
|
199
|
-
it "128" do
|
200
|
-
match 128, "\xcc\x80"
|
201
|
-
end
|
202
|
-
|
203
|
-
it "256" do
|
204
|
-
match 256, "\xcd\x01\x00"
|
205
|
-
end
|
206
|
-
|
207
|
-
it "-1" do
|
208
|
-
match -1, "\xff"
|
209
|
-
end
|
210
|
-
|
211
|
-
it "-33" do
|
212
|
-
match -33, "\xd0\xdf"
|
213
|
-
end
|
214
|
-
|
215
|
-
it "-129" do
|
216
|
-
match -129, "\xd1\xff\x7f"
|
217
|
-
end
|
218
|
-
|
219
|
-
it "{1=>1}" do
|
220
|
-
obj = {1=>1}
|
221
|
-
match obj, "\x81\x01\x01"
|
222
|
-
end
|
223
|
-
|
224
|
-
it "1.0" do
|
225
|
-
match 1.0, "\xcb\x3f\xf0\x00\x00\x00\x00\x00\x00"
|
226
|
-
end
|
227
|
-
|
228
|
-
it "[]" do
|
229
|
-
match [], "\x90"
|
230
|
-
end
|
231
|
-
|
232
|
-
it "[0, 1, ..., 14]" do
|
233
|
-
obj = (0..14).to_a
|
234
|
-
match obj, "\x9f\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"
|
235
|
-
end
|
236
|
-
|
237
|
-
it "[0, 1, ..., 15]" do
|
238
|
-
obj = (0..15).to_a
|
239
|
-
match obj, "\xdc\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
240
|
-
end
|
241
|
-
|
242
|
-
it "{}" do
|
243
|
-
obj = {}
|
244
|
-
match obj, "\x80"
|
245
|
-
end
|
246
|
-
|
247
|
-
## FIXME
|
248
|
-
# it "{0=>0, 1=>1, ..., 14=>14}" do
|
249
|
-
# a = (0..14).to_a;
|
250
|
-
# match Hash[*a.zip(a).flatten], "\x8f\x05\x05\x0b\x0b\x00\x00\x06\x06\x0c\x0c\x01\x01\x07\x07\x0d\x0d\x02\x02\x08\x08\x0e\x0e\x03\x03\x09\x09\x04\x04\x0a\x0a"
|
251
|
-
# end
|
252
|
-
#
|
253
|
-
# it "{0=>0, 1=>1, ..., 15=>15}" do
|
254
|
-
# a = (0..15).to_a;
|
255
|
-
# match Hash[*a.zip(a).flatten], "\xde\x00\x10\x05\x05\x0b\x0b\x00\x00\x06\x06\x0c\x0c\x01\x01\x07\x07\x0d\x0d\x02\x02\x08\x08\x0e\x0e\x03\x03\x09\x09\x0f\x0f\x04\x04\x0a\x0a"
|
256
|
-
# end
|
257
|
-
|
258
|
-
## FIXME
|
259
|
-
# it "fixmap" do
|
260
|
-
# check_map 1, 0
|
261
|
-
# check_map 1, (1<<4)-1
|
262
|
-
# end
|
263
|
-
#
|
264
|
-
# it "map 16" do
|
265
|
-
# check_map 3, (1<<4)
|
266
|
-
# check_map 3, (1<<16)-1
|
267
|
-
# end
|
268
|
-
#
|
269
|
-
# it "map 32" do
|
270
|
-
# check_map 5, (1<<16)
|
271
|
-
# #check_map 5, (1<<32)-1 # memory error
|
272
|
-
# end
|
273
|
-
|
274
|
-
def check(len, obj)
|
275
|
-
raw = obj.to_msgpack.to_s
|
276
|
-
raw.length.should == len
|
277
|
-
MessagePack.unpack(raw).should == obj
|
278
|
-
end
|
279
|
-
|
280
|
-
def check_raw(overhead, num)
|
281
|
-
check num+overhead, (" "*num).force_encoding(Encoding::UTF_8)
|
282
|
-
end
|
283
|
-
|
284
|
-
def check_bin(overhead, num)
|
285
|
-
check num+overhead, (" "*num).force_encoding(Encoding::ASCII_8BIT)
|
286
|
-
end
|
287
|
-
|
288
|
-
def check_array(overhead, num)
|
289
|
-
check num+overhead, Array.new(num)
|
290
|
-
end
|
291
|
-
|
292
|
-
def match(obj, buf)
|
293
|
-
raw = obj.to_msgpack.to_s
|
294
|
-
raw.should == buf
|
295
|
-
end
|
296
|
-
|
297
|
-
def pack_unpack(obj)
|
298
|
-
MessagePack.unpack(obj.to_msgpack)
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
if RUBY_PLATFORM.include?('java')
|
4
|
-
# JRuby should use this library, MRI should use the standard gem
|
5
|
-
$: << File.expand_path('../../../lib', __FILE__)
|
6
|
-
end
|
7
|
-
|
8
|
-
require 'viiite'
|
9
|
-
require 'msgpack'
|
10
|
-
require 'json'
|
11
|
-
require 'bson'
|
12
|
-
|
13
|
-
if RUBY_PLATFORM.include?('java')
|
14
|
-
BSON_IMPL = BSON::BSON_JAVA
|
15
|
-
else
|
16
|
-
BSON_IMPL = BSON::BSON_C
|
17
|
-
end
|
18
|
-
|
19
|
-
OBJECT_STRUCTURE = {'x' => ['y', 34, 2**30 + 3, 2.1223423423356, {'hello' => 'world', '5' => [63, 'asjdl']}]}
|
20
|
-
ENCODED_MSGPACK = "\x81\xA1x\x95\xA1y\"\xCE@\x00\x00\x03\xCB@\x00\xFA\x8E\x9F9\xFA\xC1\x82\xA5hello\xA5world\xA15\x92?\xA5asjdl"
|
21
|
-
ENCODED_BSON = "d\x00\x00\x00\x04x\x00\\\x00\x00\x00\x020\x00\x02\x00\x00\x00y\x00\x101\x00\"\x00\x00\x00\x102\x00\x03\x00\x00@\x013\x00\xC1\xFA9\x9F\x8E\xFA\x00@\x034\x002\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x045\x00\x19\x00\x00\x00\x100\x00?\x00\x00\x00\x021\x00\x06\x00\x00\x00asjdl\x00\x00\x00\x00\x00"
|
22
|
-
ENCODED_JSON = '{"x":["y",34,1073741827,2.1223423423356,{"hello":"world","5":[63,"asjdl"]}]}'
|
23
|
-
ITERATIONS = 1_00_000
|
24
|
-
IMPLEMENTATIONS = ENV.fetch('IMPLEMENTATIONS', 'json,bson,msgpack').split(',').map(&:to_sym)
|
25
|
-
|
26
|
-
Viiite.bm do |b|
|
27
|
-
b.variation_point :ruby, Viiite.which_ruby
|
28
|
-
|
29
|
-
IMPLEMENTATIONS.each do |lib|
|
30
|
-
b.variation_point :lib, lib
|
31
|
-
|
32
|
-
|
33
|
-
b.report(:pack) do
|
34
|
-
ITERATIONS.times do
|
35
|
-
case lib
|
36
|
-
when :msgpack then MessagePack.pack(OBJECT_STRUCTURE)
|
37
|
-
when :bson then BSON_IMPL.serialize(OBJECT_STRUCTURE).to_s
|
38
|
-
when :json then OBJECT_STRUCTURE.to_json
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
b.report(:unpack) do
|
44
|
-
ITERATIONS.times do
|
45
|
-
case lib
|
46
|
-
when :msgpack then MessagePack.unpack(ENCODED_MSGPACK)
|
47
|
-
when :bson then BSON_IMPL.deserialize(ENCODED_BSON)
|
48
|
-
when :json then JSON.parse(ENCODED_JSON)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
b.report(:pack_unpack) do
|
54
|
-
ITERATIONS.times do
|
55
|
-
case lib
|
56
|
-
when :msgpack then MessagePack.unpack(MessagePack.pack(OBJECT_STRUCTURE))
|
57
|
-
when :bson then BSON_IMPL.deserialize(BSON_IMPL.serialize(OBJECT_STRUCTURE).to_s)
|
58
|
-
when :json then JSON.parse(OBJECT_STRUCTURE.to_json)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
b.report(:unpack_pack) do
|
64
|
-
ITERATIONS.times do
|
65
|
-
case lib
|
66
|
-
when :msgpack then MessagePack.pack(MessagePack.unpack(ENCODED_MSGPACK))
|
67
|
-
when :bson then BSON_IMPL.serialize(BSON_IMPL.deserialize(ENCODED_BSON)).to_s
|
68
|
-
when :json then OBJECT_STRUCTURE.to_json(JSON.parse(ENCODED_JSON))
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
$: << File.expand_path('../../../lib', __FILE__)
|
4
|
-
|
5
|
-
require 'viiite'
|
6
|
-
require 'msgpack'
|
7
|
-
|
8
|
-
|
9
|
-
iterations = 10_000
|
10
|
-
data = MessagePack.pack(:hello => 'world', :nested => ['structure', {:value => 42}])
|
11
|
-
|
12
|
-
Viiite.bm do |b|
|
13
|
-
b.report(:strings) do
|
14
|
-
iterations.times do
|
15
|
-
MessagePack.unpack(data)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
b.report(:symbols) do
|
20
|
-
options = {:symbolize_keys => true}
|
21
|
-
iterations.times do
|
22
|
-
MessagePack.unpack(data, options)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/spec/jruby/unpacker_spec.rb
DELETED
@@ -1,186 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
|
-
require 'stringio'
|
4
|
-
require 'tempfile'
|
5
|
-
|
6
|
-
require 'spec_helper'
|
7
|
-
|
8
|
-
describe MessagePack::Unpacker do
|
9
|
-
let :unpacker do
|
10
|
-
MessagePack::Unpacker.new
|
11
|
-
end
|
12
|
-
|
13
|
-
let :packer do
|
14
|
-
MessagePack::Packer.new
|
15
|
-
end
|
16
|
-
|
17
|
-
let :buffer1 do
|
18
|
-
MessagePack.pack(:foo => 'bar')
|
19
|
-
end
|
20
|
-
|
21
|
-
let :buffer2 do
|
22
|
-
MessagePack.pack(:hello => {:world => [1, 2, 3]})
|
23
|
-
end
|
24
|
-
|
25
|
-
let :buffer3 do
|
26
|
-
MessagePack.pack(:x => 'y')
|
27
|
-
end
|
28
|
-
|
29
|
-
describe '#execute/#execute_limit/#finished?' do
|
30
|
-
let :buffer do
|
31
|
-
buffer1 + buffer2 + buffer3
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'extracts an object from the buffer' do
|
35
|
-
subject.execute(buffer, 0)
|
36
|
-
subject.data.should == {'foo' => 'bar'}
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'extracts an object from the buffer, starting at an offset' do
|
40
|
-
subject.execute(buffer, buffer1.length)
|
41
|
-
subject.data.should == {'hello' => {'world' => [1, 2, 3]}}
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'extracts an object from the buffer, starting at an offset reading bytes up to a limit' do
|
45
|
-
subject.execute_limit(buffer, buffer1.length, buffer2.length)
|
46
|
-
subject.data.should == {'hello' => {'world' => [1, 2, 3]}}
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'extracts nothing if the limit cuts an object in half' do
|
50
|
-
subject.execute_limit(buffer, buffer1.length, 3)
|
51
|
-
subject.data.should be_nil
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'returns the offset where the object ended' do
|
55
|
-
subject.execute(buffer, 0).should == buffer1.length
|
56
|
-
subject.execute(buffer, buffer1.length).should == buffer1.length + buffer2.length
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'is finished if #data returns an object' do
|
60
|
-
subject.execute_limit(buffer, buffer1.length, buffer2.length)
|
61
|
-
subject.should be_finished
|
62
|
-
|
63
|
-
subject.execute_limit(buffer, buffer1.length, 3)
|
64
|
-
subject.should_not be_finished
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe '#each' do
|
69
|
-
context 'with a StringIO stream' do
|
70
|
-
it 'yields each object in the stream' do
|
71
|
-
objects = []
|
72
|
-
subject.stream = StringIO.new(buffer1 + buffer2 + buffer3)
|
73
|
-
subject.each do |obj|
|
74
|
-
objects << obj
|
75
|
-
end
|
76
|
-
objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
context 'with a File stream' do
|
81
|
-
it 'yields each object in the stream' do
|
82
|
-
objects = []
|
83
|
-
file = Tempfile.new('msgpack')
|
84
|
-
file.write(buffer1)
|
85
|
-
file.write(buffer2)
|
86
|
-
file.write(buffer3)
|
87
|
-
file.open
|
88
|
-
subject.stream = file
|
89
|
-
subject.each do |obj|
|
90
|
-
objects << obj
|
91
|
-
end
|
92
|
-
objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
describe '#fill' do
|
98
|
-
it 'is a no-op' do
|
99
|
-
subject.stream = StringIO.new(buffer1 + buffer2 + buffer3)
|
100
|
-
subject.fill
|
101
|
-
subject.each { |obj| }
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def flatten(struct, results = [])
|
106
|
-
case struct
|
107
|
-
when Array
|
108
|
-
struct.each { |v| flatten(v, results) }
|
109
|
-
when Hash
|
110
|
-
struct.each { |k, v| flatten(v, flatten(k, results)) }
|
111
|
-
else
|
112
|
-
results << struct
|
113
|
-
end
|
114
|
-
results
|
115
|
-
end
|
116
|
-
|
117
|
-
context 'encoding', :encodings do
|
118
|
-
before :all do
|
119
|
-
@default_internal = Encoding.default_internal
|
120
|
-
@default_external = Encoding.default_external
|
121
|
-
end
|
122
|
-
|
123
|
-
after :all do
|
124
|
-
Encoding.default_internal = @default_internal
|
125
|
-
Encoding.default_external = @default_external
|
126
|
-
end
|
127
|
-
|
128
|
-
let :buffer do
|
129
|
-
MessagePack.pack({'hello' => 'world', 'nested' => ['object', {"sk\xC3\xA5l".force_encoding('utf-8') => true}]})
|
130
|
-
end
|
131
|
-
|
132
|
-
let :unpacker do
|
133
|
-
described_class.new
|
134
|
-
end
|
135
|
-
|
136
|
-
before do
|
137
|
-
Encoding.default_internal = Encoding::UTF_8
|
138
|
-
Encoding.default_external = Encoding::ISO_8859_1
|
139
|
-
end
|
140
|
-
|
141
|
-
it 'produces results with encoding as binary or string(utf8)' do
|
142
|
-
unpacker.execute(buffer, 0)
|
143
|
-
strings = flatten(unpacker.data).grep(String)
|
144
|
-
strings.map(&:encoding).uniq.sort{|a,b| a.to_s <=> b.to_s}.should == [Encoding::ASCII_8BIT, Encoding::UTF_8]
|
145
|
-
end
|
146
|
-
|
147
|
-
it 'recodes to internal encoding' do
|
148
|
-
unpacker.execute(buffer, 0)
|
149
|
-
unpacker.data['nested'][1].keys.should == ["sk\xC3\xA5l".force_encoding(Encoding::UTF_8)]
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
context 'extensions' do
|
154
|
-
context 'symbolized keys' do
|
155
|
-
let :buffer do
|
156
|
-
MessagePack.pack({'hello' => 'world', 'nested' => ['object', {'structure' => true}]})
|
157
|
-
end
|
158
|
-
|
159
|
-
let :unpacker do
|
160
|
-
described_class.new(:symbolize_keys => true)
|
161
|
-
end
|
162
|
-
|
163
|
-
it 'can symbolize keys when using #execute' do
|
164
|
-
unpacker.execute(buffer, 0)
|
165
|
-
unpacker.data.should == {:hello => 'world', :nested => ['object', {:structure => true}]}
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
context 'encoding', :encodings do
|
170
|
-
let :buffer do
|
171
|
-
MessagePack.pack({'hello' => 'world', 'nested' => ['object', {'structure' => true}]})
|
172
|
-
end
|
173
|
-
|
174
|
-
let :unpacker do
|
175
|
-
described_class.new()
|
176
|
-
end
|
177
|
-
|
178
|
-
it 'decode binary as ascii-8bit string when using #execute' do
|
179
|
-
unpacker.execute(buffer, 0)
|
180
|
-
strings = flatten(unpacker.data).grep(String)
|
181
|
-
strings.should == %w[hello world nested object structure]
|
182
|
-
strings.map(&:encoding).uniq.should == [Encoding::ASCII_8BIT]
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|