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/ext/cbor/buffer.h ADDED
@@ -0,0 +1,469 @@
1
+ /*
2
+ * CBOR for Ruby
3
+ *
4
+ * Copyright (C) 2013 Carsten Bormann
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License").
7
+ *
8
+ * Based on:
9
+ ***********/
10
+ /*
11
+ * MessagePack for Ruby
12
+ *
13
+ * Copyright (C) 2008-2013 Sadayuki Furuhashi
14
+ *
15
+ * Licensed under the Apache License, Version 2.0 (the "License");
16
+ * you may not use this file except in compliance with the License.
17
+ * You may obtain a copy of the License at
18
+ *
19
+ * http://www.apache.org/licenses/LICENSE-2.0
20
+ *
21
+ * Unless required by applicable law or agreed to in writing, software
22
+ * distributed under the License is distributed on an "AS IS" BASIS,
23
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
+ * See the License for the specific language governing permissions and
25
+ * limitations under the License.
26
+ */
27
+ #ifndef MSGPACK_RUBY_BUFFER_H__
28
+ #define MSGPACK_RUBY_BUFFER_H__
29
+
30
+ #include "cbor.h"
31
+
32
+ #include "compat.h"
33
+ #include "sysdep.h"
34
+
35
+ #ifdef COMPAT_HAVE_ENCODING /* see compat.h*/
36
+ extern int s_enc_ascii8bit;
37
+ extern int s_enc_usascii;
38
+ extern int s_enc_utf8;
39
+ extern VALUE s_enc_utf8_value;
40
+ #endif
41
+
42
+ extern VALUE rb_cCBOR_Tagged;
43
+ extern VALUE rb_cCBOR_Simple;
44
+
45
+ #ifndef MSGPACK_BUFFER_STRING_WRITE_REFERENCE_DEFAULT
46
+ #define MSGPACK_BUFFER_STRING_WRITE_REFERENCE_DEFAULT (512*1024)
47
+ #endif
48
+
49
+ /* at least 23 (RSTRING_EMBED_LEN_MAX) bytes */
50
+ #ifndef MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM
51
+ #define MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM 256
52
+ #endif
53
+
54
+ #ifndef MSGPACK_BUFFER_STRING_READ_REFERENCE_DEFAULT
55
+ #define MSGPACK_BUFFER_STRING_READ_REFERENCE_DEFAULT 256
56
+ #endif
57
+
58
+ /* at least 23 (RSTRING_EMBED_LEN_MAX) bytes */
59
+ #ifndef MSGPACK_BUFFER_STRING_READ_REFERENCE_MINIMUM
60
+ #define MSGPACK_BUFFER_STRING_READ_REFERENCE_MINIMUM 256
61
+ #endif
62
+
63
+ #ifndef MSGPACK_BUFFER_IO_BUFFER_SIZE_DEFAULT
64
+ #define MSGPACK_BUFFER_IO_BUFFER_SIZE_DEFAULT (32*1024)
65
+ #endif
66
+
67
+ #ifndef MSGPACK_BUFFER_IO_BUFFER_SIZE_MINIMUM
68
+ #define MSGPACK_BUFFER_IO_BUFFER_SIZE_MINIMUM (1024)
69
+ #endif
70
+
71
+ #define NO_MAPPED_STRING ((VALUE)0)
72
+
73
+ struct msgpack_buffer_chunk_t;
74
+ typedef struct msgpack_buffer_chunk_t msgpack_buffer_chunk_t;
75
+
76
+ struct msgpack_buffer_t;
77
+ typedef struct msgpack_buffer_t msgpack_buffer_t;
78
+
79
+ /*
80
+ * msgpack_buffer_chunk_t
81
+ * +----------------+
82
+ * | filled | free |
83
+ * +---------+------+
84
+ * ^ first ^ last
85
+ */
86
+ struct msgpack_buffer_chunk_t {
87
+ char* first;
88
+ char* last;
89
+ void* mem;
90
+ msgpack_buffer_chunk_t* next;
91
+ VALUE mapped_string; /* RBString or NO_MAPPED_STRING */
92
+ };
93
+
94
+ union msgpack_buffer_cast_block_t {
95
+ char buffer[8];
96
+ uint8_t u8;
97
+ uint16_t u16;
98
+ uint32_t u32;
99
+ uint64_t u64;
100
+ int8_t i8;
101
+ int16_t i16;
102
+ int32_t i32;
103
+ int64_t i64;
104
+ float f;
105
+ double d;
106
+ };
107
+
108
+ struct msgpack_buffer_t {
109
+ char* read_buffer;
110
+ char* tail_buffer_end;
111
+
112
+ msgpack_buffer_chunk_t tail;
113
+ msgpack_buffer_chunk_t* head;
114
+ msgpack_buffer_chunk_t* free_list;
115
+
116
+ #ifndef DISABLE_RMEM
117
+ char* rmem_last;
118
+ char* rmem_end;
119
+ void** rmem_owner;
120
+ #endif
121
+
122
+ union msgpack_buffer_cast_block_t cast_block;
123
+
124
+ VALUE io;
125
+ VALUE io_buffer;
126
+ ID io_write_all_method;
127
+ ID io_partial_read_method;
128
+
129
+ size_t write_reference_threshold;
130
+ size_t read_reference_threshold;
131
+ size_t io_buffer_size;
132
+
133
+ VALUE owner;
134
+ };
135
+
136
+ /*
137
+ * initialization functions
138
+ */
139
+ void msgpack_buffer_static_init();
140
+
141
+ void msgpack_buffer_static_destroy();
142
+
143
+ void msgpack_buffer_init(msgpack_buffer_t* b);
144
+
145
+ void msgpack_buffer_destroy(msgpack_buffer_t* b);
146
+
147
+ void msgpack_buffer_mark(msgpack_buffer_t* b);
148
+
149
+ void msgpack_buffer_clear(msgpack_buffer_t* b);
150
+
151
+ static inline void msgpack_buffer_set_write_reference_threshold(msgpack_buffer_t* b, size_t length)
152
+ {
153
+ if(length < MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM) {
154
+ length = MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM;
155
+ }
156
+ b->write_reference_threshold = length;
157
+ }
158
+
159
+ static inline void msgpack_buffer_set_read_reference_threshold(msgpack_buffer_t* b, size_t length)
160
+ {
161
+ if(length < MSGPACK_BUFFER_STRING_READ_REFERENCE_MINIMUM) {
162
+ length = MSGPACK_BUFFER_STRING_READ_REFERENCE_MINIMUM;
163
+ }
164
+ b->read_reference_threshold = length;
165
+ }
166
+
167
+ static inline void msgpack_buffer_set_io_buffer_size(msgpack_buffer_t* b, size_t length)
168
+ {
169
+ if(length < MSGPACK_BUFFER_IO_BUFFER_SIZE_MINIMUM) {
170
+ length = MSGPACK_BUFFER_IO_BUFFER_SIZE_MINIMUM;
171
+ }
172
+ b->io_buffer_size = length;
173
+ }
174
+
175
+ static inline void msgpack_buffer_reset_io(msgpack_buffer_t* b)
176
+ {
177
+ b->io = Qnil;
178
+ }
179
+
180
+ static inline bool msgpack_buffer_has_io(msgpack_buffer_t* b)
181
+ {
182
+ return b->io != Qnil;
183
+ }
184
+
185
+ static inline void msgpack_buffer_reset(msgpack_buffer_t* b)
186
+ {
187
+ msgpack_buffer_clear(b);
188
+ msgpack_buffer_reset_io(b);
189
+ }
190
+
191
+
192
+ /*
193
+ * writer functions
194
+ */
195
+
196
+ static inline size_t msgpack_buffer_writable_size(const msgpack_buffer_t* b)
197
+ {
198
+ return b->tail_buffer_end - b->tail.last;
199
+ }
200
+
201
+ static inline void msgpack_buffer_write_1(msgpack_buffer_t* b, int byte)
202
+ {
203
+ (*b->tail.last++) = (char) byte;
204
+ }
205
+
206
+ static inline void msgpack_buffer_write_2(msgpack_buffer_t* b, int byte1, unsigned char byte2)
207
+ {
208
+ *(b->tail.last++) = (char) byte1;
209
+ *(b->tail.last++) = (char) byte2;
210
+ }
211
+
212
+ static inline void msgpack_buffer_write_byte_and_data(msgpack_buffer_t* b, int byte, const void* data, size_t length)
213
+ {
214
+ (*b->tail.last++) = (char) byte;
215
+
216
+ memcpy(b->tail.last, data, length);
217
+ b->tail.last += length;
218
+ }
219
+
220
+ void _msgpack_buffer_expand(msgpack_buffer_t* b, const char* data, size_t length, bool use_flush);
221
+
222
+ size_t msgpack_buffer_flush_to_io(msgpack_buffer_t* b, VALUE io, ID write_method, bool consume);
223
+
224
+ static inline size_t msgpack_buffer_flush(msgpack_buffer_t* b)
225
+ {
226
+ if(b->io == Qnil) {
227
+ return 0;
228
+ }
229
+ return msgpack_buffer_flush_to_io(b, b->io, b->io_write_all_method, true);
230
+ }
231
+
232
+ static inline void msgpack_buffer_ensure_writable(msgpack_buffer_t* b, size_t require)
233
+ {
234
+ if(msgpack_buffer_writable_size(b) < require) {
235
+ _msgpack_buffer_expand(b, NULL, require, true);
236
+ }
237
+ }
238
+
239
+ static inline void _msgpack_buffer_append_impl(msgpack_buffer_t* b, const char* data, size_t length, bool flush_to_io)
240
+ {
241
+ if(length == 0) {
242
+ return;
243
+ }
244
+
245
+ if(length <= msgpack_buffer_writable_size(b)) {
246
+ memcpy(b->tail.last, data, length);
247
+ b->tail.last += length;
248
+ return;
249
+ }
250
+
251
+ _msgpack_buffer_expand(b, data, length, flush_to_io);
252
+ }
253
+
254
+ static inline void msgpack_buffer_append(msgpack_buffer_t* b, const char* data, size_t length)
255
+ {
256
+ _msgpack_buffer_append_impl(b, data, length, true);
257
+ }
258
+
259
+ static inline void msgpack_buffer_append_nonblock(msgpack_buffer_t* b, const char* data, size_t length)
260
+ {
261
+ _msgpack_buffer_append_impl(b, data, length, false);
262
+ }
263
+
264
+ void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string);
265
+
266
+ static inline size_t msgpack_buffer_append_string(msgpack_buffer_t* b, VALUE string)
267
+ {
268
+ size_t length = RSTRING_LEN(string);
269
+
270
+ if(length > b->write_reference_threshold) {
271
+ _msgpack_buffer_append_long_string(b, string);
272
+
273
+ } else {
274
+ msgpack_buffer_append(b, RSTRING_PTR(string), length);
275
+ }
276
+
277
+ return length;
278
+ }
279
+
280
+
281
+ /*
282
+ * IO functions
283
+ */
284
+ size_t _msgpack_buffer_feed_from_io(msgpack_buffer_t* b);
285
+
286
+ size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string, size_t length);
287
+
288
+ size_t _msgpack_buffer_skip_from_io(msgpack_buffer_t* b, size_t length);
289
+
290
+
291
+ /*
292
+ * reader functions
293
+ */
294
+
295
+ static inline size_t msgpack_buffer_top_readable_size(const msgpack_buffer_t* b)
296
+ {
297
+ return b->head->last - b->read_buffer;
298
+ }
299
+
300
+ size_t msgpack_buffer_all_readable_size(const msgpack_buffer_t* b);
301
+
302
+ bool _msgpack_buffer_shift_chunk(msgpack_buffer_t* b);
303
+
304
+ static inline void _msgpack_buffer_consumed(msgpack_buffer_t* b, size_t length)
305
+ {
306
+ b->read_buffer += length;
307
+ if(b->read_buffer >= b->head->last) {
308
+ _msgpack_buffer_shift_chunk(b);
309
+ }
310
+ }
311
+
312
+ static inline int msgpack_buffer_peek_top_1(msgpack_buffer_t* b)
313
+ {
314
+ return (int) (unsigned char) b->read_buffer[0];
315
+ }
316
+
317
+ static inline int msgpack_buffer_read_top_1(msgpack_buffer_t* b)
318
+ {
319
+ int r = (int) (unsigned char) b->read_buffer[0];
320
+
321
+ _msgpack_buffer_consumed(b, 1);
322
+
323
+ return r;
324
+ }
325
+
326
+ static inline int msgpack_buffer_read_1(msgpack_buffer_t* b)
327
+ {
328
+ if(msgpack_buffer_top_readable_size(b) <= 0) {
329
+ if(b->io == Qnil) {
330
+ return -1;
331
+ }
332
+ _msgpack_buffer_feed_from_io(b);
333
+ }
334
+
335
+ int r = (int) (unsigned char) b->read_buffer[0];
336
+ _msgpack_buffer_consumed(b, 1);
337
+
338
+ return r;
339
+ }
340
+
341
+
342
+ /*
343
+ * bulk read / skip functions
344
+ */
345
+
346
+ size_t msgpack_buffer_read_nonblock(msgpack_buffer_t* b, char* buffer, size_t length);
347
+
348
+ static inline bool msgpack_buffer_ensure_readable(msgpack_buffer_t* b, size_t require)
349
+ {
350
+ if(msgpack_buffer_top_readable_size(b) < require) {
351
+ size_t sz = msgpack_buffer_all_readable_size(b);
352
+ if(sz < require) {
353
+ if(b->io == Qnil) {
354
+ return false;
355
+ }
356
+ do {
357
+ size_t rl = _msgpack_buffer_feed_from_io(b);
358
+ sz += rl;
359
+ } while(sz < require);
360
+ }
361
+ }
362
+ return true;
363
+ }
364
+
365
+ bool _msgpack_buffer_read_all2(msgpack_buffer_t* b, char* buffer, size_t length);
366
+
367
+ static inline bool msgpack_buffer_read_all(msgpack_buffer_t* b, char* buffer, size_t length)
368
+ {
369
+ size_t avail = msgpack_buffer_top_readable_size(b);
370
+ if(avail < length) {
371
+ return _msgpack_buffer_read_all2(b, buffer, length);
372
+ }
373
+
374
+ memcpy(buffer, b->read_buffer, length);
375
+ _msgpack_buffer_consumed(b, length);
376
+ return true;
377
+ }
378
+
379
+ static inline size_t msgpack_buffer_skip_nonblock(msgpack_buffer_t* b, size_t length)
380
+ {
381
+ size_t avail = msgpack_buffer_top_readable_size(b);
382
+ if(avail < length) {
383
+ return msgpack_buffer_read_nonblock(b, NULL, length);
384
+ }
385
+ _msgpack_buffer_consumed(b, length);
386
+ return length;
387
+ }
388
+
389
+ static inline union msgpack_buffer_cast_block_t* msgpack_buffer_read_cast_block(msgpack_buffer_t* b, size_t n)
390
+ {
391
+ if(!msgpack_buffer_read_all(b, b->cast_block.buffer, n)) {
392
+ return NULL;
393
+ }
394
+ return &b->cast_block;
395
+ }
396
+
397
+ size_t msgpack_buffer_read_to_string_nonblock(msgpack_buffer_t* b, VALUE string, size_t length);
398
+
399
+ static inline size_t msgpack_buffer_read_to_string(msgpack_buffer_t* b, VALUE string, size_t length)
400
+ {
401
+ if(length == 0) {
402
+ return 0;
403
+ }
404
+
405
+ size_t avail = msgpack_buffer_top_readable_size(b);
406
+ if(avail > 0) {
407
+ return msgpack_buffer_read_to_string_nonblock(b, string, length);
408
+ } else if(b->io != Qnil) {
409
+ return _msgpack_buffer_read_from_io_to_string(b, string, length);
410
+ } else {
411
+ return 0;
412
+ }
413
+ }
414
+
415
+ static inline size_t msgpack_buffer_skip(msgpack_buffer_t* b, size_t length)
416
+ {
417
+ if(length == 0) {
418
+ return 0;
419
+ }
420
+
421
+ size_t avail = msgpack_buffer_top_readable_size(b);
422
+ if(avail > 0) {
423
+ return msgpack_buffer_skip_nonblock(b, length);
424
+ } else if(b->io != Qnil) {
425
+ return _msgpack_buffer_skip_from_io(b, length);
426
+ } else {
427
+ return 0;
428
+ }
429
+ }
430
+
431
+
432
+ VALUE msgpack_buffer_all_as_string(msgpack_buffer_t* b);
433
+
434
+ VALUE msgpack_buffer_all_as_string_array(msgpack_buffer_t* b);
435
+
436
+ static inline VALUE _msgpack_buffer_refer_head_mapped_string(msgpack_buffer_t* b, size_t length)
437
+ {
438
+ size_t offset = b->read_buffer - b->head->first;
439
+ return rb_str_substr(b->head->mapped_string, offset, length);
440
+ }
441
+
442
+ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_t length, bool will_be_frozen, bool as_symbol)
443
+ {
444
+ #ifndef DISABLE_BUFFER_READ_REFERENCE_OPTIMIZE
445
+ /* optimize */
446
+ if(!will_be_frozen &&
447
+ b->head->mapped_string != NO_MAPPED_STRING &&
448
+ length >= b->read_reference_threshold) {
449
+ VALUE result = _msgpack_buffer_refer_head_mapped_string(b, length);
450
+ _msgpack_buffer_consumed(b, length);
451
+ return result;
452
+ }
453
+ #endif
454
+
455
+ VALUE result;
456
+ if (as_symbol) {
457
+ result = ID2SYM(rb_intern2(b->read_buffer, length));
458
+ /* todo: rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc) */
459
+ } else {
460
+ result = rb_str_new(b->read_buffer, length);
461
+ /* todo: use rb_enc_str_new(const char *ptr, long len, rb_encoding *enc) :: */
462
+ }
463
+ _msgpack_buffer_consumed(b, length);
464
+ return result;
465
+ }
466
+
467
+
468
+ #endif
469
+