msgpack 1.3.2 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +1,6 @@
1
1
  module MessagePack
2
- VERSION = "1.3.2"
3
-
4
- # NOTE for msgpack-ruby maintainer:
5
- # Check these things to release new binaryes for new Ruby versions (especially for Windows):
6
- # * versions/supports of rake-compiler & rake-compiler-dock
7
- # * update RUBY_CC_VERSION in Rakefile
8
- # * check Ruby dependency of released mswin gem details
2
+ VERSION = "1.4.2"
3
+ # Note for maintainers:
4
+ # Don't miss building/releasing the JRuby version (rake buld:java)
5
+ # See "How to build -java rubygems" in README for more details.
9
6
  end
@@ -20,13 +20,11 @@ Gem::Specification.new do |s|
20
20
  end
21
21
  s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
22
22
 
23
+ s.required_ruby_version = ">= 2.4"
24
+
23
25
  s.add_development_dependency 'bundler'
24
26
  s.add_development_dependency 'rake'
25
- s.add_development_dependency 'rake-compiler', ['~> 1.0']
26
- if /java/ !~ RUBY_PLATFORM
27
- # NOTE: rake-compiler-dock SHOULD be updated for new Ruby versions
28
- s.add_development_dependency 'rake-compiler-dock', ['~> 0.7.0']
29
- end
27
+ s.add_development_dependency 'rake-compiler'
30
28
  s.add_development_dependency 'rspec', ['~> 3.3']
31
29
  s.add_development_dependency 'yard'
32
30
  s.add_development_dependency 'json'
@@ -19,6 +19,23 @@ def java?
19
19
  /java/ =~ RUBY_PLATFORM
20
20
  end
21
21
 
22
+ # checking if Hash#[]= (rb_hash_aset) dedupes string keys
23
+ def automatic_string_keys_deduplication?
24
+ h = {}
25
+ x = {}
26
+ r = rand.to_s
27
+ h[%W(#{r}).join('')] = :foo
28
+ x[%W(#{r}).join('')] = :foo
29
+
30
+ x.keys[0].equal?(h.keys[0])
31
+ end
32
+
33
+ def string_deduplication?
34
+ r1 = rand.to_s
35
+ r2 = r1.dup
36
+ (-r1).equal?(-r2)
37
+ end
38
+
22
39
  if java?
23
40
  RSpec.configure do |c|
24
41
  c.treat_symbols_as_metadata_keys_with_true_values = true
@@ -18,13 +18,26 @@ describe MessagePack::Unpacker do
18
18
  it 'gets options to specify how to unpack values' do
19
19
  u1 = MessagePack::Unpacker.new
20
20
  u1.symbolize_keys?.should == false
21
+ u1.freeze?.should == false
21
22
  u1.allow_unknown_ext?.should == false
22
23
 
23
- u2 = MessagePack::Unpacker.new(symbolize_keys: true, allow_unknown_ext: true)
24
+ u2 = MessagePack::Unpacker.new(symbolize_keys: true, freeze: true, allow_unknown_ext: true)
24
25
  u2.symbolize_keys?.should == true
26
+ u2.freeze?.should == true
25
27
  u2.allow_unknown_ext?.should == true
26
28
  end
27
29
 
30
+ if automatic_string_keys_deduplication?
31
+ it 'ensure string hash keys are deduplicated' do
32
+ sample_data = [{"foo" => 1}, {"foo" => 2}]
33
+ sample_packed = MessagePack.pack(sample_data).force_encoding('ASCII-8BIT')
34
+ unpacker.feed(sample_packed)
35
+ hashes = nil
36
+ unpacker.each { |obj| hashes = obj }
37
+ expect(hashes[0].keys.first).to equal(hashes[1].keys.first)
38
+ end
39
+ end
40
+
28
41
  it 'gets IO or object which has #read to read data from it' do
29
42
  sample_data = {"message" => "morning!", "num" => 1}
30
43
  sample_packed = MessagePack.pack(sample_data).force_encoding('ASCII-8BIT')
@@ -621,6 +634,14 @@ describe MessagePack::Unpacker do
621
634
  array = ['foo'] * 10_000
622
635
  MessagePack.unpack(MessagePack.pack(array)).size.should == 10_000
623
636
  end
637
+
638
+ it 'preserve string encoding (issue #200)' do
639
+ string = 'a'.force_encoding(Encoding::UTF_8)
640
+ MessagePack.unpack(MessagePack.pack(string)).encoding.should == string.encoding
641
+
642
+ string *= 256
643
+ MessagePack.unpack(MessagePack.pack(string)).encoding.should == string.encoding
644
+ end
624
645
  end
625
646
 
626
647
  context 'extensions' do
@@ -651,6 +672,88 @@ describe MessagePack::Unpacker do
651
672
  end
652
673
  end
653
674
 
675
+ context 'freeze' do
676
+ let :struct do
677
+ {'hello' => 'world', 'nested' => ['object', {'structure' => true}]}
678
+ end
679
+
680
+ let :buffer do
681
+ MessagePack.pack(struct)
682
+ end
683
+
684
+ let :unpacker do
685
+ described_class.new(:freeze => true)
686
+ end
687
+
688
+ it 'can freeze objects when using .unpack' do
689
+ parsed_struct = MessagePack.unpack(buffer, freeze: true)
690
+ parsed_struct.should == struct
691
+
692
+ parsed_struct.should be_frozen
693
+ parsed_struct['hello'].should be_frozen
694
+ parsed_struct['nested'].should be_frozen
695
+ parsed_struct['nested'][0].should be_frozen
696
+ parsed_struct['nested'][1].should be_frozen
697
+
698
+ if string_deduplication?
699
+ parsed_struct.keys[0].should be_equal('hello'.freeze)
700
+ parsed_struct.keys[1].should be_equal('nested'.freeze)
701
+ parsed_struct.values[0].should be_equal('world'.freeze)
702
+ parsed_struct.values[1][0].should be_equal('object'.freeze)
703
+ parsed_struct.values[1][1].keys[0].should be_equal('structure'.freeze)
704
+ end
705
+ end
706
+
707
+ it 'can freeze objects when using #each' do
708
+ objs = []
709
+ unpacker.feed(buffer)
710
+ unpacker.each do |obj|
711
+ objs << obj
712
+ end
713
+
714
+ parsed_struct = objs.first
715
+ parsed_struct.should == struct
716
+
717
+ parsed_struct.should be_frozen
718
+ parsed_struct['hello'].should be_frozen
719
+ parsed_struct['nested'].should be_frozen
720
+ parsed_struct['nested'][0].should be_frozen
721
+ parsed_struct['nested'][1].should be_frozen
722
+
723
+ if string_deduplication?
724
+ parsed_struct.keys[0].should be_equal('hello'.freeze)
725
+ parsed_struct.keys[1].should be_equal('nested'.freeze)
726
+ parsed_struct.values[0].should be_equal('world'.freeze)
727
+ parsed_struct.values[1][0].should be_equal('object'.freeze)
728
+ parsed_struct.values[1][1].keys[0].should be_equal('structure'.freeze)
729
+ end
730
+ end
731
+
732
+ it 'can freeze objects when using #feed_each' do
733
+ objs = []
734
+ unpacker.feed_each(buffer) do |obj|
735
+ objs << obj
736
+ end
737
+
738
+ parsed_struct = objs.first
739
+ parsed_struct.should == struct
740
+
741
+ parsed_struct.should be_frozen
742
+ parsed_struct['hello'].should be_frozen
743
+ parsed_struct['nested'].should be_frozen
744
+ parsed_struct['nested'][0].should be_frozen
745
+ parsed_struct['nested'][1].should be_frozen
746
+
747
+ if string_deduplication?
748
+ parsed_struct.keys[0].should be_equal('hello'.freeze)
749
+ parsed_struct.keys[1].should be_equal('nested'.freeze)
750
+ parsed_struct.values[0].should be_equal('world'.freeze)
751
+ parsed_struct.values[1][0].should be_equal('object'.freeze)
752
+ parsed_struct.values[1][1].keys[0].should be_equal('structure'.freeze)
753
+ end
754
+ end
755
+ end
756
+
654
757
  context 'binary encoding', :encodings do
655
758
  let :buffer do
656
759
  MessagePack.pack({'hello' => 'world', 'nested' => ['object', {'structure' => true}]})
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msgpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  - Theo Hultberg
9
9
  - Satoshi Tagomori
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-02-04 00:00:00.000000000 Z
13
+ date: 2021-02-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -44,30 +44,16 @@ dependencies:
44
44
  name: rake-compiler
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - "~>"
48
- - !ruby/object:Gem::Version
49
- version: '1.0'
50
- type: :development
51
- prerelease: false
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - "~>"
55
- - !ruby/object:Gem::Version
56
- version: '1.0'
57
- - !ruby/object:Gem::Dependency
58
- name: rake-compiler-dock
59
- requirement: !ruby/object:Gem::Requirement
60
- requirements:
61
- - - "~>"
47
+ - - ">="
62
48
  - !ruby/object:Gem::Version
63
- version: 0.7.0
49
+ version: '0'
64
50
  type: :development
65
51
  prerelease: false
66
52
  version_requirements: !ruby/object:Gem::Requirement
67
53
  requirements:
68
- - - "~>"
54
+ - - ">="
69
55
  - !ruby/object:Gem::Version
70
- version: 0.7.0
56
+ version: '0'
71
57
  - !ruby/object:Gem::Dependency
72
58
  name: rspec
73
59
  requirement: !ruby/object:Gem::Requirement
@@ -128,7 +114,7 @@ files:
128
114
  - ChangeLog
129
115
  - Gemfile
130
116
  - LICENSE
131
- - README.rdoc
117
+ - README.md
132
118
  - Rakefile
133
119
  - appveyor.yml
134
120
  - bench/pack.rb
@@ -228,7 +214,7 @@ homepage: http://msgpack.org/
228
214
  licenses:
229
215
  - Apache 2.0
230
216
  metadata: {}
231
- post_install_message:
217
+ post_install_message:
232
218
  rdoc_options: []
233
219
  require_paths:
234
220
  - lib
@@ -236,15 +222,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
236
222
  requirements:
237
223
  - - ">="
238
224
  - !ruby/object:Gem::Version
239
- version: '0'
225
+ version: '2.4'
240
226
  required_rubygems_version: !ruby/object:Gem::Requirement
241
227
  requirements:
242
228
  - - ">="
243
229
  - !ruby/object:Gem::Version
244
230
  version: '0'
245
231
  requirements: []
246
- rubygems_version: 3.1.2
247
- signing_key:
232
+ rubygems_version: 3.2.3
233
+ signing_key:
248
234
  specification_version: 4
249
235
  summary: MessagePack, a binary-based efficient data interchange format.
250
236
  test_files:
@@ -1,225 +0,0 @@
1
-
2
- = MessagePack
3
-
4
- MessagePack[http://msgpack.org] is an efficient binary serialization format.
5
- It lets you exchange data among multiple languages like JSON but it's faster and smaller.
6
- For example, small integers (like flags or error code) are encoded into a single byte,
7
- and typical short strings only require an extra byte in addition to the strings themselves.
8
-
9
- If you ever wished to use JSON for convenience (storing an image with metadata) but could
10
- not for technical reasons (binary data, size, speed...), MessagePack is a perfect replacement.
11
-
12
- require 'msgpack'
13
- msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03"
14
- MessagePack.unpack(msg) #=> [1,2,3]
15
-
16
- Use RubyGems to install:
17
-
18
- gem install msgpack
19
-
20
- or build msgpack-ruby and install:
21
-
22
- bundle
23
- rake
24
- gem install --local pkg/msgpack
25
-
26
-
27
- = Use cases
28
-
29
- * Create REST API returing MessagePack using Rails + [RABL](https://github.com/nesquena/rabl)
30
- * Store objects efficiently serialized by msgpack on memcached or Redis
31
- * In fact Redis supports msgpack in EVAL-scripts[http://redis.io/commands/eval]
32
- * Upload data in efficient format from mobile devices such as smartphones
33
- * MessagePack works on iPhone/iPad and Android. See also Objective-C[https://github.com/msgpack/msgpack-objectivec] and Java[https://github.com/msgpack/msgpack-java] implementations
34
- * Design a portable protocol to communicate with embedded devices
35
- * Check also Fluentd[http://fluentd.org/] which is a log collector which uses msgpack for the log format (they say it uses JSON but actually it's msgpack, which is compatible with JSON)
36
- * Exchange objects between software components written in different languages
37
- * You'll need a flexible but efficient format so that components exchange objects while keeping compatibility
38
-
39
- = Portability
40
-
41
- MessagePack for Ruby should run on x86, ARM, PowerPC, SPARC and other CPU architectures.
42
-
43
- And it works with MRI (CRuby) and Rubinius.
44
- Patches to improve portability is highly welcomed.
45
-
46
-
47
- = Serializing objects
48
-
49
- Use *MessagePack.pack* or *to_msgpack*:
50
-
51
- require 'msgpack'
52
- msg = MessagePack.pack(obj) # or
53
- msg = obj.to_msgpack
54
-
55
- == Streaming serialization
56
-
57
- Packer provides advanced API to serialize objects in streaming style:
58
-
59
- # serialize a 2-element array [e1, e2]
60
- pk = MessagePack::Packer.new(io)
61
- pk.write_array_header(2).write(e1).write(e2).flush
62
-
63
- See {API reference}[http://ruby.msgpack.org/MessagePack/Packer.html] for details.
64
-
65
- = Deserializing objects
66
-
67
- Use *MessagePack.unpack*:
68
-
69
- require 'msgpack'
70
- obj = MessagePack.unpack(msg)
71
-
72
- == Streaming deserialization
73
-
74
- Unpacker provides advanced API to deserialize objects in streaming style:
75
-
76
- # deserialize objects from an IO
77
- u = MessagePack::Unpacker.new(io)
78
- u.each do |obj|
79
- # ...
80
- end
81
-
82
- or event-driven style which works well with EventMachine:
83
-
84
- # event-driven deserialization
85
- def on_read(data)
86
- @u ||= MessagePack::Unpacker.new
87
- @u.feed_each(data) {|obj|
88
- # ...
89
- }
90
- end
91
-
92
- See {API reference}[http://ruby.msgpack.org/MessagePack/Unpacker.html] for details.
93
-
94
- = Serializing and deserializing symbols
95
-
96
- By default, symbols are serialized as strings:
97
-
98
- packed = :symbol.to_msgpack # => "\xA6symbol"
99
- MessagePack.unpack(packed) # => "symbol"
100
-
101
- This can be customized by registering an extension type for them:
102
-
103
- MessagePack::DefaultFactory.register_type(0x00, Symbol)
104
-
105
- # symbols now survive round trips
106
- packed = :symbol.to_msgpack # => "\xc7\x06\x00symbol"
107
- MessagePack.unpack(packed) # => :symbol
108
-
109
- The extension type for symbols is configurable like any other extension type.
110
- For example, to customize how symbols are packed you can just redefine
111
- Symbol#to_msgpack_ext. Doing this gives you an option to prevent symbols from
112
- being serialized altogether by throwing an exception:
113
-
114
- class Symbol
115
- def to_msgpack_ext
116
- raise "Serialization of symbols prohibited"
117
- end
118
- end
119
-
120
- MessagePack::DefaultFactory.register_type(0x00, Symbol)
121
-
122
- [1, :symbol, 'string'].to_msgpack # => RuntimeError: Serialization of symbols prohibited
123
-
124
- = Serializing and deserializing Time instances
125
-
126
- There are the timestamp extension type in MessagePack,
127
- but it is not registered by default.
128
-
129
- To map Ruby's Time to MessagePack's timestamp for the default factory:
130
-
131
- MessagePack::DefaultFactory.register_type(
132
- MessagePack::Timestamp::TYPE, # or just -1
133
- Time,
134
- packer: MessagePack::Time::Packer,
135
- unpacker: MessagePack::Time::Unpacker
136
- )
137
-
138
- See {API reference}[http://ruby.msgpack.org/] for details.
139
-
140
- = Extension Types
141
-
142
- Packer and Unpacker support {Extension types of MessagePack}[https://github.com/msgpack/msgpack/blob/master/spec.md#types-extension-type].
143
-
144
- # register how to serialize custom class at first
145
- pk = MessagePack::Packer.new(io)
146
- pk.register_type(0x01, MyClass1, :to_msgpack_ext) # equal to pk.register_type(0x01, MyClass)
147
- pk.register_type(0x02, MyClass2){|obj| obj.how_to_serialize() } # blocks also available
148
-
149
- # almost same API for unpacker
150
- uk = MessagePack::Unpacker.new()
151
- uk.register_type(0x01, MyClass1, :from_msgpack_ext)
152
- uk.register_type(0x02){|data| MyClass2.create_from_serialized_data(data) }
153
-
154
- MessagePack::Factory is to create packer and unpacker which have same extension types.
155
-
156
- factory = MessagePack::Factory.new
157
- factory.register_type(0x01, MyClass1) # same with next line
158
- factory.register_type(0x01, MyClass1, packer: :to_msgpack_ext, unpacker: :from_msgpack_ext)
159
- pk = factory.packer(options_for_packer)
160
- uk = factory.unpacker(options_for_unpacker)
161
-
162
- For *MessagePack.pack* and *MessagePack.unpack*, default packer/unpacker refer *MessagePack::DefaultFactory*. Call *MessagePack::DefaultFactory.register_type* to enable types process globally.
163
-
164
- MessagePack::DefaultFactory.register_type(0x03, MyClass3)
165
- MessagePack.unpack(data_with_ext_typeid_03) #=> MyClass3 instance
166
-
167
- = Buffer API
168
-
169
- MessagePack for Ruby provides a buffer API so that you can read or write data by hand, not via Packer or Unpacker API.
170
-
171
- This {MessagePack::Buffer}[http://ruby.msgpack.org/MessagePack/Buffer.html] is backed with a fixed-length shared memory pool which is very fast for small data (<= 4KB),
172
- and has zero-copy capability which significantly affects performance to handle large binary data.
173
-
174
- = How to build and run tests
175
-
176
- Before building msgpack, you need to install bundler and dependencies.
177
-
178
- gem install bundler
179
- bundle install
180
-
181
- Then, you can run the tasks as follows:
182
-
183
- * Build
184
-
185
- bundle exec rake build
186
-
187
- * Run tests
188
-
189
- bundle exec rake spec
190
-
191
- * Generating docs
192
-
193
- bundle exec rake doc
194
-
195
- == How to build -java rubygems
196
-
197
- To build -java gems for JRuby, run:
198
-
199
- rake build:java
200
-
201
- If this directory has Gemfile.lock (generated with MRI), remove it beforehand.
202
-
203
- == How to build -mingw32 rubygems
204
-
205
- MessagePack mingw32/64 rubygems build process uses {rake-compiler-dock}[https://github.com/rake-compiler/rake-compiler-dock]. Run:
206
-
207
- rake build:windows
208
-
209
- Once this step successes, target gems exist in pkg/msgpack-*-{x86,x64}-mingw32.gem.
210
-
211
- == Updating documents
212
-
213
- Online documents (http://ruby.msgpack.org) is generated from gh-pages branch.
214
- Following commands update documents in gh-pages branch:
215
-
216
- bundle exec rake doc
217
- git checkout gh-pages
218
- cp doc/* ./ -a
219
-
220
- = Copyright
221
-
222
- Author:: Sadayuki Furuhashi <frsyuki@gmail.com>
223
- Copyright:: Copyright (c) 2008-2015 Sadayuki Furuhashi
224
- License:: Apache License, Version 2.0
225
-