hx_cbor 2021.8.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +30 -0
  3. data/.travis.yml +24 -0
  4. data/ChangeLog +106 -0
  5. data/Gemfile +11 -0
  6. data/README.rdoc +191 -0
  7. data/Rakefile +97 -0
  8. data/doclib/cbor.rb +80 -0
  9. data/doclib/cbor/buffer.rb +193 -0
  10. data/doclib/cbor/core_ext.rb +133 -0
  11. data/doclib/cbor/error.rb +14 -0
  12. data/doclib/cbor/packer.rb +133 -0
  13. data/doclib/cbor/simple.rb +15 -0
  14. data/doclib/cbor/tagged.rb +16 -0
  15. data/doclib/cbor/unpacker.rb +138 -0
  16. data/ext/cbor/3424.i.rb +29 -0
  17. data/ext/cbor/buffer.c +693 -0
  18. data/ext/cbor/buffer.h +484 -0
  19. data/ext/cbor/buffer_class.c +516 -0
  20. data/ext/cbor/buffer_class.h +41 -0
  21. data/ext/cbor/cbor.h +69 -0
  22. data/ext/cbor/compat.h +147 -0
  23. data/ext/cbor/core_ext.c +201 -0
  24. data/ext/cbor/core_ext.h +35 -0
  25. data/ext/cbor/example.rb +10 -0
  26. data/ext/cbor/extconf.rb +29 -0
  27. data/ext/cbor/install.sh +1 -0
  28. data/ext/cbor/packer.c +169 -0
  29. data/ext/cbor/packer.h +362 -0
  30. data/ext/cbor/packer_class.c +304 -0
  31. data/ext/cbor/packer_class.h +39 -0
  32. data/ext/cbor/rbinit.c +51 -0
  33. data/ext/cbor/renamer.h +56 -0
  34. data/ext/cbor/rmem.c +103 -0
  35. data/ext/cbor/rmem.h +118 -0
  36. data/ext/cbor/sysdep.h +139 -0
  37. data/ext/cbor/sysdep_endian.h +59 -0
  38. data/ext/cbor/sysdep_types.h +55 -0
  39. data/ext/cbor/unpacker.c +784 -0
  40. data/ext/cbor/unpacker.h +135 -0
  41. data/ext/cbor/unpacker_class.c +439 -0
  42. data/ext/cbor/unpacker_class.h +39 -0
  43. data/hx_cbor.gemspec +25 -0
  44. data/lib/cbor.rb +6 -0
  45. data/lib/cbor/version.rb +3 -0
  46. data/spec/buffer_io_spec.rb +260 -0
  47. data/spec/buffer_spec.rb +576 -0
  48. data/spec/cases.cbor +0 -0
  49. data/spec/cases.cbor_stream +0 -0
  50. data/spec/cases.json +1 -0
  51. data/spec/cases.msg +0 -0
  52. data/spec/cases_compact.msg +0 -0
  53. data/spec/cases_spec.rb +39 -0
  54. data/spec/format_spec.rb +540 -0
  55. data/spec/packer_spec.rb +127 -0
  56. data/spec/random_compat.rb +24 -0
  57. data/spec/spec_helper.rb +68 -0
  58. data/spec/unpacker_spec.rb +260 -0
  59. metadata +198 -0
@@ -0,0 +1,127 @@
1
+ # encoding: ascii-8bit
2
+ require 'spec_helper'
3
+
4
+ require 'stringio'
5
+ if defined?(Encoding)
6
+ Encoding.default_external = 'ASCII-8BIT'
7
+ end
8
+
9
+ describe Packer do
10
+ let :packer do
11
+ Packer.new
12
+ end
13
+
14
+ it 'initialize' do
15
+ Packer.new
16
+ Packer.new(nil)
17
+ Packer.new(StringIO.new)
18
+ Packer.new({})
19
+ Packer.new(StringIO.new, {})
20
+ end
21
+
22
+ #it 'Packer' do
23
+ # Packer(packer).object_id.should == packer.object_id
24
+ # Packer(nil).class.should == Packer
25
+ # Packer('').class.should == Packer
26
+ # Packer('initbuf').to_s.should == 'initbuf'
27
+ #end
28
+
29
+ it 'write' do
30
+ packer.write([])
31
+ packer.to_s.should == "\x80"
32
+ end
33
+
34
+ it 'write_nil' do
35
+ packer.write_nil
36
+ packer.to_s.should == "\xf6"
37
+ end
38
+
39
+ it 'write_array_header 0' do
40
+ packer.write_array_header(0)
41
+ packer.to_s.should == "\x80"
42
+ end
43
+
44
+ it 'write_array_header 1' do
45
+ packer.write_array_header(1)
46
+ packer.to_s.should == "\x81"
47
+ end
48
+
49
+ it 'write_map_header 0' do
50
+ packer.write_map_header(0)
51
+ packer.to_s.should == "\xa0"
52
+ end
53
+
54
+ it 'write_map_header 1' do
55
+ packer.write_map_header(1)
56
+ packer.to_s.should == "\xa1"
57
+ end
58
+
59
+ it 'flush' do
60
+ io = StringIO.new
61
+ pk = Packer.new(io)
62
+ pk.write_nil
63
+ pk.flush
64
+ pk.to_s.should == ''
65
+ io.string.should == "\xf6"
66
+ end
67
+
68
+ it 'buffer' do
69
+ o1 = packer.buffer.object_id
70
+ packer.buffer << 'frsyuki'
71
+ packer.buffer.to_s.should == 'frsyuki'
72
+ packer.buffer.object_id.should == o1
73
+ end
74
+
75
+ it 'to_cbor returns String' do
76
+ nil.to_cbor.class.should == String
77
+ true.to_cbor.class.should == String
78
+ false.to_cbor.class.should == String
79
+ 1.to_cbor.class.should == String
80
+ 1.0.to_cbor.class.should == String
81
+ "".to_cbor.class.should == String
82
+ Hash.new.to_cbor.class.should == String
83
+ Array.new.to_cbor.class.should == String
84
+ end
85
+
86
+ class CustomPack01
87
+ def to_cbor(pk=nil)
88
+ return MessagePack.pack(self, pk) unless pk.class == MessagePack::Packer
89
+ pk.write_array_header(2)
90
+ pk.write(1)
91
+ pk.write(2)
92
+ return pk
93
+ end
94
+ end
95
+
96
+ class CustomPack02
97
+ def to_cbor(pk=nil)
98
+ [1,2].to_cbor(pk)
99
+ end
100
+ end
101
+
102
+ it 'calls custom to_cbor method' do
103
+ MessagePack.pack(CustomPack01.new).should == [1,2].to_cbor
104
+ MessagePack.pack(CustomPack02.new).should == [1,2].to_cbor
105
+ CustomPack01.new.to_cbor.should == [1,2].to_cbor
106
+ CustomPack02.new.to_cbor.should == [1,2].to_cbor
107
+ end
108
+
109
+ it 'calls custom to_cbor method with io' do
110
+ s01 = StringIO.new
111
+ MessagePack.pack(CustomPack01.new, s01)
112
+ s01.string.should == [1,2].to_cbor
113
+
114
+ s02 = StringIO.new
115
+ MessagePack.pack(CustomPack02.new, s02)
116
+ s02.string.should == [1,2].to_cbor
117
+
118
+ s03 = StringIO.new
119
+ CustomPack01.new.to_cbor(s03)
120
+ s03.string.should == [1,2].to_cbor
121
+
122
+ s04 = StringIO.new
123
+ CustomPack02.new.to_cbor(s04)
124
+ s04.string.should == [1,2].to_cbor
125
+ end
126
+ end
127
+
@@ -0,0 +1,24 @@
1
+
2
+ unless defined? Random
3
+ class Random
4
+ def initialize(seed=Time.now.to_i)
5
+ Kernel.srand(seed)
6
+ @seed = seed
7
+ end
8
+
9
+ attr_reader :seed
10
+
11
+ def rand(arg)
12
+ Kernel.rand(arg)
13
+ end
14
+
15
+ def bytes(n)
16
+ array = []
17
+ n.times do
18
+ array << rand(256)
19
+ end
20
+ array.pack('C*')
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,68 @@
1
+ require 'rubygems' # for 1.8
2
+
3
+ RSpec.configure do |config|
4
+ config.expect_with :rspec do |c|
5
+ c.syntax = [:should, :expect]
6
+ end
7
+ config.mock_with :rspec do |c|
8
+ c.syntax = [:should, :expect]
9
+ end
10
+ end
11
+
12
+
13
+ class String
14
+ if ''.respond_to? :encode
15
+ def encode_as_utf8
16
+ encode(Encoding::UTF_8)
17
+ end
18
+ def force_as_utf8
19
+ force_encoding(Encoding::UTF_8)
20
+ end
21
+ unless String.instance_methods.include?(:b)
22
+ def b
23
+ dup.force_encoding(Encoding::BINARY)
24
+ end
25
+ end
26
+ else
27
+ def encode_as_utf8
28
+ self # MRI 1.8
29
+ end
30
+ def force_as_utf8
31
+ self # MRI 1.8
32
+ end
33
+ def b
34
+ self
35
+ end
36
+ end
37
+ unless ''.respond_to? :clear
38
+ def clear
39
+ replace('')
40
+ end
41
+ end
42
+ def hexbytes(sep = '')
43
+ bytes.map{|x| "%02x" % x}.join(sep)
44
+ end
45
+ end
46
+
47
+ if ENV['SIMPLE_COV']
48
+ require 'simplecov'
49
+ SimpleCov.start do
50
+ add_filter 'spec/'
51
+ add_filter 'pkg/'
52
+ add_filter 'vendor/'
53
+ end
54
+ end
55
+
56
+ if ENV['GC_STRESS']
57
+ puts "enable GC.stress"
58
+ GC.stress = true
59
+ end
60
+
61
+ require 'cbor'
62
+
63
+ MessagePack = CBOR # XXX
64
+
65
+ Packer = MessagePack::Packer
66
+ Unpacker = MessagePack::Unpacker
67
+ Buffer = MessagePack::Buffer
68
+
@@ -0,0 +1,260 @@
1
+ # encoding: ascii-8bit
2
+ require 'spec_helper'
3
+
4
+ describe Unpacker do
5
+ let :unpacker do
6
+ Unpacker.new
7
+ end
8
+
9
+ let :packer do
10
+ Packer.new
11
+ end
12
+
13
+ # TODO initialize
14
+
15
+ it 'read_array_header succeeds' do
16
+ unpacker.feed("\x81")
17
+ unpacker.read_array_header.should == 1
18
+ end
19
+
20
+ it 'read_array_header fails' do
21
+ unpacker.feed("\xa1")
22
+ lambda {
23
+ unpacker.read_array_header
24
+ }.should raise_error(MessagePack::TypeError)
25
+ end
26
+
27
+ it 'read_array_header converts an array to value sequence' do
28
+ packer.write_array_header(2)
29
+ packer.write("e")
30
+ packer.write(1)
31
+ unpacker = Unpacker.new
32
+ unpacker.feed(packer.to_s)
33
+ unpacker.read_array_header.should == 2
34
+ unpacker.read.should == "e"
35
+ unpacker.read.should == 1
36
+ end
37
+
38
+ it 'read_map_header succeeds' do
39
+ unpacker.feed("\xa1")
40
+ unpacker.read_map_header.should == 1
41
+ end
42
+
43
+ it 'read_map_header converts an map to key-value sequence' do
44
+ packer.write_map_header(1)
45
+ packer.write("k")
46
+ packer.write("v")
47
+ unpacker = Unpacker.new
48
+ unpacker.feed(packer.to_s)
49
+ unpacker.read_map_header.should == 1
50
+ unpacker.read.should == "k"
51
+ unpacker.read.should == "v"
52
+ end
53
+
54
+ it 'read_map_header fails' do
55
+ unpacker.feed("\x81")
56
+ lambda {
57
+ unpacker.read_map_header
58
+ }.should raise_error(MessagePack::TypeError)
59
+ end
60
+
61
+ it 'skip_nil succeeds' do
62
+ unpacker.feed("\xf6")
63
+ unpacker.skip_nil.should == true
64
+ end
65
+
66
+ it 'skip_nil fails' do
67
+ unpacker.feed("\x80")
68
+ unpacker.skip_nil.should == false
69
+ end
70
+
71
+ it 'skip skips objects' do
72
+ packer.write(1)
73
+ packer.write(2)
74
+ packer.write(3)
75
+ packer.write(4)
76
+ packer.write(5)
77
+
78
+ unpacker = Unpacker.new(packer.buffer)
79
+
80
+ unpacker.read.should == 1
81
+ unpacker.skip
82
+ unpacker.read.should == 3
83
+ unpacker.skip
84
+ unpacker.read.should == 5
85
+ end
86
+
87
+ it 'read raises EOFError' do
88
+ lambda {
89
+ unpacker.read
90
+ }.should raise_error(EOFError)
91
+ end
92
+
93
+ it 'skip raises EOFError' do
94
+ lambda {
95
+ unpacker.skip
96
+ }.should raise_error(EOFError)
97
+ end
98
+
99
+ it 'skip_nil raises EOFError' do
100
+ lambda {
101
+ unpacker.skip_nil
102
+ }.should raise_error(EOFError)
103
+ end
104
+
105
+ let :sample_object do
106
+ [1024, {["a","b"]=>["c","d"]}, ["e","f"], "d", 70000, 4.12, 1.5, 1.5, 1.5]
107
+ end
108
+
109
+ it 'sample object OK' do
110
+ obj2 = MessagePack.unpack(sample_object.to_cbor)
111
+ obj2.should == sample_object
112
+ end
113
+
114
+ it 'feed and each continue internal state' do
115
+ raw = sample_object.to_cbor.to_s * 4
116
+ objects = []
117
+
118
+ raw.split(//).each do |b|
119
+ unpacker.feed(b)
120
+ unpacker.each {|c|
121
+ objects << c
122
+ }
123
+ end
124
+
125
+ objects.should == [sample_object] * 4
126
+ end
127
+
128
+ it 'feed_each continues internal state' do
129
+ raw = sample_object.to_cbor.to_s * 4
130
+ objects = []
131
+
132
+ raw.split(//).each do |b|
133
+ unpacker.feed_each(b) {|c|
134
+ objects << c
135
+ }
136
+ end
137
+
138
+ objects.should == [sample_object] * 4
139
+ end
140
+
141
+ it 'reset clears internal buffer' do
142
+ # 1-element array
143
+ unpacker.feed("\x91")
144
+ unpacker.reset
145
+ unpacker.feed("\x01")
146
+
147
+ unpacker.each.map {|x| x }.should == [1]
148
+ end
149
+
150
+ it 'reset clears internal state' do
151
+ # 1-element array
152
+ unpacker.feed("\x91")
153
+ unpacker.each.map {|x| x }.should == []
154
+
155
+ unpacker.reset
156
+
157
+ unpacker.feed("\x01")
158
+ unpacker.each.map {|x| x }.should == [1]
159
+ end
160
+
161
+ it 'buffer' do
162
+ o1 = unpacker.buffer.object_id
163
+ unpacker.buffer << 'frsyuki'
164
+ unpacker.buffer.to_s.should == 'frsyuki'
165
+ unpacker.buffer.object_id.should == o1
166
+ end
167
+
168
+ it 'frozen short strings' do
169
+ raw = sample_object.to_cbor.to_s.force_as_utf8
170
+ lambda {
171
+ unpacker.feed_each(raw.freeze) { }
172
+ }.should_not raise_error
173
+ end
174
+
175
+ it 'frozen long strings' do
176
+ raw = (sample_object.to_cbor.to_s * 10240).force_as_utf8
177
+ lambda {
178
+ unpacker.feed_each(raw.freeze) { }
179
+ }.should_not raise_error
180
+ end
181
+
182
+ it 'read raises level stack too deep error' do
183
+ 512.times { packer.write_array_header(1) }
184
+ packer.write(nil)
185
+
186
+ unpacker = Unpacker.new(packer.buffer)
187
+ lambda {
188
+ unpacker.read
189
+ }.should raise_error(MessagePack::StackError)
190
+ end
191
+
192
+ it 'skip raises level stack too deep error' do
193
+ 512.times { packer.write_array_header(1) }
194
+ packer.write(nil)
195
+
196
+ unpacker = Unpacker.new(packer.buffer)
197
+ lambda {
198
+ unpacker.skip
199
+ }.should raise_error(MessagePack::StackError)
200
+ end
201
+
202
+ it 'read raises invalid byte error' do
203
+ unpacker.feed("\xdf")
204
+ lambda {
205
+ unpacker.read
206
+ }.should raise_error(MessagePack::MalformedFormatError)
207
+ end
208
+
209
+ it 'skip raises invalid byte error' do
210
+ unpacker.feed("\xdf")
211
+ lambda {
212
+ unpacker.skip
213
+ }.should raise_error(MessagePack::MalformedFormatError)
214
+ end
215
+
216
+ it "gc mark" do
217
+ raw = sample_object.to_cbor.to_s * 4
218
+
219
+ n = 0
220
+ raw.split(//).each do |b|
221
+ GC.start
222
+ unpacker.feed_each(b) {|o|
223
+ GC.start
224
+ o.should == sample_object
225
+ n += 1
226
+ }
227
+ GC.start
228
+ end
229
+
230
+ n.should == 4
231
+ end
232
+
233
+ it "buffer" do
234
+ orig = "a"*32*1024*4
235
+ raw = orig.to_cbor.to_s
236
+
237
+ n = 655
238
+ times = raw.size / n
239
+ times += 1 unless raw.size % n == 0
240
+
241
+ off = 0
242
+ parsed = false
243
+
244
+ times.times do
245
+ parsed.should == false
246
+
247
+ seg = raw[off, n]
248
+ off += seg.length
249
+
250
+ unpacker.feed_each(seg) {|obj|
251
+ parsed.should == false
252
+ obj.should == orig
253
+ parsed = true
254
+ }
255
+ end
256
+
257
+ parsed.should == true
258
+ end
259
+ end
260
+