cbor 0.5.6.2

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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.travis.yml +5 -0
  4. data/ChangeLog +87 -0
  5. data/README.rdoc +180 -0
  6. data/Rakefile +94 -0
  7. data/cbor.gemspec +26 -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/buffer.c +693 -0
  17. data/ext/cbor/buffer.h +469 -0
  18. data/ext/cbor/buffer_class.c +516 -0
  19. data/ext/cbor/buffer_class.h +41 -0
  20. data/ext/cbor/cbor.h +69 -0
  21. data/ext/cbor/compat.h +136 -0
  22. data/ext/cbor/core_ext.c +181 -0
  23. data/ext/cbor/core_ext.h +35 -0
  24. data/ext/cbor/extconf.rb +25 -0
  25. data/ext/cbor/packer.c +169 -0
  26. data/ext/cbor/packer.h +337 -0
  27. data/ext/cbor/packer_class.c +304 -0
  28. data/ext/cbor/packer_class.h +39 -0
  29. data/ext/cbor/rbinit.c +51 -0
  30. data/ext/cbor/renamer.h +56 -0
  31. data/ext/cbor/rmem.c +103 -0
  32. data/ext/cbor/rmem.h +118 -0
  33. data/ext/cbor/sysdep.h +135 -0
  34. data/ext/cbor/sysdep_endian.h +59 -0
  35. data/ext/cbor/sysdep_types.h +55 -0
  36. data/ext/cbor/unpacker.c +735 -0
  37. data/ext/cbor/unpacker.h +133 -0
  38. data/ext/cbor/unpacker_class.c +417 -0
  39. data/ext/cbor/unpacker_class.h +39 -0
  40. data/lib/cbor.rb +9 -0
  41. data/lib/cbor/version.rb +3 -0
  42. data/spec/buffer_io_spec.rb +260 -0
  43. data/spec/buffer_spec.rb +576 -0
  44. data/spec/cases.cbor +0 -0
  45. data/spec/cases.cbor_stream +0 -0
  46. data/spec/cases.json +1 -0
  47. data/spec/cases.msg +0 -0
  48. data/spec/cases_compact.msg +0 -0
  49. data/spec/cases_spec.rb +39 -0
  50. data/spec/format_spec.rb +445 -0
  51. data/spec/packer_spec.rb +127 -0
  52. data/spec/random_compat.rb +24 -0
  53. data/spec/spec_helper.rb +45 -0
  54. data/spec/unpacker_spec.rb +238 -0
  55. metadata +196 -0
data/spec/cases.cbor ADDED
Binary file
Binary file
data/spec/cases.json ADDED
@@ -0,0 +1 @@
1
+ [false,true,null,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,127,127,255,65535,4294967295,-32,-32,-128,-32768,-2147483648,0.0,-0.0,1.0,-1.0,"a","a","a","","","",[0],[0],[0],[],[],[],{},{},{},{"a":97},{"a":97},{"a":97},[[]],[["a"]]]
data/spec/cases.msg ADDED
Binary file
Binary file
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'json'
3
+
4
+ describe MessagePack do
5
+ here = File.dirname(__FILE__)
6
+ CASES = File.read("#{here}/cases.cbor_stream")
7
+ CASES_JSON = File.read("#{here}/cases.json")
8
+ CASES_INDEFINITE = File.read("#{here}/cases.cbor_stream") # TODO
9
+
10
+ it 'compare with json' do
11
+ ms = []
12
+ MessagePack::Unpacker.new.feed_each(CASES) {|m|
13
+ ms << m
14
+ }
15
+
16
+ js = JSON.load(CASES_JSON)
17
+
18
+ ms.zip(js) {|m,j|
19
+ m.should == j
20
+ }
21
+ end
22
+
23
+ it 'compare with compat' do
24
+ ms = []
25
+ MessagePack::Unpacker.new.feed_each(CASES) {|m|
26
+ ms << m
27
+ }
28
+
29
+ cs = []
30
+ MessagePack::Unpacker.new.feed_each(CASES_INDEFINITE) {|c|
31
+ cs << c
32
+ }
33
+
34
+ ms.zip(cs) {|m,c|
35
+ m.should == c
36
+ }
37
+ end
38
+ end
39
+
@@ -0,0 +1,445 @@
1
+ # encoding: ascii-8bit
2
+ require 'spec_helper'
3
+
4
+ def bignum_to_bytes(bn)
5
+ bn.to_s(16).chars.each_slice(2).map{|a| a.join.to_i(16).chr}.join
6
+ end
7
+ # => "\x98!sHq#\x98W\x91\x82sY\x87)Hu#E"
8
+ # 0x982173487123985791827359872948752345
9
+
10
+ unless defined?(Float::INFINITY)
11
+ class Float
12
+ INFINITY = 1.0/0.0
13
+ NAN = 0.0/0.0
14
+ end
15
+ end
16
+
17
+ describe MessagePack do
18
+ it "nil" do
19
+ check 1, nil
20
+ end
21
+
22
+ it "true" do
23
+ check 1, true
24
+ end
25
+
26
+ it "false" do
27
+ check 1, false
28
+ end
29
+
30
+ it "zero" do
31
+ check 1, 0
32
+ end
33
+
34
+ it "positive fixnum" do
35
+ check 1, 1
36
+ check 2, (1<<6)
37
+ check 2, (1<<7)-1
38
+ end
39
+
40
+ it "positive int 8" do
41
+ check 1, -1
42
+ check 2, (1<<7)
43
+ check 2, (1<<8)-1
44
+ end
45
+
46
+ it "positive int 16" do
47
+ check 3, (1<<8)
48
+ check 3, (1<<16)-1
49
+ check 3, 1024
50
+ check 4, [1024]
51
+ end
52
+
53
+ it "positive int 32" do
54
+ check 5, (1<<16)
55
+ check 5, (1<<32)-1
56
+ end
57
+
58
+ it "positive int 64" do
59
+ check 9, (1<<32)
60
+ check 9, (1<<64)-1
61
+ end
62
+
63
+ it "negative fixnum" do
64
+ check 1, -1
65
+ check 1, -24
66
+ check 2, -25
67
+ end
68
+
69
+ it "negative int 8" do
70
+ check 2, -((1<<5)+1)
71
+ check 2, -(1<<7)
72
+ end
73
+
74
+ it "negative int 16" do
75
+ check 2, -((1<<7)+1)
76
+ check 2, -256
77
+ check 3, -(1<<15)
78
+ end
79
+
80
+ it "negative int 32" do
81
+ check 3, -((1<<15)+1)
82
+ check 3, -(1<<16)
83
+ check 5, -(1<<31)
84
+ check 5, -(1<<32)
85
+ end
86
+
87
+ it "negative int 64" do
88
+ check 5, -((1<<31)+1)
89
+ check 9, -(1<<63)
90
+ check 9, -(1<<64)
91
+ end
92
+
93
+ it "half" do
94
+ check 3, 1.0
95
+ check 3, -1.0
96
+ check 3, -2.0
97
+ check 3, 65504.0
98
+ check 3, -65504.0
99
+ check 3, Math.ldexp(1, -14) # ≈ 6.10352 × 10−5 (minimum positive normal)
100
+ check 3, -Math.ldexp(1, -14) # ≈ 6.10352 × 10−5 (maximum negative normal)
101
+ check 3, Math.ldexp(1, -14) - Math.ldexp(1, -24) # ≈ 6.09756 × 10−5 (maximum subnormal)
102
+ check 3, Math.ldexp(1, -24) # ≈ 5.96046 × 10−8 (minimum positive subnormal)
103
+ check 3, -Math.ldexp(1, -24) # ≈ -5.96046 × 10−8 (maximum negative subnormal)
104
+ check 5, Math.ldexp(1, -14) - Math.ldexp(0.5, -24) # check loss of precision
105
+ check 5, Math.ldexp(1.5, -24) # loss of precision (subnormal)
106
+ check 3, Math.ldexp(1.5, -23)
107
+ check 5, Math.ldexp(1.75, -23)
108
+ check 3, Float::INFINITY
109
+ check 3, -Float::INFINITY
110
+ # check 3, Float::NAN # NAN is not equal to itself, to this never checks out...
111
+ raw = Float::NAN.to_cbor.to_s
112
+ raw.length.should == 3
113
+ MessagePack.unpack(raw).nan?.should == true
114
+ end
115
+
116
+ it "double" do
117
+ check 9, 0.1
118
+ check 9, -0.1
119
+ end
120
+
121
+ it "fixraw" do
122
+ check_raw 1, 0
123
+ check_raw 1, 23
124
+ end
125
+
126
+ it "raw 16" do
127
+ check_raw 2, (1<<5)
128
+ check_raw 3, (1<<16)-1
129
+ end
130
+
131
+ it "raw 32" do
132
+ check_raw 5, (1<<16)
133
+ #check_raw 5, (1<<32)-1 # memory error
134
+ end
135
+
136
+ it "fixarray" do
137
+ check_array 1, 0
138
+ check_array 1, (1<<4)-1
139
+ check_array 1, 23
140
+ end
141
+
142
+ it "array 16" do
143
+ check_array 1, (1<<4)
144
+ #check_array 3, (1<<16)-1
145
+ end
146
+
147
+ it "array 32" do
148
+ #check_array 5, (1<<16)
149
+ #check_array 5, (1<<32)-1 # memory error
150
+ end
151
+
152
+ it "nil" do
153
+ match nil, "\xf6"
154
+ end
155
+
156
+ it "false" do
157
+ match false, "\xf4"
158
+ end
159
+
160
+ it "true" do
161
+ match true, "\xf5"
162
+ end
163
+
164
+ it "0" do
165
+ match 0, "\x00"
166
+ end
167
+
168
+ it "127" do
169
+ match 127, "\x18\x7f"
170
+ end
171
+
172
+ it "128" do
173
+ match 128, "\x18\x80"
174
+ end
175
+
176
+ it "256" do
177
+ match 256, "\x19\x01\x00"
178
+ end
179
+
180
+ it "-1" do
181
+ match -1, "\x20"
182
+ end
183
+
184
+ it "-33" do
185
+ match -33, "\x38\x20"
186
+ end
187
+
188
+ it "-129" do
189
+ match -129, "\x38\x80"
190
+ end
191
+
192
+ it "-257" do
193
+ match -257, "\x39\x01\x00"
194
+ end
195
+
196
+ it "{1=>1}" do
197
+ obj = {1=>1}
198
+ match obj, "\xA1\x01\x01"
199
+ end
200
+
201
+ it "1.0" do
202
+ match 1.0, "\xF9\x3c\x00"
203
+ end
204
+
205
+ it "[]" do
206
+ match [], "\x80"
207
+ end
208
+
209
+ it "[0, 1, ..., 14]" do
210
+ obj = (0..14).to_a
211
+ match obj, "\x8f\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"
212
+ end
213
+
214
+ it "[0, 1, ..., 15]" do
215
+ obj = (0..15).to_a
216
+ match obj, "\x90\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
217
+ end
218
+
219
+ it "[0, 1, ..., 22]" do
220
+ obj = (0..22).to_a
221
+ match obj, "\x97\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16"
222
+ end
223
+
224
+ it "[0, 1, ..., 23]" do
225
+ obj = (0..23).to_a
226
+ match obj, "\x98\x18\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17"
227
+ end
228
+
229
+ it "{}" do
230
+ obj = {}
231
+ match obj, "\xA0"
232
+ end
233
+
234
+ it "0x982173487123985791827359872948752345" do
235
+ check_bn(0x982173487123985791827359872948752345, 0xc2)
236
+ check_bn(-0x982173487123985791827359872948752345, 0xc3)
237
+ check_bn(0x9821734871239857918273598729487523, 0xc2)
238
+ check_bn(0x98217348712398579182735987294875, 0xc2)
239
+ check_bn(0x982173487123985791827359872948, 0xc2)
240
+ check_bn(0x9821734871239857918273598729, 0xc2)
241
+ check_bn(0x98217348712398579182735987, 0xc2)
242
+ check 20, 0x982173487123985791827359872948752345
243
+ check 20, -0x982173487123985791827359872948752345
244
+ check 19, 0x9821734871239857918273598729487523
245
+ check 18, 0x98217348712398579182735987294875
246
+ check 18, -0x98217348712398579182735987294875
247
+ check 17, 0x982173487123985791827359872948
248
+ check 16, 0x9821734871239857918273598729
249
+ check 15, 0x98217348712398579182735987
250
+ check 15, 0x9821734871239857918273598
251
+ check 16, [0x9821734871239857918273598]
252
+ check 39, 0x982173487123985791827359872948752345982173487123985791827359872948752345
253
+ check 3005, 256**3000+4711 # 3001 bignum, 3 string, 1 tag
254
+ end
255
+
256
+ it "fixnum/bignum switch" do
257
+ CBOR.encode(CBOR.decode("\xc2\x40")).should == "\x00"
258
+ CBOR.encode(CBOR.decode("\xc2\x41\x00")).should == "\x00"
259
+ CBOR.encode(CBOR.decode("\xc2\x41a")).should == "\x18a"
260
+ CBOR.encode(CBOR.decode("\xc2\x42aa")).should == "\x19aa"
261
+ CBOR.encode(CBOR.decode("\xc2\x43aaa")).should == "\x1A\x00aaa"
262
+ CBOR.encode(CBOR.decode("\xc2\x44aaaa")).should == "\x1Aaaaa"
263
+ CBOR.encode(CBOR.decode("\xc2\x45aaaaa")).should == "\e\x00\x00\x00aaaaa"
264
+ CBOR.encode(CBOR.decode("\xc2\x46aaaaaa")).should == "\e\x00\x00aaaaaa"
265
+ CBOR.encode(CBOR.decode("\xc2\x47aaaaaaa")).should == "\e\x00aaaaaaa"
266
+ CBOR.encode(CBOR.decode("\xc2\x48aaaaaaaa")).should == "\eaaaaaaaa"
267
+ CBOR.encode(CBOR.decode("\xc2\x49\x00aaaaaaaa")).should == "\eaaaaaaaa"
268
+ CBOR.encode(CBOR.decode("\xc2\x49aaaaaaaaa")).should == "\xC2Iaaaaaaaaa"
269
+ CBOR.encode(CBOR.decode("\xc2\x4a\x00aaaaaaaaa")).should == "\xC2Iaaaaaaaaa"
270
+ CBOR.encode(CBOR.decode("\xc2\x4aaaaaaaaaaa")).should == "\xC2Jaaaaaaaaaa"
271
+ CBOR.encode(CBOR.decode("\xc2\x4b\x00aaaaaaaaaa")).should == "\xC2Jaaaaaaaaaa"
272
+ CBOR.encode(CBOR.decode("\xc2\x4baaaaaaaaaaa")).should == "\xC2Kaaaaaaaaaaa"
273
+ CBOR.encode(CBOR.decode("\xc2\x4c\x00aaaaaaaaaaa")).should == "\xC2Kaaaaaaaaaaa"
274
+ CBOR.encode(CBOR.decode("\xc2\x4caaaaaaaaaaaa")).should == "\xC2Laaaaaaaaaaaa"
275
+ CBOR.encode(CBOR.decode("\xc2\x4d\x00aaaaaaaaaaaa")).should == "\xC2Laaaaaaaaaaaa"
276
+ CBOR.encode(CBOR.decode("\xc2\x4daaaaaaaaaaaaa")).should == "\xC2Maaaaaaaaaaaaa"
277
+ end
278
+
279
+ it "a-non-ascii" do
280
+ if ''.respond_to? :encode
281
+ match "abc".encode("UTF-32BE"), "cabc"
282
+ end
283
+ end
284
+
285
+ it "a" do
286
+ match "a".encode_as_utf8, "aa"
287
+ check 2, "a".encode_as_utf8
288
+ check_decode "aa", "a".encode_as_utf8
289
+ end
290
+
291
+ it "a.b" do
292
+ if ''.respond_to? :encode
293
+ match "a".b, "Aa"
294
+ end
295
+ check 2, "a".b
296
+ check_decode "Aa", "a".b
297
+ end
298
+
299
+ it "[_ ]" do
300
+ check_decode "\x9f\xff", []
301
+ end
302
+
303
+ it "[_ 1]" do
304
+ check_decode "\x9f\x01\xff", [1]
305
+ end
306
+
307
+ it "{_ }" do
308
+ check_decode "\xbf\xff", {}
309
+ end
310
+
311
+ it "{_ 1 => 2}" do
312
+ check_decode "\xbf\x01\x02\xff", {1 => 2}
313
+ end
314
+
315
+
316
+ it "{_ 1 => BREAK}" do
317
+ lambda {
318
+ check_decode "\xbf\x01\xff", {1 => 2}
319
+ }.should raise_error(MessagePack::MalformedFormatError)
320
+ end
321
+
322
+ it "(_ a b)" do
323
+ check_decode "\x7f\xff", "".encode_as_utf8
324
+ check_decode "\x5f\xff", "".b
325
+ check_decode "\x7faa\xff", "a".encode_as_utf8
326
+ check_decode "\x5fAa\xff", "a".b
327
+ check_decode "\x7faabbb\xff", "abb".encode_as_utf8
328
+ check_decode "\x5fAaBbb\xff", "abb".b
329
+ if ''.respond_to? :encode
330
+ lambda {
331
+ check_decode "\x7faaBbb\xff", "abb".encode_as_utf8
332
+ }.should raise_error(MessagePack::MalformedFormatError)
333
+ lambda {
334
+ check_decode "\x7fAa\xff", "a".encode_as_utf8
335
+ }.should raise_error(MessagePack::MalformedFormatError)
336
+ lambda {
337
+ check_decode "\x5fAabbb\xff", "abb".b
338
+ }.should raise_error(MessagePack::MalformedFormatError)
339
+ lambda {
340
+ check_decode "\x5faa\xff", "a".b
341
+ }.should raise_error(MessagePack::MalformedFormatError)
342
+ end
343
+ end
344
+
345
+ it "Time" do
346
+ check_decode "\xc1\x19\x12\x67", Time.at(4711)
347
+ check 6, Time.at(Time.now.to_i)
348
+ end
349
+
350
+ it "URI" do
351
+ check_decode "\xd8\x20\x78\x13http://www.ietf.org", CBOR::Tagged.new(32, "http://www.ietf.org")
352
+ require 'uri'
353
+ check_decode "\xd8\x20\x78\x13http://www.ietf.org", URI.parse("http://www.ietf.org")
354
+ # This doesn't work yet if 'uri' is not required before 'cbor':
355
+ # check 6, URI.parse("http://www.ietf.org")
356
+ end
357
+
358
+ it "regexp" do
359
+ check_decode "\xd8\x23\x63foo", /foo/
360
+ check 14, /(?-mix:foo)/
361
+ check 6, /foo/
362
+ end
363
+
364
+ it "Unknown simple 0" do
365
+ check_decode "\xf3", CBOR::Simple.new(19)
366
+ check 1, CBOR::Simple.new(0)
367
+ end
368
+
369
+ it "Unknown tag 0" do
370
+ check_decode "\xc0\x00", CBOR::Tagged.new(0, 0)
371
+ check 11, CBOR::Tagged.new(4711, "Frotzel")
372
+ end
373
+
374
+ it "Keys as Symbols" do # Experimental!
375
+ CBOR.decode(CBOR.encode({a: 1}), :keys_as_symbols).should == {a: 1}
376
+ CBOR.decode(CBOR.encode({a: 1})).should == {"a" => 1}
377
+ expect { CBOR.decode("\x00", :foobar) }.to raise_error(ArgumentError)
378
+ end
379
+
380
+ ## FIXME
381
+ # it "{0=>0, 1=>1, ..., 14=>14}" do
382
+ # a = (0..14).to_a;
383
+ # 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"
384
+ # end
385
+ #
386
+ # it "{0=>0, 1=>1, ..., 15=>15}" do
387
+ # a = (0..15).to_a;
388
+ # 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"
389
+ # end
390
+
391
+ ## FIXME
392
+ # it "fixmap" do
393
+ # check_map 1, 0
394
+ # check_map 1, (1<<4)-1
395
+ # end
396
+ #
397
+ # it "map 16" do
398
+ # check_map 3, (1<<4)
399
+ # check_map 3, (1<<16)-1
400
+ # end
401
+ #
402
+ # it "map 32" do
403
+ # check_map 5, (1<<16)
404
+ # #check_map 5, (1<<32)-1 # memory error
405
+ # end
406
+
407
+ def check(len, obj)
408
+ raw = obj.to_cbor.to_s
409
+ raw.length.should == len
410
+ obj2 = MessagePack.unpack(raw)
411
+ obj2.should == obj
412
+ if obj.respond_to? :encoding
413
+ obj2.encoding.should == obj.encoding
414
+ end
415
+ end
416
+
417
+ def check_raw(overhead, num)
418
+ check num+overhead, " "*num
419
+ end
420
+
421
+ def check_array(overhead, num)
422
+ check num+overhead, Array.new(num)
423
+ end
424
+
425
+ def check_bn(bn, tag)
426
+ bnb = bignum_to_bytes(bn < 0 ? ~bn : bn)
427
+ bnbs = bnb.size
428
+ match bn, "#{tag.chr}#{(bnbs + 0x40).chr}#{bnb}"
429
+ end
430
+
431
+ def match(obj, buf)
432
+ raw = obj.to_cbor.to_s
433
+ raw.should == buf
434
+ end
435
+
436
+ def check_decode(c, obj)
437
+ obj2 = MessagePack.unpack(c)
438
+ obj2.should == obj
439
+ if obj.respond_to? :encoding
440
+ obj2.encoding.should == obj.encoding
441
+ end
442
+ end
443
+
444
+ end
445
+