msgpack 1.4.2 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +85 -0
  3. data/README.md +52 -1
  4. data/ext/java/org/msgpack/jruby/Buffer.java +26 -19
  5. data/ext/java/org/msgpack/jruby/Decoder.java +29 -21
  6. data/ext/java/org/msgpack/jruby/Encoder.java +68 -30
  7. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +43 -64
  8. data/ext/java/org/msgpack/jruby/ExtensionValue.java +6 -9
  9. data/ext/java/org/msgpack/jruby/Factory.java +43 -42
  10. data/ext/java/org/msgpack/jruby/Packer.java +37 -40
  11. data/ext/java/org/msgpack/jruby/Unpacker.java +80 -73
  12. data/ext/msgpack/buffer.c +54 -74
  13. data/ext/msgpack/buffer.h +21 -18
  14. data/ext/msgpack/buffer_class.c +161 -52
  15. data/ext/msgpack/buffer_class.h +1 -0
  16. data/ext/msgpack/compat.h +0 -99
  17. data/ext/msgpack/extconf.rb +25 -46
  18. data/ext/msgpack/factory_class.c +143 -87
  19. data/ext/msgpack/packer.c +66 -43
  20. data/ext/msgpack/packer.h +25 -20
  21. data/ext/msgpack/packer_class.c +102 -130
  22. data/ext/msgpack/packer_class.h +11 -0
  23. data/ext/msgpack/packer_ext_registry.c +35 -40
  24. data/ext/msgpack/packer_ext_registry.h +41 -38
  25. data/ext/msgpack/rbinit.c +1 -1
  26. data/ext/msgpack/rmem.c +3 -4
  27. data/ext/msgpack/sysdep.h +5 -2
  28. data/ext/msgpack/unpacker.c +126 -108
  29. data/ext/msgpack/unpacker.h +16 -13
  30. data/ext/msgpack/unpacker_class.c +86 -126
  31. data/ext/msgpack/unpacker_class.h +11 -0
  32. data/ext/msgpack/unpacker_ext_registry.c +40 -28
  33. data/ext/msgpack/unpacker_ext_registry.h +21 -18
  34. data/lib/msgpack/bigint.rb +69 -0
  35. data/lib/msgpack/buffer.rb +9 -0
  36. data/lib/msgpack/factory.rb +140 -10
  37. data/lib/msgpack/packer.rb +10 -1
  38. data/lib/msgpack/symbol.rb +21 -4
  39. data/lib/msgpack/time.rb +1 -1
  40. data/lib/msgpack/unpacker.rb +14 -1
  41. data/lib/msgpack/version.rb +1 -1
  42. data/lib/msgpack.rb +6 -7
  43. data/msgpack.gemspec +8 -5
  44. metadata +37 -82
  45. data/.gitignore +0 -23
  46. data/.rubocop.yml +0 -36
  47. data/.travis.yml +0 -39
  48. data/Gemfile +0 -9
  49. data/Rakefile +0 -71
  50. data/appveyor.yml +0 -18
  51. data/bench/pack.rb +0 -23
  52. data/bench/pack_log.rb +0 -33
  53. data/bench/pack_log_long.rb +0 -65
  54. data/bench/pack_symbols.rb +0 -28
  55. data/bench/run.sh +0 -14
  56. data/bench/run_long.sh +0 -35
  57. data/bench/run_symbols.sh +0 -26
  58. data/bench/unpack.rb +0 -21
  59. data/bench/unpack_log.rb +0 -34
  60. data/bench/unpack_log_long.rb +0 -67
  61. data/doclib/msgpack/buffer.rb +0 -193
  62. data/doclib/msgpack/core_ext.rb +0 -101
  63. data/doclib/msgpack/error.rb +0 -19
  64. data/doclib/msgpack/extension_value.rb +0 -9
  65. data/doclib/msgpack/factory.rb +0 -101
  66. data/doclib/msgpack/packer.rb +0 -208
  67. data/doclib/msgpack/time.rb +0 -22
  68. data/doclib/msgpack/timestamp.rb +0 -44
  69. data/doclib/msgpack/unpacker.rb +0 -183
  70. data/doclib/msgpack.rb +0 -87
  71. data/msgpack.org.md +0 -46
  72. data/spec/cases.json +0 -1
  73. data/spec/cases.msg +0 -0
  74. data/spec/cases_compact.msg +0 -0
  75. data/spec/cases_spec.rb +0 -39
  76. data/spec/cruby/buffer_io_spec.rb +0 -255
  77. data/spec/cruby/buffer_packer.rb +0 -29
  78. data/spec/cruby/buffer_spec.rb +0 -575
  79. data/spec/cruby/buffer_unpacker.rb +0 -19
  80. data/spec/cruby/unpacker_spec.rb +0 -70
  81. data/spec/ext_value_spec.rb +0 -99
  82. data/spec/exttypes.rb +0 -51
  83. data/spec/factory_spec.rb +0 -367
  84. data/spec/format_spec.rb +0 -301
  85. data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
  86. data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
  87. data/spec/jruby/unpacker_spec.rb +0 -186
  88. data/spec/msgpack_spec.rb +0 -214
  89. data/spec/pack_spec.rb +0 -61
  90. data/spec/packer_spec.rb +0 -557
  91. data/spec/random_compat.rb +0 -24
  92. data/spec/spec_helper.rb +0 -55
  93. data/spec/timestamp_spec.rb +0 -121
  94. data/spec/unpack_spec.rb +0 -57
  95. data/spec/unpacker_spec.rb +0 -819
@@ -1,99 +0,0 @@
1
- # encoding: ascii-8bit
2
- require 'spec_helper'
3
-
4
- describe MessagePack::ExtensionValue do
5
- subject do
6
- described_class.new(1, "data")
7
- end
8
-
9
- describe '#type/#type=' do
10
- it 'returns value set by #initialize' do
11
- subject.type.should == 1
12
- end
13
-
14
- it 'assigns a value' do
15
- subject.type = 2
16
- subject.type.should == 2
17
- end
18
- end
19
-
20
- describe '#payload/#payload=' do
21
- it 'returns value set by #initialize' do
22
- subject.payload.should == "data"
23
- end
24
-
25
- it 'assigns a value' do
26
- subject.payload = "a"
27
- subject.payload.should == "a"
28
- end
29
- end
30
-
31
- describe '#==/#eql?/#hash' do
32
- it 'returns equivalent if the content is same' do
33
- ext1 = MessagePack::ExtensionValue.new(1, "data")
34
- ext2 = MessagePack::ExtensionValue.new(1, "data")
35
- (ext1 == ext2).should be true
36
- ext1.eql?(ext2).should be true
37
- (ext1.hash == ext2.hash).should be true
38
- end
39
-
40
- it 'returns not equivalent if type is not same' do
41
- ext1 = MessagePack::ExtensionValue.new(1, "data")
42
- ext2 = MessagePack::ExtensionValue.new(2, "data")
43
- (ext1 == ext2).should be false
44
- ext1.eql?(ext2).should be false
45
- (ext1.hash == ext2.hash).should be false
46
- end
47
-
48
- it 'returns not equivalent if payload is not same' do
49
- ext1 = MessagePack::ExtensionValue.new(1, "data")
50
- ext2 = MessagePack::ExtensionValue.new(1, "value")
51
- (ext1 == ext2).should be false
52
- ext1.eql?(ext2).should be false
53
- (ext1.hash == ext2.hash).should be false
54
- end
55
- end
56
-
57
- describe '#to_msgpack' do
58
- it 'serializes very short payload' do
59
- ext = MessagePack::ExtensionValue.new(1, "a"*2).to_msgpack
60
- ext.should == "\xd5\x01" + "a"*2
61
- end
62
-
63
- it 'serializes short payload' do
64
- ext = MessagePack::ExtensionValue.new(1, "a"*18).to_msgpack
65
- ext.should == "\xc7\x12\x01" + "a"*18
66
- end
67
-
68
- it 'serializes long payload' do
69
- ext = MessagePack::ExtensionValue.new(1, "a"*65540).to_msgpack
70
- ext.should == "\xc9\x00\x01\x00\x04\x01" + "a"*65540
71
- end
72
-
73
- it 'with a packer serializes to a packer' do
74
- ext = MessagePack::ExtensionValue.new(1, "aa")
75
- packer = MessagePack::Packer.new
76
- ext.to_msgpack(packer)
77
- packer.buffer.to_s.should == "\xd5\x01aa"
78
- end
79
-
80
- [-129, -65540, -(2**40), 128, 65540, 2**40].each do |type|
81
- context "with invalid type (#{type})" do
82
- it 'raises RangeError' do
83
- lambda { MessagePack::ExtensionValue.new(type, "a").to_msgpack }.should raise_error(RangeError)
84
- end
85
- end
86
- end
87
- end
88
-
89
- describe '#dup' do
90
- it 'duplicates' do
91
- ext1 = MessagePack::ExtensionValue.new(1, "data")
92
- ext2 = ext1.dup
93
- ext2.type = 2
94
- ext2.payload = "data2"
95
- ext1.type.should == 1
96
- ext1.payload.should == "data"
97
- end
98
- end
99
- end
data/spec/exttypes.rb DELETED
@@ -1,51 +0,0 @@
1
- class DummyTimeStamp1
2
- TYPE = 15
3
-
4
- attr_reader :utime, :usec, :time
5
-
6
- def initialize(utime, usec)
7
- @utime = utime
8
- @usec = usec
9
- @time = Time.at(utime, usec)
10
- end
11
-
12
- def ==(other)
13
- self.utime == other.utime && self.usec == other.usec
14
- end
15
-
16
- def self.type_id
17
- 15
18
- end
19
-
20
- def self.from_msgpack_ext(data)
21
- new(*data.unpack('I*'))
22
- end
23
-
24
- def to_msgpack_ext
25
- [@utime,@usec].pack('I*')
26
- end
27
- end
28
-
29
- class DummyTimeStamp2
30
- TYPE = 16
31
-
32
- attr_reader :utime, :usec, :time
33
-
34
- def initialize(utime, usec)
35
- @utime = utime
36
- @usec = usec
37
- @time = Time.at(utime, usec)
38
- end
39
-
40
- def ==(other)
41
- self.utime == other.utime && self.usec == other.usec
42
- end
43
-
44
- def self.deserialize(data)
45
- new(* data.split(',', 2).map(&:to_i))
46
- end
47
-
48
- def serialize
49
- [@utime,@usec].map(&:to_s).join(',')
50
- end
51
- end
data/spec/factory_spec.rb DELETED
@@ -1,367 +0,0 @@
1
- # encoding: ascii-8bit
2
- require 'spec_helper'
3
-
4
- describe MessagePack::Factory do
5
- subject do
6
- described_class.new
7
- end
8
-
9
- describe '#packer' do
10
- it 'creates a Packer instance' do
11
- subject.packer.should be_kind_of(MessagePack::Packer)
12
- end
13
-
14
- it 'creates new instance' do
15
- subject.packer.object_id.should_not == subject.packer.object_id
16
- end
17
- end
18
-
19
- describe '#unpacker' do
20
- it 'creates a Unpacker instance' do
21
- subject.unpacker.should be_kind_of(MessagePack::Unpacker)
22
- end
23
-
24
- it 'creates new instance' do
25
- subject.unpacker.object_id.should_not == subject.unpacker.object_id
26
- end
27
-
28
- it 'creates unpacker with symbolize_keys option' do
29
- unpacker = subject.unpacker(symbolize_keys: true)
30
- unpacker.feed(MessagePack.pack({'k'=>'v'}))
31
- unpacker.read.should == {:k => 'v'}
32
- end
33
-
34
- it 'creates unpacker with allow_unknown_ext option' do
35
- unpacker = subject.unpacker(allow_unknown_ext: true)
36
- unpacker.feed(MessagePack::ExtensionValue.new(1, 'a').to_msgpack)
37
- unpacker.read.should == MessagePack::ExtensionValue.new(1, 'a')
38
- end
39
-
40
- it 'creates unpacker without allow_unknown_ext option' do
41
- unpacker = subject.unpacker
42
- unpacker.feed(MessagePack::ExtensionValue.new(1, 'a').to_msgpack)
43
- expect{ unpacker.read }.to raise_error(MessagePack::UnknownExtTypeError)
44
- end
45
- end
46
-
47
- describe '#dump and #load' do
48
- it 'can be used like a standard coder' do
49
- subject.register_type(0x00, Symbol)
50
- expect(subject.load(subject.dump(:symbol))).to be == :symbol
51
- end
52
-
53
- it 'is alias as pack and unpack' do
54
- subject.register_type(0x00, Symbol)
55
- expect(subject.unpack(subject.pack(:symbol))).to be == :symbol
56
- end
57
-
58
- it 'accept options' do
59
- hash = subject.unpack(MessagePack.pack('k' => 'v'), symbolize_keys: true)
60
- expect(hash).to be == { k: 'v' }
61
- end
62
- end
63
-
64
- describe '#freeze' do
65
- it 'can freeze factory instance to deny new registrations anymore' do
66
- subject.register_type(0x00, Symbol)
67
- subject.freeze
68
- expect(subject.frozen?).to be_truthy
69
- expect{ subject.register_type(0x01, Array) }.to raise_error(RuntimeError, "can't modify frozen Factory")
70
- end
71
- end
72
-
73
- class MyType
74
- def initialize(a, b)
75
- @a = a
76
- @b = b
77
- end
78
-
79
- attr_reader :a, :b
80
-
81
- def to_msgpack_ext
82
- [a, b].pack('CC')
83
- end
84
-
85
- def self.from_msgpack_ext(data)
86
- new(*data.unpack('CC'))
87
- end
88
-
89
- def to_msgpack_ext_only_a
90
- [a, 0].pack('CC')
91
- end
92
-
93
- def self.from_msgpack_ext_only_b(data)
94
- a, b = *data.unpack('CC')
95
- new(0, b)
96
- end
97
- end
98
-
99
- class MyType2 < MyType
100
- end
101
-
102
- describe '#registered_types' do
103
- it 'returns Array' do
104
- expect(subject.registered_types).to be_instance_of(Array)
105
- end
106
-
107
- it 'returns Array of Hash contains :type, :class, :packer, :unpacker' do
108
- subject.register_type(0x20, ::MyType)
109
- subject.register_type(0x21, ::MyType2)
110
-
111
- list = subject.registered_types
112
-
113
- expect(list.size).to eq(2)
114
- expect(list[0]).to be_instance_of(Hash)
115
- expect(list[1]).to be_instance_of(Hash)
116
- expect(list[0].keys.sort).to eq([:type, :class, :packer, :unpacker].sort)
117
- expect(list[1].keys.sort).to eq([:type, :class, :packer, :unpacker].sort)
118
-
119
- expect(list[0][:type]).to eq(0x20)
120
- expect(list[0][:class]).to eq(::MyType)
121
- expect(list[0][:packer]).to eq(:to_msgpack_ext)
122
- expect(list[0][:unpacker]).to eq(:from_msgpack_ext)
123
-
124
- expect(list[1][:type]).to eq(0x21)
125
- expect(list[1][:class]).to eq(::MyType2)
126
- expect(list[1][:packer]).to eq(:to_msgpack_ext)
127
- expect(list[1][:unpacker]).to eq(:from_msgpack_ext)
128
- end
129
-
130
- it 'returns Array of Hash which has nil for unregistered feature' do
131
- subject.register_type(0x21, ::MyType2, unpacker: :from_msgpack_ext)
132
- subject.register_type(0x20, ::MyType, packer: :to_msgpack_ext)
133
-
134
- list = subject.registered_types
135
-
136
- expect(list.size).to eq(2)
137
- expect(list[0]).to be_instance_of(Hash)
138
- expect(list[1]).to be_instance_of(Hash)
139
- expect(list[0].keys.sort).to eq([:type, :class, :packer, :unpacker].sort)
140
- expect(list[1].keys.sort).to eq([:type, :class, :packer, :unpacker].sort)
141
-
142
- expect(list[0][:type]).to eq(0x20)
143
- expect(list[0][:class]).to eq(::MyType)
144
- expect(list[0][:packer]).to eq(:to_msgpack_ext)
145
- expect(list[0][:unpacker]).to be_nil
146
-
147
- expect(list[1][:type]).to eq(0x21)
148
- expect(list[1][:class]).to eq(::MyType2)
149
- expect(list[1][:packer]).to be_nil
150
- expect(list[1][:unpacker]).to eq(:from_msgpack_ext)
151
- end
152
- end
153
-
154
- describe '#type_registered?' do
155
- it 'receive Class or Integer, and return bool' do
156
- expect(subject.type_registered?(0x00)).to be_falsy
157
- expect(subject.type_registered?(0x01)).to be_falsy
158
- expect(subject.type_registered?(::MyType)).to be_falsy
159
- end
160
-
161
- it 'has option to specify what types are registered for' do
162
- expect(subject.type_registered?(0x00, :both)).to be_falsy
163
- expect(subject.type_registered?(0x00, :packer)).to be_falsy
164
- expect(subject.type_registered?(0x00, :unpacker)).to be_falsy
165
- expect{ subject.type_registered?(0x00, :something) }.to raise_error(ArgumentError)
166
- end
167
-
168
- it 'returns true if specified type or class is already registered' do
169
- subject.register_type(0x20, ::MyType)
170
- subject.register_type(0x21, ::MyType2)
171
-
172
- expect(subject.type_registered?(0x00)).to be_falsy
173
- expect(subject.type_registered?(0x01)).to be_falsy
174
-
175
- expect(subject.type_registered?(0x20)).to be_truthy
176
- expect(subject.type_registered?(0x21)).to be_truthy
177
- expect(subject.type_registered?(::MyType)).to be_truthy
178
- expect(subject.type_registered?(::MyType2)).to be_truthy
179
- end
180
- end
181
-
182
- describe '#register_type' do
183
- let :src do
184
- ::MyType.new(1, 2)
185
- end
186
-
187
- it 'registers #to_msgpack_ext and .from_msgpack_ext by default' do
188
- subject.register_type(0x7f, ::MyType)
189
-
190
- data = subject.packer.write(src).to_s
191
- my = subject.unpacker.feed(data).read
192
- my.a.should == 1
193
- my.b.should == 2
194
- end
195
-
196
- it 'registers custom packer method name' do
197
- subject.register_type(0x7f, ::MyType, packer: :to_msgpack_ext_only_a, unpacker: :from_msgpack_ext)
198
-
199
- data = subject.packer.write(src).to_s
200
- my = subject.unpacker.feed(data).read
201
- my.a.should == 1
202
- my.b.should == 0
203
- end
204
-
205
- it 'registers custom unpacker method name' do
206
- subject.register_type(0x7f, ::MyType, packer: :to_msgpack_ext, unpacker: 'from_msgpack_ext_only_b')
207
-
208
- data = subject.packer.write(src).to_s
209
- my = subject.unpacker.feed(data).read
210
- my.a.should == 0
211
- my.b.should == 2
212
- end
213
-
214
- it 'registers custom proc objects' do
215
- pk = lambda {|obj| [obj.a + obj.b].pack('C') }
216
- uk = lambda {|data| ::MyType.new(data.unpack('C').first, -1) }
217
- subject.register_type(0x7f, ::MyType, packer: pk, unpacker: uk)
218
-
219
- data = subject.packer.write(src).to_s
220
- my = subject.unpacker.feed(data).read
221
- my.a.should == 3
222
- my.b.should == -1
223
- end
224
-
225
- it 'does not affect existent packer and unpackers' do
226
- subject.register_type(0x7f, ::MyType)
227
- packer = subject.packer
228
- unpacker = subject.unpacker
229
-
230
- subject.register_type(0x7f, ::MyType, packer: :to_msgpack_ext_only_a, unpacker: :from_msgpack_ext_only_b)
231
-
232
- data = packer.write(src).to_s
233
- my = unpacker.feed(data).read
234
- my.a.should == 1
235
- my.b.should == 2
236
- end
237
-
238
- describe "registering an ext type for a module" do
239
- before do
240
- mod = Module.new do
241
- def self.from_msgpack_ext(data)
242
- "unpacked #{data}"
243
- end
244
-
245
- def to_msgpack_ext
246
- 'value_msgpacked'
247
- end
248
- end
249
- stub_const('Mod', mod)
250
- end
251
- let(:factory) { described_class.new }
252
- before { factory.register_type(0x01, Mod) }
253
-
254
- describe "packing an object whose class included the module" do
255
- subject { factory.packer.pack(value).to_s }
256
- before { stub_const('Value', Class.new{ include Mod }) }
257
- let(:value) { Value.new }
258
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
259
- end
260
-
261
- describe "packing an object which has been extended by the module" do
262
- subject { factory.packer.pack(object).to_s }
263
- let(:object) { Object.new.extend Mod }
264
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
265
- end
266
-
267
- describe "unpacking with the module" do
268
- subject { factory.unpacker.feed("\xC7\x06\x01module").unpack }
269
- it { is_expected.to eq "unpacked module" }
270
- end
271
- end
272
- end
273
-
274
- describe 'the special treatment of symbols with ext type' do
275
- let(:packer) { subject.packer }
276
- let(:unpacker) { subject.unpacker }
277
-
278
- def symbol_after_roundtrip
279
- packed_symbol = packer.pack(:symbol).to_s
280
- unpacker.feed(packed_symbol).unpack
281
- end
282
-
283
- context 'if no ext type is registered for symbols' do
284
- it 'converts symbols to string' do
285
- expect(symbol_after_roundtrip).to eq 'symbol'
286
- end
287
- end
288
-
289
- context 'if an ext type is registered for symbols' do
290
- context 'if using the default serializer' do
291
- before { subject.register_type(0x00, ::Symbol) }
292
-
293
- it 'lets symbols survive a roundtrip' do
294
- expect(symbol_after_roundtrip).to be :symbol
295
- end
296
- end
297
-
298
- context 'if using a custom serializer' do
299
- before do
300
- class Symbol
301
- alias_method :to_msgpack_ext_orig, :to_msgpack_ext
302
- def to_msgpack_ext
303
- self.to_s.codepoints.to_a.pack('n*')
304
- end
305
- end
306
-
307
- class << Symbol
308
- alias_method :from_msgpack_ext_orig, :from_msgpack_ext
309
- def from_msgpack_ext(data)
310
- data.unpack('n*').map(&:chr).join.to_sym
311
- end
312
- end
313
- end
314
-
315
- before { subject.register_type(0x00, ::Symbol) }
316
-
317
- it 'lets symbols survive a roundtrip' do
318
- expect(symbol_after_roundtrip).to be :symbol
319
- end
320
-
321
- after do
322
- class Symbol
323
- alias_method :to_msgpack_ext, :to_msgpack_ext_orig
324
- end
325
-
326
- class << Symbol
327
- alias_method :from_msgpack_ext, :from_msgpack_ext_orig
328
- end
329
- end
330
- end
331
- end
332
- end
333
-
334
- describe 'under stressful GC' do
335
- it 'works well' do
336
- begin
337
- GC.stress = true
338
-
339
- f = MessagePack::Factory.new
340
- f.register_type(0x0a, Symbol)
341
- ensure
342
- GC.stress = false
343
- end
344
- end
345
- end
346
-
347
- describe 'DefaultFactory' do
348
- it 'is a factory' do
349
- MessagePack::DefaultFactory.should be_kind_of(MessagePack::Factory)
350
- end
351
-
352
- require_relative 'exttypes'
353
-
354
- it 'should be referred by MessagePack.pack and MessagePack.unpack' do
355
- MessagePack::DefaultFactory.register_type(DummyTimeStamp1::TYPE, DummyTimeStamp1)
356
- MessagePack::DefaultFactory.register_type(DummyTimeStamp2::TYPE, DummyTimeStamp2, packer: :serialize, unpacker: :deserialize)
357
-
358
- t = Time.now
359
-
360
- dm1 = DummyTimeStamp1.new(t.to_i, t.usec)
361
- expect(MessagePack.unpack(MessagePack.pack(dm1))).to eq(dm1)
362
-
363
- dm2 = DummyTimeStamp1.new(t.to_i, t.usec)
364
- expect(MessagePack.unpack(MessagePack.pack(dm2))).to eq(dm2)
365
- end
366
- end
367
- end