cbor 0.5.6.2

Sign up to get free protection for your applications and to get access to all the features.
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
+