msgpack 1.4.5 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yaml +5 -5
- data/ChangeLog +14 -0
- data/README.md +22 -0
- data/doclib/msgpack/factory.rb +45 -2
- data/ext/java/org/msgpack/jruby/Buffer.java +6 -0
- data/ext/java/org/msgpack/jruby/Decoder.java +23 -19
- data/ext/java/org/msgpack/jruby/Encoder.java +46 -18
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +24 -31
- data/ext/java/org/msgpack/jruby/Factory.java +40 -5
- data/ext/java/org/msgpack/jruby/Packer.java +21 -11
- data/ext/java/org/msgpack/jruby/Unpacker.java +44 -22
- data/ext/msgpack/buffer_class.c +12 -3
- data/ext/msgpack/factory_class.c +62 -5
- data/ext/msgpack/packer.c +42 -5
- data/ext/msgpack/packer.h +24 -0
- data/ext/msgpack/packer_class.c +22 -19
- data/ext/msgpack/packer_ext_registry.c +13 -4
- data/ext/msgpack/packer_ext_registry.h +10 -5
- data/ext/msgpack/unpacker.c +59 -19
- data/ext/msgpack/unpacker_class.c +14 -5
- data/ext/msgpack/unpacker_ext_registry.c +3 -2
- data/ext/msgpack/unpacker_ext_registry.h +5 -2
- data/lib/msgpack/bigint.rb +69 -0
- data/lib/msgpack/factory.rb +103 -0
- data/lib/msgpack/version.rb +1 -1
- data/lib/msgpack.rb +4 -5
- data/spec/bigint_spec.rb +26 -0
- data/spec/factory_spec.rb +220 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/timestamp_spec.rb +2 -2
- metadata +4 -2
data/spec/factory_spec.rb
CHANGED
@@ -283,6 +283,174 @@ describe MessagePack::Factory do
|
|
283
283
|
it { is_expected.to eq "unpacked module" }
|
284
284
|
end
|
285
285
|
end
|
286
|
+
|
287
|
+
describe "registering an ext type for Integer" do
|
288
|
+
let(:factory) { described_class.new }
|
289
|
+
let(:bigint) { 10**150 }
|
290
|
+
|
291
|
+
it 'does not work by default without passing `oversized_integer_extension: true`' do
|
292
|
+
factory.register_type(0x01, Integer, packer: :to_s, unpacker: method(:Integer))
|
293
|
+
|
294
|
+
expect do
|
295
|
+
factory.dump(bigint)
|
296
|
+
end.to raise_error RangeError
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'raises ArgumentError if the type is not Integer' do
|
300
|
+
expect do
|
301
|
+
factory.register_type(0x01, MyType, packer: :to_s, unpacker: method(:Integer), oversized_integer_extension: true)
|
302
|
+
end.to raise_error(ArgumentError)
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'invokes the packer if registered with `oversized_integer_extension: true`' do
|
306
|
+
factory.register_type(0x01, Integer, packer: :to_s, unpacker: method(:Integer), oversized_integer_extension: true)
|
307
|
+
|
308
|
+
expect(factory.load(factory.dump(bigint))).to be == bigint
|
309
|
+
end
|
310
|
+
|
311
|
+
it 'does not use the oversized_integer_extension packer for integers fitting in native types' do
|
312
|
+
factory.register_type(
|
313
|
+
0x01,
|
314
|
+
Integer,
|
315
|
+
packer: ->(int) { raise NotImplementedError },
|
316
|
+
unpacker: ->(payload) { raise NotImplementedError },
|
317
|
+
oversized_integer_extension: true
|
318
|
+
)
|
319
|
+
|
320
|
+
expect(factory.dump(42)).to eq(MessagePack.dump(42))
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
describe "registering ext type with recursive serialization" do
|
325
|
+
before do
|
326
|
+
stub_const("Point", Struct.new(:x, :y, :z))
|
327
|
+
end
|
328
|
+
|
329
|
+
it 'can receive the packer as argument (proc)' do
|
330
|
+
factory = MessagePack::Factory.new
|
331
|
+
factory.register_type(0x00, Symbol)
|
332
|
+
factory.register_type(
|
333
|
+
0x01,
|
334
|
+
Point,
|
335
|
+
packer: ->(point, packer) do
|
336
|
+
packer.write(point.to_h)
|
337
|
+
nil
|
338
|
+
end,
|
339
|
+
unpacker: ->(unpacker) do
|
340
|
+
attrs = unpacker.read
|
341
|
+
Point.new(attrs.fetch(:x), attrs.fetch(:y), attrs.fetch(:z))
|
342
|
+
end,
|
343
|
+
recursive: true,
|
344
|
+
)
|
345
|
+
|
346
|
+
point = Point.new(1, 2, 3)
|
347
|
+
payload = factory.dump(point)
|
348
|
+
expect(factory.load(payload)).to be == point
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'can receive the packer as argument (Method)' do
|
352
|
+
mod = Module.new
|
353
|
+
mod.define_singleton_method(:packer) do |point, packer|
|
354
|
+
packer.write(point.to_h)
|
355
|
+
nil
|
356
|
+
end
|
357
|
+
|
358
|
+
mod.define_singleton_method(:unpacker) do |unpacker|
|
359
|
+
attrs = unpacker.read
|
360
|
+
Point.new(attrs.fetch(:x), attrs.fetch(:y), attrs.fetch(:z))
|
361
|
+
end
|
362
|
+
|
363
|
+
factory = MessagePack::Factory.new
|
364
|
+
factory.register_type(0x00, Symbol)
|
365
|
+
factory.register_type(
|
366
|
+
0x01,
|
367
|
+
Point,
|
368
|
+
packer: mod.method(:packer),
|
369
|
+
unpacker: mod.method(:unpacker),
|
370
|
+
recursive: true,
|
371
|
+
)
|
372
|
+
|
373
|
+
point = Point.new(1, 2, 3)
|
374
|
+
payload = factory.dump(point)
|
375
|
+
expect(factory.load(payload)).to be == point
|
376
|
+
end
|
377
|
+
|
378
|
+
it 'respect message pack format' do
|
379
|
+
factory = MessagePack::Factory.new
|
380
|
+
factory.register_type(0x00, Symbol)
|
381
|
+
factory.register_type(
|
382
|
+
0x01,
|
383
|
+
Point,
|
384
|
+
packer: ->(point, packer) do
|
385
|
+
packer.write(point.to_a)
|
386
|
+
nil
|
387
|
+
end,
|
388
|
+
unpacker: ->(unpacker) do
|
389
|
+
attrs = unpacker.read
|
390
|
+
Point.new(*attrs)
|
391
|
+
end,
|
392
|
+
recursive: true,
|
393
|
+
)
|
394
|
+
|
395
|
+
point = Point.new(1, 2, 3)
|
396
|
+
expect(factory.dump(point)).to be == "\xD6\x01".b + MessagePack.dump([1, 2, 3])
|
397
|
+
end
|
398
|
+
|
399
|
+
it 'sets the correct length' do
|
400
|
+
factory = MessagePack::Factory.new
|
401
|
+
factory.register_type(0x00, Symbol)
|
402
|
+
factory.register_type(
|
403
|
+
0x01,
|
404
|
+
Point,
|
405
|
+
packer: ->(point, packer) do
|
406
|
+
packer.write(point.to_h)
|
407
|
+
nil
|
408
|
+
end,
|
409
|
+
unpacker: ->(unpacker) do
|
410
|
+
attrs = unpacker.read
|
411
|
+
Point.new(attrs.fetch(:x), attrs.fetch(:y), attrs.fetch(:z))
|
412
|
+
end,
|
413
|
+
recursive: true,
|
414
|
+
)
|
415
|
+
|
416
|
+
point = Point.new(1, 2, 3)
|
417
|
+
payload = factory.dump([1, point, 3])
|
418
|
+
|
419
|
+
obj = MessagePack::Factory.new.load(payload, allow_unknown_ext: true)
|
420
|
+
expect(obj).to be == [
|
421
|
+
1,
|
422
|
+
MessagePack::ExtensionValue.new(1, factory.dump(x: 1, y: 2, z: 3)),
|
423
|
+
3,
|
424
|
+
]
|
425
|
+
|
426
|
+
expect(factory.load(payload)).to be == [
|
427
|
+
1,
|
428
|
+
Point.new(1, 2, 3),
|
429
|
+
3,
|
430
|
+
]
|
431
|
+
end
|
432
|
+
|
433
|
+
it 'can be nested' do
|
434
|
+
factory = MessagePack::Factory.new
|
435
|
+
factory.register_type(
|
436
|
+
0x02,
|
437
|
+
Set,
|
438
|
+
packer: ->(set, packer) do
|
439
|
+
packer.write(set.to_a)
|
440
|
+
nil
|
441
|
+
end,
|
442
|
+
unpacker: ->(unpacker) do
|
443
|
+
unpacker.read.to_set
|
444
|
+
end,
|
445
|
+
recursive: true,
|
446
|
+
)
|
447
|
+
|
448
|
+
expected = Set[1, Set[2, Set[3]]]
|
449
|
+
payload = factory.dump(expected)
|
450
|
+
expect(payload).to be == "\xC7\v\x02\x92\x01\xC7\x06\x02\x92\x02\xD5\x02\x91\x03".b
|
451
|
+
expect(factory.load(factory.dump(expected))).to be == expected
|
452
|
+
end
|
453
|
+
end
|
286
454
|
end
|
287
455
|
|
288
456
|
describe 'the special treatment of symbols with ext type' do
|
@@ -437,4 +605,56 @@ describe MessagePack::Factory do
|
|
437
605
|
expect(MessagePack.unpack(MessagePack.pack(dm2))).to eq(dm2)
|
438
606
|
end
|
439
607
|
end
|
608
|
+
|
609
|
+
describe '#pool' do
|
610
|
+
let(:factory) { described_class.new }
|
611
|
+
|
612
|
+
it 'responds to serializers interface' do
|
613
|
+
pool = factory.pool(1)
|
614
|
+
expect(pool.load(pool.dump(42))).to be == 42
|
615
|
+
end
|
616
|
+
|
617
|
+
it 'types can be registered before the pool is created' do
|
618
|
+
factory.register_type(0x00, Symbol)
|
619
|
+
pool = factory.pool(1)
|
620
|
+
expect(pool.load(pool.dump(:foo))).to be == :foo
|
621
|
+
end
|
622
|
+
|
623
|
+
it 'types cannot be registered after the pool is created' do
|
624
|
+
pool = factory.pool(1)
|
625
|
+
factory.register_type(0x20, ::MyType)
|
626
|
+
|
627
|
+
expect do
|
628
|
+
pool.dump(MyType.new(1, 2))
|
629
|
+
end.to raise_error NoMethodError
|
630
|
+
|
631
|
+
payload = factory.dump(MyType.new(1, 2))
|
632
|
+
expect do
|
633
|
+
pool.load(payload)
|
634
|
+
end.to raise_error MessagePack::UnknownExtTypeError
|
635
|
+
end
|
636
|
+
|
637
|
+
it 'support symbolize_keys: true' do
|
638
|
+
pool = factory.pool(1, symbolize_keys: true)
|
639
|
+
expect(pool.load(pool.dump('foo' => 1))).to be == { foo: 1 }
|
640
|
+
end
|
641
|
+
|
642
|
+
it 'support freeze: true' do
|
643
|
+
pool = factory.pool(1, freeze: true)
|
644
|
+
expect(pool.load(pool.dump('foo'))).to be_frozen
|
645
|
+
end
|
646
|
+
|
647
|
+
it 'is thread safe' do
|
648
|
+
pool = factory.pool(1)
|
649
|
+
|
650
|
+
threads = 10.times.map do
|
651
|
+
Thread.new do
|
652
|
+
1_000.times do |i|
|
653
|
+
expect(pool.load(pool.dump(i))).to be == i
|
654
|
+
end
|
655
|
+
end
|
656
|
+
end
|
657
|
+
threads.each(&:join)
|
658
|
+
end
|
659
|
+
end
|
440
660
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "set"
|
1
2
|
|
2
3
|
if ENV['SIMPLE_COV']
|
3
4
|
require 'simplecov'
|
@@ -14,6 +15,7 @@ if ENV['GC_STRESS']
|
|
14
15
|
end
|
15
16
|
|
16
17
|
require 'msgpack'
|
18
|
+
require "msgpack/bigint"
|
17
19
|
|
18
20
|
if GC.respond_to?(:verify_compaction_references)
|
19
21
|
# This method was added in Ruby 3.0.0. Calling it this way asks the GC to
|
@@ -27,6 +29,8 @@ end
|
|
27
29
|
|
28
30
|
IS_JRUBY = RUBY_ENGINE == 'jruby'
|
29
31
|
|
32
|
+
IS_TRUFFLERUBY = RUBY_ENGINE == 'truffleruby'
|
33
|
+
|
30
34
|
# checking if Hash#[]= (rb_hash_aset) dedupes string keys
|
31
35
|
def automatic_string_keys_deduplication?
|
32
36
|
h = {}
|
data/spec/timestamp_spec.rb
CHANGED
@@ -87,14 +87,14 @@ describe MessagePack::Timestamp do
|
|
87
87
|
|
88
88
|
let(:time96_min) { Time.at(-2**63).utc }
|
89
89
|
it 'is serialized into timestamp96' do
|
90
|
-
skip if IS_JRUBY # JRuby
|
90
|
+
skip if IS_JRUBY || IS_TRUFFLERUBY # JRuby and TruffleRuby both use underlying Java time classes that do not support |year| >= 1 billion
|
91
91
|
expect(factory.pack(time96_min).size).to be 15
|
92
92
|
expect(factory.unpack(factory.pack(time96_min)).utc).to eq(time96_min)
|
93
93
|
end
|
94
94
|
|
95
95
|
let(:time96_max) { Time.at(2**63 - 1).utc }
|
96
96
|
it 'is serialized into timestamp96' do
|
97
|
-
skip if IS_JRUBY # JRuby
|
97
|
+
skip if IS_JRUBY || IS_TRUFFLERUBY # JRuby and TruffleRuby both use underlying Java time classes that do not support |year| >= 1 billion
|
98
98
|
expect(factory.pack(time96_max).size).to be 15
|
99
99
|
expect(factory.unpack(factory.pack(time96_max)).utc).to eq(time96_max)
|
100
100
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: msgpack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-
|
13
|
+
date: 2022-05-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -176,6 +176,7 @@ files:
|
|
176
176
|
- ext/msgpack/unpacker_ext_registry.c
|
177
177
|
- ext/msgpack/unpacker_ext_registry.h
|
178
178
|
- lib/msgpack.rb
|
179
|
+
- lib/msgpack/bigint.rb
|
179
180
|
- lib/msgpack/core_ext.rb
|
180
181
|
- lib/msgpack/factory.rb
|
181
182
|
- lib/msgpack/packer.rb
|
@@ -186,6 +187,7 @@ files:
|
|
186
187
|
- lib/msgpack/version.rb
|
187
188
|
- msgpack.gemspec
|
188
189
|
- msgpack.org.md
|
190
|
+
- spec/bigint_spec.rb
|
189
191
|
- spec/cases.json
|
190
192
|
- spec/cases.msg
|
191
193
|
- spec/cases_compact.msg
|