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
@@ -0,0 +1,25 @@
1
+ require 'mkmf'
2
+
3
+ have_header("ruby/st.h")
4
+ have_header("st.h")
5
+ have_func("rb_str_replace", ["ruby.h"])
6
+ have_func("rb_big_new", ["ruby.h"])
7
+
8
+ $CFLAGS << %[ -I.. -Wall -O3 -g -std=c99]
9
+ #$CFLAGS << %[ -DDISABLE_RMEM]
10
+ #$CFLAGS << %[ -DDISABLE_RMEM_REUSE_INTERNAL_FRAGMENT]
11
+ #$CFLAGS << %[ -DDISABLE_BUFFER_READ_REFERENCE_OPTIMIZE]
12
+ #$CFLAGS << %[ -DDISABLE_BUFFER_READ_TO_S_OPTIMIZE]
13
+
14
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
15
+ # msgpack-ruby doesn't modify data came from RSTRING_PTR(str)
16
+ $CFLAGS << %[ -DRSTRING_NOT_MODIFIED]
17
+ # Rubinius C extensions don't grab GVL while rmem is not thread safe
18
+ $CFLAGS << %[ -DDISABLE_RMEM]
19
+ end
20
+
21
+ if warnflags = CONFIG['warnflags']
22
+ warnflags.slice!(/ -Wdeclaration-after-statement/)
23
+ end
24
+
25
+ create_makefile('cbor/cbor')
data/ext/cbor/packer.c ADDED
@@ -0,0 +1,169 @@
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
+
28
+ #include "packer.h"
29
+
30
+ #ifdef RUBINIUS
31
+ static ID s_to_iter;
32
+ static ID s_next;
33
+ static ID s_key;
34
+ static ID s_value;
35
+ #endif
36
+
37
+ void msgpack_packer_static_init()
38
+ {
39
+ #ifdef RUBINIUS
40
+ s_to_iter = rb_intern("to_iter");
41
+ s_next = rb_intern("next");
42
+ s_key = rb_intern("key");
43
+ s_value = rb_intern("value");
44
+ #endif
45
+ }
46
+
47
+ void msgpack_packer_static_destroy()
48
+ { }
49
+
50
+ void msgpack_packer_init(msgpack_packer_t* pk)
51
+ {
52
+ memset(pk, 0, sizeof(msgpack_packer_t));
53
+
54
+ msgpack_buffer_init(PACKER_BUFFER_(pk));
55
+
56
+ pk->io = Qnil;
57
+ }
58
+
59
+ void msgpack_packer_destroy(msgpack_packer_t* pk)
60
+ {
61
+ msgpack_buffer_destroy(PACKER_BUFFER_(pk));
62
+ }
63
+
64
+ void msgpack_packer_mark(msgpack_packer_t* pk)
65
+ {
66
+ rb_gc_mark(pk->io);
67
+
68
+ /* See MessagePack_Buffer_wrap */
69
+ /* msgpack_buffer_mark(PACKER_BUFFER_(pk)); */
70
+ rb_gc_mark(pk->buffer_ref);
71
+ }
72
+
73
+ void msgpack_packer_reset(msgpack_packer_t* pk)
74
+ {
75
+ msgpack_buffer_clear(PACKER_BUFFER_(pk));
76
+
77
+ pk->io = Qnil;
78
+ pk->io_write_all_method = 0;
79
+ pk->buffer_ref = Qnil;
80
+ }
81
+
82
+
83
+ void msgpack_packer_write_array_value(msgpack_packer_t* pk, VALUE v)
84
+ {
85
+ /* actual return type of RARRAY_LEN is long */
86
+ unsigned long len = RARRAY_LEN(v);
87
+ msgpack_packer_write_array_header(pk, len);
88
+
89
+ unsigned long i;
90
+ for(i=0; i < len; ++i) {
91
+ VALUE e = rb_ary_entry(v, i);
92
+ msgpack_packer_write_value(pk, e);
93
+ }
94
+ }
95
+
96
+ static int write_hash_foreach(VALUE key, VALUE value, VALUE pk_value)
97
+ {
98
+ if (key == Qundef) {
99
+ return ST_CONTINUE;
100
+ }
101
+ msgpack_packer_t* pk = (msgpack_packer_t*) pk_value;
102
+ msgpack_packer_write_value(pk, key);
103
+ msgpack_packer_write_value(pk, value);
104
+ return ST_CONTINUE;
105
+ }
106
+
107
+ void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v)
108
+ {
109
+ /* actual return type of RHASH_SIZE is long (if SIZEOF_LONG == SIZEOF_VOIDP
110
+ * or long long (if SIZEOF_LONG_LONG == SIZEOF_VOIDP. See st.h. */
111
+ unsigned long len = RHASH_SIZE(v);
112
+ msgpack_packer_write_map_header(pk, len);
113
+
114
+ #ifdef RUBINIUS
115
+ VALUE iter = rb_funcall(v, s_to_iter, 0);
116
+ VALUE entry = Qnil;
117
+ while(RTEST(entry = rb_funcall(iter, s_next, 1, entry))) {
118
+ VALUE key = rb_funcall(entry, s_key, 0);
119
+ VALUE val = rb_funcall(entry, s_value, 0);
120
+ write_hash_foreach(key, val, (VALUE) pk);
121
+ }
122
+ #else
123
+ rb_hash_foreach(v, write_hash_foreach, (VALUE) pk);
124
+ #endif
125
+ }
126
+
127
+ static void _msgpack_packer_write_other_value(msgpack_packer_t* pk, VALUE v)
128
+ {
129
+ rb_funcall(v, pk->to_msgpack_method, 1, pk->to_msgpack_arg);
130
+ }
131
+
132
+ void msgpack_packer_write_value(msgpack_packer_t* pk, VALUE v)
133
+ {
134
+ switch(rb_type(v)) {
135
+ case T_NIL:
136
+ msgpack_packer_write_nil(pk);
137
+ break;
138
+ case T_TRUE:
139
+ msgpack_packer_write_true(pk);
140
+ break;
141
+ case T_FALSE:
142
+ msgpack_packer_write_false(pk);
143
+ break;
144
+ case T_FIXNUM:
145
+ msgpack_packer_write_fixnum_value(pk, v);
146
+ break;
147
+ case T_SYMBOL:
148
+ msgpack_packer_write_symbol_value(pk, v);
149
+ break;
150
+ case T_STRING:
151
+ msgpack_packer_write_string_value(pk, v);
152
+ break;
153
+ case T_ARRAY:
154
+ msgpack_packer_write_array_value(pk, v);
155
+ break;
156
+ case T_HASH:
157
+ msgpack_packer_write_hash_value(pk, v);
158
+ break;
159
+ case T_BIGNUM:
160
+ msgpack_packer_write_bignum_value(pk, v);
161
+ break;
162
+ case T_FLOAT:
163
+ msgpack_packer_write_float_value(pk, v);
164
+ break;
165
+ default:
166
+ _msgpack_packer_write_other_value(pk, v);
167
+ }
168
+ }
169
+
data/ext/cbor/packer.h ADDED
@@ -0,0 +1,337 @@
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_PACKER_H__
28
+ #define MSGPACK_RUBY_PACKER_H__
29
+
30
+ #include "buffer.h"
31
+
32
+ #ifndef MSGPACK_PACKER_IO_FLUSH_THRESHOLD_TO_WRITE_STRING_BODY
33
+ #define MSGPACK_PACKER_IO_FLUSH_THRESHOLD_TO_WRITE_STRING_BODY (1024)
34
+ #endif
35
+
36
+ struct msgpack_packer_t;
37
+ typedef struct msgpack_packer_t msgpack_packer_t;
38
+
39
+ struct msgpack_packer_t {
40
+ msgpack_buffer_t buffer;
41
+
42
+ VALUE io;
43
+ ID io_write_all_method;
44
+
45
+ ID to_msgpack_method;
46
+ VALUE to_msgpack_arg;
47
+
48
+ VALUE buffer_ref;
49
+ };
50
+
51
+ #define PACKER_BUFFER_(pk) (&(pk)->buffer)
52
+
53
+ void msgpack_packer_static_init();
54
+
55
+ void msgpack_packer_static_destroy();
56
+
57
+ void msgpack_packer_init(msgpack_packer_t* pk);
58
+
59
+ void msgpack_packer_destroy(msgpack_packer_t* pk);
60
+
61
+ void msgpack_packer_mark(msgpack_packer_t* pk);
62
+
63
+ static inline void msgpack_packer_set_to_msgpack_method(msgpack_packer_t* pk,
64
+ ID to_msgpack_method, VALUE to_msgpack_arg)
65
+ {
66
+ pk->to_msgpack_method = to_msgpack_method;
67
+ pk->to_msgpack_arg = to_msgpack_arg;
68
+ }
69
+
70
+ static inline void msgpack_packer_set_io(msgpack_packer_t* pk, VALUE io, ID io_write_all_method)
71
+ {
72
+ pk->io = io;
73
+ pk->io_write_all_method = io_write_all_method;
74
+ }
75
+
76
+ void msgpack_packer_reset(msgpack_packer_t* pk);
77
+
78
+
79
+ static inline void cbor_encoder_write_head(msgpack_packer_t* pk, unsigned int ib, uint64_t n)
80
+ {
81
+ if (n < 24) {
82
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
83
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), ib + n);
84
+ } else if (n < 256) {
85
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
86
+ msgpack_buffer_write_2(PACKER_BUFFER_(pk), ib + 24, n);
87
+ } else if (n < 65536) {
88
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
89
+ uint16_t be = _msgpack_be16(n);
90
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), ib + 25, (const void*)&be, 2);
91
+ } else if (n < 0x100000000LU) {
92
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
93
+ uint32_t be = _msgpack_be32(n);
94
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), ib + 26, (const void*)&be, 4);
95
+ } else {
96
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9);
97
+ uint64_t be = _msgpack_be64(n);
98
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), ib + 27, (const void*)&be, 8);
99
+ }
100
+ }
101
+
102
+ static inline void msgpack_packer_write_nil(msgpack_packer_t* pk)
103
+ {
104
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
105
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), IB_NIL);
106
+ }
107
+
108
+ static inline void msgpack_packer_write_true(msgpack_packer_t* pk)
109
+ {
110
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
111
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), IB_TRUE);
112
+ }
113
+
114
+ static inline void msgpack_packer_write_false(msgpack_packer_t* pk)
115
+ {
116
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
117
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), IB_FALSE);
118
+ }
119
+
120
+ static inline void _msgpack_packer_write_long_long64(msgpack_packer_t* pk, long long v)
121
+ {
122
+ uint64_t ui = v >> 63; // extend sign to whole length
123
+ int mt = ui & IB_NEGFLAG; // extract major type
124
+ ui ^= v; // complement negatives
125
+ cbor_encoder_write_head(pk, mt, ui);
126
+ }
127
+
128
+ static inline void msgpack_packer_write_long(msgpack_packer_t* pk, long v)
129
+ {
130
+ _msgpack_packer_write_long_long64(pk, v);
131
+ }
132
+
133
+ static inline void msgpack_packer_write_u64(msgpack_packer_t* pk, uint64_t v)
134
+ {
135
+ cbor_encoder_write_head(pk, IB_UNSIGNED, v);
136
+ }
137
+
138
+ static inline void msgpack_packer_write_double(msgpack_packer_t* pk, double v)
139
+ {
140
+ float fv = v;
141
+ if (fv == v) { /* 32 bits is enough and we aren't NaN */
142
+ union {
143
+ float f;
144
+ uint32_t u32;
145
+ char mem[4];
146
+ } castbuf = { fv };
147
+ int b32 = castbuf.u32;
148
+ if ((b32 & 0x1FFF) == 0) { /* worth trying half */
149
+ int s16 = (b32 >> 16) & 0x8000;
150
+ int exp = (b32 >> 23) & 0xff;
151
+ int mant = b32 & 0x7fffff;
152
+ if (exp == 0 && mant == 0)
153
+ ; /* 0.0, -0.0 */
154
+ else if (exp >= 113 && exp <= 142) /* normalized */
155
+ s16 += ((exp - 112) << 10) + (mant >> 13);
156
+ else if (exp >= 103 && exp < 113) { /* denorm, exp16 = 0 */
157
+ if (mant & ((1 << (126 - exp)) - 1))
158
+ goto float32; /* loss of precision */
159
+ s16 += ((mant + 0x800000) >> (126 - exp));
160
+ } else if (exp == 255 && mant == 0) { /* Inf */
161
+ s16 += 0x7c00;
162
+ } else
163
+ goto float32; /* loss of range */
164
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
165
+ uint16_t be = _msgpack_be16(s16);
166
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), IB_FLOAT2, (const void*)&be, 2);
167
+ return;
168
+ }
169
+ float32:
170
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
171
+ castbuf.u32 = _msgpack_be_float(castbuf.u32);
172
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), IB_FLOAT4, castbuf.mem, 4);
173
+ } else if (v != v) { /* NaN */
174
+ cbor_encoder_write_head(pk, 0xe0, 0xfe00);
175
+ } else {
176
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9);
177
+ union {
178
+ double d;
179
+ uint64_t u64;
180
+ char mem[8];
181
+ } castbuf = { v };
182
+ castbuf.u64 = _msgpack_be_double(castbuf.u64);
183
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), IB_FLOAT8, castbuf.mem, 8);
184
+ }
185
+ }
186
+
187
+ static inline void msgpack_packer_write_array_header(msgpack_packer_t* pk, uint64_t n)
188
+ {
189
+ cbor_encoder_write_head(pk, IB_ARRAY, n);
190
+ }
191
+
192
+ static inline void msgpack_packer_write_map_header(msgpack_packer_t* pk, uint64_t n)
193
+ {
194
+ cbor_encoder_write_head(pk, IB_MAP, n);
195
+ }
196
+
197
+
198
+ void _msgpack_packer_write_string_to_io(msgpack_packer_t* pk, VALUE string);
199
+
200
+ static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE v)
201
+ {
202
+ int mt = IB_TEXT; /* text string */
203
+ #ifdef COMPAT_HAVE_ENCODING
204
+ int enc = ENCODING_GET(v);
205
+ if (enc == s_enc_ascii8bit) {
206
+ mt = IB_BYTES;
207
+ } else if (enc != s_enc_utf8 && enc != s_enc_usascii) {
208
+ if(!ENC_CODERANGE_ASCIIONLY(v)) {
209
+ v = rb_str_encode(v, s_enc_utf8_value, 0, Qnil);
210
+ }
211
+ }
212
+ #endif
213
+ cbor_encoder_write_head(pk, mt, RSTRING_LEN(v));
214
+ msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
215
+ }
216
+
217
+ static inline void msgpack_packer_write_symbol_value(msgpack_packer_t* pk, VALUE v)
218
+ {
219
+ const char* name = rb_id2name(SYM2ID(v));
220
+ /* actual return type of strlen is size_t */
221
+ unsigned long len = strlen(name);
222
+ if(len > 0xffffffffUL) {
223
+ // TODO rb_eArgError?
224
+ rb_raise(rb_eArgError, "size of symbol is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL);
225
+ }
226
+ cbor_encoder_write_head(pk, IB_TEXT, len);
227
+ msgpack_buffer_append(PACKER_BUFFER_(pk), name, len);
228
+ }
229
+
230
+ static inline void msgpack_packer_write_fixnum_value(msgpack_packer_t* pk, VALUE v)
231
+ {
232
+ #ifdef JRUBY
233
+ msgpack_packer_write_long(pk, FIXNUM_P(v) ? FIX2LONG(v) : rb_num2ll(v));
234
+ #else
235
+ msgpack_packer_write_long(pk, FIX2LONG(v));
236
+ #endif
237
+ }
238
+
239
+ static inline void msgpack_packer_write_bignum_value(msgpack_packer_t* pk, VALUE v)
240
+ {
241
+ long len;
242
+ int ib = IB_UNSIGNED;
243
+ if (!RBIGNUM_POSITIVE_P(v)) {
244
+ v = rb_funcall(v, rb_intern("~"), 0); /* should be rb_big_neg(), but that is static. */
245
+ ib = IB_NEGATIVE;
246
+ }
247
+ len = RBIGNUM_LEN(v); /* This API is broken in Rubinius 2.1.1, #2742 */
248
+ if (len > SIZEOF_LONG_LONG/SIZEOF_BDIGITS) {
249
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
250
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), IB_BIGNUM + IB_NEGFLAG_AS_BIT(ib));
251
+ {
252
+ #ifndef CANT_DO_BIGNUMS_FAST_ON_THIS_PLATFORM
253
+ BDIGIT *dp = RBIGNUM_DIGITS(v);
254
+ BDIGIT *de = dp + len;
255
+ int nbyte = (len - 1) * SIZEOF_BDIGITS;
256
+ int nbmsdig = 0;
257
+ BDIGIT msdig;
258
+ int i;
259
+ if ((msdig = de[-1]) == 0) /* todo: check whether that occurs */
260
+ rb_raise(rb_eRangeError, "cbor writing unnormalized bignum");
261
+ while (msdig) { /* get number of significant bytes in msdig */
262
+ nbmsdig++;
263
+ msdig >>= 8;
264
+ }
265
+ nbyte += nbmsdig;
266
+ cbor_encoder_write_head(pk, IB_BYTES, nbyte);
267
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), nbyte);
268
+ /* first digit: */
269
+ msdig = de[-1];
270
+ while (nbmsdig) {
271
+ --nbmsdig;
272
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), msdig >> (nbmsdig << 3));
273
+ }
274
+ /* rest of the digits: */
275
+ for (i = 1; i < len; ++i) {
276
+ BDIGIT be = NTOHBDIGIT(de[-1-i]);
277
+ msgpack_buffer_append(PACKER_BUFFER_(pk), (const void*)&be, SIZEOF_BDIGITS);
278
+ }
279
+ #else
280
+ /* This is a slow workaround only... But a working one.*/
281
+ size_t nbyte;
282
+ VALUE hexval = rb_funcall(v, rb_intern("to_s"), 1, INT2FIX(16));
283
+ char *hp;
284
+ int i;
285
+ if (RSTRING_LEN(hexval) & 1)
286
+ rb_funcall(hexval, rb_intern("[]="), 3, INT2FIX(0), INT2FIX(0), rb_str_new("0", 1));
287
+ nbyte = RSTRING_LEN(hexval) >> 1;
288
+ hp = RSTRING_PTR(hexval);
289
+ cbor_encoder_write_head(pk, IB_BYTES, nbyte);
290
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), nbyte);
291
+ for (i = 0; i < nbyte; i++) {
292
+ int c;
293
+ sscanf(hp, "%2x", &c);
294
+ hp += 2;
295
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), c);
296
+ }
297
+ #endif
298
+ }
299
+ } else {
300
+ cbor_encoder_write_head(pk, ib, rb_big2ull(v));
301
+ }
302
+
303
+ #ifdef RB_GC_GUARD
304
+ RB_GC_GUARD(v);
305
+ #endif
306
+ }
307
+
308
+ static inline void msgpack_packer_write_float_value(msgpack_packer_t* pk, VALUE v)
309
+ {
310
+ msgpack_packer_write_double(pk, rb_num2dbl(v));
311
+ }
312
+
313
+ static inline void msgpack_packer_write_simple_value(msgpack_packer_t* pk, VALUE v)
314
+ {
315
+ cbor_encoder_write_head(pk, IB_PRIM, FIX2LONG(rb_struct_aref(v, INT2FIX(0))));
316
+ }
317
+
318
+ void msgpack_packer_write_array_value(msgpack_packer_t* pk, VALUE v);
319
+
320
+ void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v);
321
+
322
+ void msgpack_packer_write_value(msgpack_packer_t* pk, VALUE v);
323
+
324
+ static inline void msgpack_packer_write_tagged_value(msgpack_packer_t* pk, VALUE v)
325
+ {
326
+ cbor_encoder_write_head(pk, IB_TAG, FIX2LONG(rb_struct_aref(v, INT2FIX(0))));
327
+ msgpack_packer_write_value(pk, rb_struct_aref(v, INT2FIX(1)));
328
+ }
329
+
330
+ static inline void msgpack_packer_write_processed_value(msgpack_packer_t* pk, VALUE v, ID method, int tag)
331
+ {
332
+ cbor_encoder_write_head(pk, IB_TAG, tag);
333
+ msgpack_packer_write_value(pk, rb_funcall(v, method, 0));
334
+ }
335
+
336
+ #endif
337
+