msgpack-ably 0.5.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.travis.yml +26 -0
  4. data/ChangeLog +101 -0
  5. data/README.rdoc +129 -0
  6. data/Rakefile +110 -0
  7. data/doclib/msgpack.rb +77 -0
  8. data/doclib/msgpack/buffer.rb +193 -0
  9. data/doclib/msgpack/core_ext.rb +101 -0
  10. data/doclib/msgpack/error.rb +14 -0
  11. data/doclib/msgpack/packer.rb +134 -0
  12. data/doclib/msgpack/unpacker.rb +146 -0
  13. data/ext/msgpack/buffer.c +678 -0
  14. data/ext/msgpack/buffer.h +441 -0
  15. data/ext/msgpack/buffer_class.c +507 -0
  16. data/ext/msgpack/buffer_class.h +32 -0
  17. data/ext/msgpack/compat.h +113 -0
  18. data/ext/msgpack/core_ext.c +129 -0
  19. data/ext/msgpack/core_ext.h +26 -0
  20. data/ext/msgpack/extconf.rb +28 -0
  21. data/ext/msgpack/packer.c +168 -0
  22. data/ext/msgpack/packer.h +429 -0
  23. data/ext/msgpack/packer_class.c +302 -0
  24. data/ext/msgpack/packer_class.h +30 -0
  25. data/ext/msgpack/rbinit.c +33 -0
  26. data/ext/msgpack/rmem.c +94 -0
  27. data/ext/msgpack/rmem.h +109 -0
  28. data/ext/msgpack/sysdep.h +115 -0
  29. data/ext/msgpack/sysdep_endian.h +50 -0
  30. data/ext/msgpack/sysdep_types.h +46 -0
  31. data/ext/msgpack/unpacker.c +781 -0
  32. data/ext/msgpack/unpacker.h +122 -0
  33. data/ext/msgpack/unpacker_class.c +405 -0
  34. data/ext/msgpack/unpacker_class.h +32 -0
  35. data/lib/msgpack.rb +6 -0
  36. data/lib/msgpack/version.rb +3 -0
  37. data/msgpack.gemspec +26 -0
  38. data/msgpack.org.md +49 -0
  39. data/spec/cases.json +1 -0
  40. data/spec/cases.msg +0 -0
  41. data/spec/cases_compact.msg +0 -0
  42. data/spec/cases_spec.rb +39 -0
  43. data/spec/cruby/buffer_io_spec.rb +256 -0
  44. data/spec/cruby/buffer_packer.rb +29 -0
  45. data/spec/cruby/buffer_spec.rb +572 -0
  46. data/spec/cruby/buffer_unpacker.rb +19 -0
  47. data/spec/format_spec.rb +256 -0
  48. data/spec/packer_spec.rb +120 -0
  49. data/spec/random_compat.rb +24 -0
  50. data/spec/spec_helper.rb +21 -0
  51. data/spec/unpacker_spec.rb +305 -0
  52. metadata +195 -0
@@ -0,0 +1,429 @@
1
+ /*
2
+ * MessagePack for Ruby
3
+ *
4
+ * Copyright (C) 2008-2013 Sadayuki Furuhashi
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ #ifndef MSGPACK_RUBY_PACKER_H__
19
+ #define MSGPACK_RUBY_PACKER_H__
20
+
21
+ #include "buffer.h"
22
+
23
+ #ifndef MSGPACK_PACKER_IO_FLUSH_THRESHOLD_TO_WRITE_STRING_BODY
24
+ #define MSGPACK_PACKER_IO_FLUSH_THRESHOLD_TO_WRITE_STRING_BODY (1024)
25
+ #endif
26
+
27
+ struct msgpack_packer_t;
28
+ typedef struct msgpack_packer_t msgpack_packer_t;
29
+
30
+ struct msgpack_packer_t {
31
+ msgpack_buffer_t buffer;
32
+
33
+ VALUE io;
34
+ ID io_write_all_method;
35
+
36
+ ID to_msgpack_method;
37
+ VALUE to_msgpack_arg;
38
+
39
+ VALUE buffer_ref;
40
+ };
41
+
42
+ #define PACKER_BUFFER_(pk) (&(pk)->buffer)
43
+
44
+ void msgpack_packer_static_init();
45
+
46
+ void msgpack_packer_static_destroy();
47
+
48
+ void msgpack_packer_init(msgpack_packer_t* pk);
49
+
50
+ void msgpack_packer_destroy(msgpack_packer_t* pk);
51
+
52
+ void msgpack_packer_mark(msgpack_packer_t* pk);
53
+
54
+ static inline void msgpack_packer_set_to_msgpack_method(msgpack_packer_t* pk,
55
+ ID to_msgpack_method, VALUE to_msgpack_arg)
56
+ {
57
+ pk->to_msgpack_method = to_msgpack_method;
58
+ pk->to_msgpack_arg = to_msgpack_arg;
59
+ }
60
+
61
+ static inline void msgpack_packer_set_io(msgpack_packer_t* pk, VALUE io, ID io_write_all_method)
62
+ {
63
+ pk->io = io;
64
+ pk->io_write_all_method = io_write_all_method;
65
+ }
66
+
67
+ void msgpack_packer_reset(msgpack_packer_t* pk);
68
+
69
+
70
+ static inline void msgpack_packer_write_nil(msgpack_packer_t* pk)
71
+ {
72
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
73
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), 0xc0);
74
+ }
75
+
76
+ static inline void msgpack_packer_write_true(msgpack_packer_t* pk)
77
+ {
78
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
79
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), 0xc3);
80
+ }
81
+
82
+ static inline void msgpack_packer_write_false(msgpack_packer_t* pk)
83
+ {
84
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
85
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), 0xc2);
86
+ }
87
+
88
+ static inline void _msgpack_packer_write_fixint(msgpack_packer_t* pk, int8_t v)
89
+ {
90
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
91
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), v);
92
+ }
93
+
94
+ static inline void _msgpack_packer_write_uint8(msgpack_packer_t* pk, uint8_t v)
95
+ {
96
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 2);
97
+ msgpack_buffer_write_2(PACKER_BUFFER_(pk), 0xcc, v);
98
+ }
99
+
100
+ static inline void _msgpack_packer_write_uint16(msgpack_packer_t* pk, uint16_t v)
101
+ {
102
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
103
+ uint16_t be = _msgpack_be16(v);
104
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xcd, (const void*)&be, 2);
105
+ }
106
+
107
+ static inline void _msgpack_packer_write_uint32(msgpack_packer_t* pk, uint32_t v)
108
+ {
109
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
110
+ uint32_t be = _msgpack_be32(v);
111
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xce, (const void*)&be, 4);
112
+ }
113
+
114
+ static inline void _msgpack_packer_write_uint64(msgpack_packer_t* pk, uint64_t v)
115
+ {
116
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9);
117
+ uint64_t be = _msgpack_be64(v);
118
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xcf, (const void*)&be, 8);
119
+ }
120
+
121
+ static inline void _msgpack_packer_write_int8(msgpack_packer_t* pk, int8_t v)
122
+ {
123
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 2);
124
+ msgpack_buffer_write_2(PACKER_BUFFER_(pk), 0xd0, v);
125
+ }
126
+
127
+ static inline void _msgpack_packer_write_int16(msgpack_packer_t* pk, int16_t v)
128
+ {
129
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
130
+ uint16_t be = _msgpack_be16(v);
131
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xd1, (const void*)&be, 2);
132
+ }
133
+
134
+ static inline void _msgpack_packer_write_int32(msgpack_packer_t* pk, int32_t v)
135
+ {
136
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
137
+ uint32_t be = _msgpack_be32(v);
138
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xd2, (const void*)&be, 4);
139
+ }
140
+
141
+ static inline void _msgpack_packer_write_int64(msgpack_packer_t* pk, int64_t v)
142
+ {
143
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9);
144
+ uint64_t be = _msgpack_be64(v);
145
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xd3, (const void*)&be, 8);
146
+ }
147
+
148
+ static inline void _msgpack_packer_write_long32(msgpack_packer_t* pk, long v)
149
+ {
150
+ if(v < -0x20L) {
151
+ if(v < -0x8000L) {
152
+ _msgpack_packer_write_int32(pk, (int32_t) v);
153
+ } else if(v < -0x80L) {
154
+ _msgpack_packer_write_int16(pk, (int16_t) v);
155
+ } else {
156
+ _msgpack_packer_write_int8(pk, (int8_t) v);
157
+ }
158
+ } else if(v <= 0x7fL) {
159
+ _msgpack_packer_write_fixint(pk, (int8_t) v);
160
+ } else {
161
+ if(v <= 0xffL) {
162
+ _msgpack_packer_write_uint8(pk, (uint8_t) v);
163
+ } else if(v <= 0xffffL) {
164
+ _msgpack_packer_write_uint16(pk, (uint16_t) v);
165
+ } else {
166
+ _msgpack_packer_write_uint32(pk, (uint32_t) v);
167
+ }
168
+ }
169
+ }
170
+
171
+ static inline void _msgpack_packer_write_long_long64(msgpack_packer_t* pk, long long v)
172
+ {
173
+ if(v < -0x20LL) {
174
+ if(v < -0x8000LL) {
175
+ if(v < -0x80000000LL) {
176
+ _msgpack_packer_write_int64(pk, (int64_t) v);
177
+ } else {
178
+ _msgpack_packer_write_int32(pk, (int32_t) v);
179
+ }
180
+ } else {
181
+ if(v < -0x80LL) {
182
+ _msgpack_packer_write_int16(pk, (int16_t) v);
183
+ } else {
184
+ _msgpack_packer_write_int8(pk, (int8_t) v);
185
+ }
186
+ }
187
+ } else if(v <= 0x7fLL) {
188
+ _msgpack_packer_write_fixint(pk, (int8_t) v);
189
+ } else {
190
+ if(v <= 0xffffLL) {
191
+ if(v <= 0xffLL) {
192
+ _msgpack_packer_write_uint8(pk, (uint8_t) v);
193
+ } else {
194
+ _msgpack_packer_write_uint16(pk, (uint16_t) v);
195
+ }
196
+ } else {
197
+ if(v <= 0xffffffffLL) {
198
+ _msgpack_packer_write_uint32(pk, (uint32_t) v);
199
+ } else {
200
+ _msgpack_packer_write_uint64(pk, (uint64_t) v);
201
+ }
202
+ }
203
+ }
204
+ }
205
+
206
+ static inline void msgpack_packer_write_long(msgpack_packer_t* pk, long v)
207
+ {
208
+ #if defined(SIZEOF_LONG)
209
+ # if SIZEOF_LONG <= 4
210
+ _msgpack_packer_write_long32(pk, v);
211
+ # else
212
+ _msgpack_packer_write_long_long64(pk, v);
213
+ # endif
214
+
215
+ #elif defined(LONG_MAX)
216
+ # if LONG_MAX <= 0x7fffffffL
217
+ _msgpack_packer_write_long32(pk, v);
218
+ # else
219
+ _msgpack_packer_write_long_long64(pk, v);
220
+ # endif
221
+
222
+ #else
223
+ if(sizeof(long) <= 4) {
224
+ _msgpack_packer_write_long32(pk, v);
225
+ } else {
226
+ _msgpack_packer_write_long_long64(pk, v);
227
+ }
228
+ #endif
229
+ }
230
+
231
+ static inline void msgpack_packer_write_long_long(msgpack_packer_t* pk, long long v)
232
+ {
233
+ /* assuming sizeof(long long) == 8 */
234
+ _msgpack_packer_write_long_long64(pk, v);
235
+ }
236
+
237
+ static inline void msgpack_packer_write_u64(msgpack_packer_t* pk, uint64_t v)
238
+ {
239
+ if(v <= 0xffULL) {
240
+ if(v <= 0x7fULL) {
241
+ _msgpack_packer_write_fixint(pk, (int8_t) v);
242
+ } else {
243
+ _msgpack_packer_write_uint8(pk, (uint8_t) v);
244
+ }
245
+ } else {
246
+ if(v <= 0xffffULL) {
247
+ _msgpack_packer_write_uint16(pk, (uint16_t) v);
248
+ } else if(v <= 0xffffffffULL) {
249
+ _msgpack_packer_write_uint32(pk, (uint32_t) v);
250
+ } else {
251
+ _msgpack_packer_write_uint64(pk, (uint64_t) v);
252
+ }
253
+ }
254
+ }
255
+
256
+ static inline void msgpack_packer_write_double(msgpack_packer_t* pk, double v)
257
+ {
258
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9);
259
+ union {
260
+ double d;
261
+ uint64_t u64;
262
+ char mem[8];
263
+ } castbuf = { v };
264
+ castbuf.u64 = _msgpack_be_double(castbuf.u64);
265
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xcb, castbuf.mem, 8);
266
+ }
267
+
268
+ static inline void msgpack_packer_write_raw_header(msgpack_packer_t* pk, unsigned int n)
269
+ {
270
+ if(n < 32) {
271
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
272
+ unsigned char h = 0xa0 | (uint8_t) n;
273
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), h);
274
+ } else if(n < 256) {
275
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 2);
276
+ unsigned char be = (uint8_t) n;
277
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xd9, (const void*)&be, 1);
278
+ } else if(n < 65536) {
279
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
280
+ uint16_t be = _msgpack_be16(n);
281
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xda, (const void*)&be, 2);
282
+ } else {
283
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
284
+ uint32_t be = _msgpack_be32(n);
285
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdb, (const void*)&be, 4);
286
+ }
287
+ }
288
+
289
+ static inline void msgpack_packer_write_bin_header(msgpack_packer_t* pk, unsigned int n)
290
+ {
291
+ if(n < 256) {
292
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
293
+ unsigned char be = (uint8_t) n;
294
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xc4, (const void*)&be, 1);
295
+ } else if(n < 65536) {
296
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
297
+ uint16_t be = _msgpack_be16(n);
298
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xc5, (const void*)&be, 2);
299
+ } else {
300
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
301
+ uint32_t be = _msgpack_be32(n);
302
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xc6, (const void*)&be, 4);
303
+ }
304
+ }
305
+
306
+ static inline void msgpack_packer_write_array_header(msgpack_packer_t* pk, unsigned int n)
307
+ {
308
+ if(n < 16) {
309
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
310
+ unsigned char h = 0x90 | (uint8_t) n;
311
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), h);
312
+ } else if(n < 65536) {
313
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
314
+ uint16_t be = _msgpack_be16(n);
315
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdc, (const void*)&be, 2);
316
+ } else {
317
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
318
+ uint32_t be = _msgpack_be32(n);
319
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdd, (const void*)&be, 4);
320
+ }
321
+ }
322
+
323
+ static inline void msgpack_packer_write_map_header(msgpack_packer_t* pk, unsigned int n)
324
+ {
325
+ if(n < 16) {
326
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
327
+ unsigned char h = 0x80 | (uint8_t) n;
328
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), h);
329
+ } else if(n < 65536) {
330
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
331
+ uint16_t be = _msgpack_be16(n);
332
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xde, (const void*)&be, 2);
333
+ } else {
334
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
335
+ uint32_t be = _msgpack_be32(n);
336
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdf, (const void*)&be, 4);
337
+ }
338
+ }
339
+
340
+ static inline char *object_id_string(VALUE object)
341
+ {
342
+ VALUE object_id = rb_funcall(object, rb_intern("object_id"), 0);
343
+ VALUE object_id_str = rb_funcall(object_id, rb_intern("to_s"), 0);
344
+ return StringValuePtr(object_id_str);
345
+ }
346
+
347
+ static inline bool is_byte_array(VALUE string)
348
+ {
349
+ VALUE ascii_8bit = rb_eval_string("Encoding::ASCII_8BIT");
350
+ VALUE string_encoding = rb_funcall(string, rb_intern("encoding"), 0);
351
+
352
+ if (strcmp(object_id_string(ascii_8bit), object_id_string(string_encoding)) == 0) {
353
+ return true;
354
+ } else {
355
+ return false;
356
+ }
357
+ }
358
+
359
+
360
+ void _msgpack_packer_write_string_to_io(msgpack_packer_t* pk, VALUE string);
361
+
362
+ static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE v)
363
+ {
364
+ /* TODO encoding conversion? */
365
+ /* actual return type of RSTRING_LEN is long */
366
+ unsigned long len = RSTRING_LEN(v);
367
+ if(len > 0xffffffffUL) {
368
+ // TODO rb_eArgError?
369
+ rb_raise(rb_eArgError, "size of string is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL);
370
+ }
371
+
372
+ if(is_byte_array(v)) {
373
+ msgpack_packer_write_bin_header(pk, (unsigned int)len);
374
+ } else {
375
+ msgpack_packer_write_raw_header(pk, (unsigned int)len);
376
+ }
377
+ msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
378
+ }
379
+
380
+ static inline void msgpack_packer_write_symbol_value(msgpack_packer_t* pk, VALUE v)
381
+ {
382
+ #ifdef HAVE_RB_SYM2STR
383
+ /* rb_sym2str is added since MRI 2.2.0 */
384
+ msgpack_packer_write_string_value(pk, rb_sym2str(v));
385
+ #else
386
+ const char* name = rb_id2name(SYM2ID(v));
387
+ unsigned long len = strlen(name);
388
+ /* actual return type of strlen is size_t */
389
+ if(len > 0xffffffffUL) {
390
+ // TODO rb_eArgError?
391
+ rb_raise(rb_eArgError, "size of symbol is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL);
392
+ }
393
+ msgpack_packer_write_raw_header(pk, (unsigned int)len);
394
+ msgpack_buffer_append(PACKER_BUFFER_(pk), name, len);
395
+ #endif
396
+ }
397
+
398
+ static inline void msgpack_packer_write_fixnum_value(msgpack_packer_t* pk, VALUE v)
399
+ {
400
+ #ifdef JRUBY
401
+ msgpack_packer_write_long(pk, FIXNUM_P(v) ? FIX2LONG(v) : rb_num2ll(v));
402
+ #else
403
+ msgpack_packer_write_long(pk, FIX2LONG(v));
404
+ #endif
405
+ }
406
+
407
+ static inline void msgpack_packer_write_bignum_value(msgpack_packer_t* pk, VALUE v)
408
+ {
409
+ if(RBIGNUM_POSITIVE_P(v)) {
410
+ msgpack_packer_write_u64(pk, rb_big2ull(v));
411
+ } else {
412
+ msgpack_packer_write_long_long(pk, rb_big2ll(v));
413
+ }
414
+ }
415
+
416
+ static inline void msgpack_packer_write_float_value(msgpack_packer_t* pk, VALUE v)
417
+ {
418
+ msgpack_packer_write_double(pk, rb_num2dbl(v));
419
+ }
420
+
421
+ void msgpack_packer_write_array_value(msgpack_packer_t* pk, VALUE v);
422
+
423
+ void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v);
424
+
425
+ void msgpack_packer_write_value(msgpack_packer_t* pk, VALUE v);
426
+
427
+
428
+ #endif
429
+
@@ -0,0 +1,302 @@
1
+ /*
2
+ * MessagePack for Ruby
3
+ *
4
+ * Copyright (C) 2008-2013 Sadayuki Furuhashi
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ #include "compat.h"
20
+ #include "ruby.h"
21
+ #include "packer.h"
22
+ #include "packer_class.h"
23
+ #include "buffer_class.h"
24
+
25
+ VALUE cMessagePack_Packer;
26
+
27
+ static ID s_to_msgpack;
28
+ static ID s_write;
29
+
30
+ //static VALUE s_packer_value;
31
+ //static msgpack_packer_t* s_packer;
32
+
33
+ #define PACKER(from, name) \
34
+ msgpack_packer_t* name; \
35
+ Data_Get_Struct(from, msgpack_packer_t, name); \
36
+ if(name == NULL) { \
37
+ rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \
38
+ }
39
+
40
+ static void Packer_free(msgpack_packer_t* pk)
41
+ {
42
+ if(pk == NULL) {
43
+ return;
44
+ }
45
+ msgpack_packer_destroy(pk);
46
+ free(pk);
47
+ }
48
+
49
+ static VALUE Packer_alloc(VALUE klass)
50
+ {
51
+ msgpack_packer_t* pk = ALLOC_N(msgpack_packer_t, 1);
52
+ msgpack_packer_init(pk);
53
+
54
+ VALUE self = Data_Wrap_Struct(klass, msgpack_packer_mark, Packer_free, pk);
55
+
56
+ msgpack_packer_set_to_msgpack_method(pk, s_to_msgpack, self);
57
+ pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
58
+
59
+ return self;
60
+ }
61
+
62
+ static VALUE Packer_initialize(int argc, VALUE* argv, VALUE self)
63
+ {
64
+ VALUE io = Qnil;
65
+ VALUE options = Qnil;
66
+
67
+ if(argc == 0 || (argc == 1 && argv[0] == Qnil)) {
68
+ /* Qnil */
69
+
70
+ } else if(argc == 1) {
71
+ VALUE v = argv[0];
72
+ if(rb_type(v) == T_HASH) {
73
+ options = v;
74
+ } else {
75
+ io = v;
76
+ }
77
+
78
+ } else if(argc == 2) {
79
+ io = argv[0];
80
+ options = argv[1];
81
+ if(rb_type(options) != T_HASH) {
82
+ rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
83
+ }
84
+
85
+ } else {
86
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
87
+ }
88
+
89
+ PACKER(self, pk);
90
+ MessagePack_Buffer_initialize(PACKER_BUFFER_(pk), io, options);
91
+
92
+ // TODO MessagePack_Unpacker_initialize and options
93
+
94
+ return self;
95
+ }
96
+
97
+ static VALUE Packer_buffer(VALUE self)
98
+ {
99
+ PACKER(self, pk);
100
+ return pk->buffer_ref;
101
+ }
102
+
103
+ static VALUE Packer_write(VALUE self, VALUE v)
104
+ {
105
+ PACKER(self, pk);
106
+ msgpack_packer_write_value(pk, v);
107
+ return self;
108
+ }
109
+
110
+ static VALUE Packer_write_nil(VALUE self)
111
+ {
112
+ PACKER(self, pk);
113
+ msgpack_packer_write_nil(pk);
114
+ return self;
115
+ }
116
+
117
+ static VALUE Packer_write_array_header(VALUE self, VALUE n)
118
+ {
119
+ PACKER(self, pk);
120
+ msgpack_packer_write_array_header(pk, NUM2UINT(n));
121
+ return self;
122
+ }
123
+
124
+ static VALUE Packer_write_map_header(VALUE self, VALUE n)
125
+ {
126
+ PACKER(self, pk);
127
+ msgpack_packer_write_map_header(pk, NUM2UINT(n));
128
+ return self;
129
+ }
130
+
131
+ static VALUE Packer_flush(VALUE self)
132
+ {
133
+ PACKER(self, pk);
134
+ msgpack_buffer_flush(PACKER_BUFFER_(pk));
135
+ return self;
136
+ }
137
+
138
+ static VALUE Packer_clear(VALUE self)
139
+ {
140
+ PACKER(self, pk);
141
+ msgpack_buffer_clear(PACKER_BUFFER_(pk));
142
+ return Qnil;
143
+ }
144
+
145
+ static VALUE Packer_size(VALUE self)
146
+ {
147
+ PACKER(self, pk);
148
+ size_t size = msgpack_buffer_all_readable_size(PACKER_BUFFER_(pk));
149
+ return SIZET2NUM(size);
150
+ }
151
+
152
+ static VALUE Packer_empty_p(VALUE self)
153
+ {
154
+ PACKER(self, pk);
155
+ if(msgpack_buffer_top_readable_size(PACKER_BUFFER_(pk)) == 0) {
156
+ return Qtrue;
157
+ } else {
158
+ return Qfalse;
159
+ }
160
+ }
161
+
162
+ static VALUE Packer_to_str(VALUE self)
163
+ {
164
+ PACKER(self, pk);
165
+ return msgpack_buffer_all_as_string(PACKER_BUFFER_(pk));
166
+ }
167
+
168
+ static VALUE Packer_to_a(VALUE self)
169
+ {
170
+ PACKER(self, pk);
171
+ return msgpack_buffer_all_as_string_array(PACKER_BUFFER_(pk));
172
+ }
173
+
174
+ static VALUE Packer_write_to(VALUE self, VALUE io)
175
+ {
176
+ PACKER(self, pk);
177
+ size_t sz = msgpack_buffer_flush_to_io(PACKER_BUFFER_(pk), io, s_write, true);
178
+ return ULONG2NUM(sz);
179
+ }
180
+
181
+ //static VALUE Packer_append(VALUE self, VALUE string_or_buffer)
182
+ //{
183
+ // PACKER(self, pk);
184
+ //
185
+ // // TODO if string_or_buffer is a Buffer
186
+ // VALUE string = string_or_buffer;
187
+ //
188
+ // msgpack_buffer_append_string(PACKER_BUFFER_(pk), string);
189
+ //
190
+ // return self;
191
+ //}
192
+
193
+ VALUE MessagePack_pack(int argc, VALUE* argv)
194
+ {
195
+ VALUE v;
196
+ VALUE io = Qnil;
197
+ VALUE options = Qnil;
198
+
199
+ if(argc == 1) {
200
+ v = argv[0];
201
+
202
+ } else if(argc == 2) {
203
+ v = argv[0];
204
+ if(rb_type(argv[1]) == T_HASH) {
205
+ options = argv[1];
206
+ } else {
207
+ io = argv[1];
208
+ }
209
+
210
+ } else if(argc == 3) {
211
+ v = argv[0];
212
+ io = argv[1];
213
+ options = argv[2];
214
+ if(rb_type(options) != T_HASH) {
215
+ rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
216
+ }
217
+
218
+ } else {
219
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", argc);
220
+ }
221
+
222
+ VALUE self = Packer_alloc(cMessagePack_Packer);
223
+ PACKER(self, pk);
224
+ //msgpack_packer_reset(s_packer);
225
+ //msgpack_buffer_reset_io(PACKER_BUFFER_(s_packer));
226
+
227
+ MessagePack_Buffer_initialize(PACKER_BUFFER_(pk), io, options);
228
+ // TODO MessagePack_Unpacker_initialize and options
229
+
230
+ msgpack_packer_write_value(pk, v);
231
+
232
+ VALUE retval;
233
+ if(io != Qnil) {
234
+ msgpack_buffer_flush(PACKER_BUFFER_(pk));
235
+ retval = Qnil;
236
+ } else {
237
+ retval = msgpack_buffer_all_as_string(PACKER_BUFFER_(pk));
238
+ }
239
+
240
+ msgpack_buffer_clear(PACKER_BUFFER_(pk)); /* to free rmem before GC */
241
+
242
+ #ifdef RB_GC_GUARD
243
+ /* This prevents compilers from optimizing out the `self` variable
244
+ * from stack. Otherwise GC free()s it. */
245
+ RB_GC_GUARD(self);
246
+ #endif
247
+
248
+ return retval;
249
+ }
250
+
251
+ static VALUE MessagePack_dump_module_method(int argc, VALUE* argv, VALUE mod)
252
+ {
253
+ UNUSED(mod);
254
+ return MessagePack_pack(argc, argv);
255
+ }
256
+
257
+ static VALUE MessagePack_pack_module_method(int argc, VALUE* argv, VALUE mod)
258
+ {
259
+ UNUSED(mod);
260
+ return MessagePack_pack(argc, argv);
261
+ }
262
+
263
+ void MessagePack_Packer_module_init(VALUE mMessagePack)
264
+ {
265
+ s_to_msgpack = rb_intern("to_msgpack");
266
+ s_write = rb_intern("write");
267
+
268
+ msgpack_packer_static_init();
269
+
270
+ cMessagePack_Packer = rb_define_class_under(mMessagePack, "Packer", rb_cObject);
271
+
272
+ rb_define_alloc_func(cMessagePack_Packer, Packer_alloc);
273
+
274
+ rb_define_method(cMessagePack_Packer, "initialize", Packer_initialize, -1);
275
+ rb_define_method(cMessagePack_Packer, "buffer", Packer_buffer, 0);
276
+ rb_define_method(cMessagePack_Packer, "write", Packer_write, 1);
277
+ rb_define_alias(cMessagePack_Packer, "pack", "write");
278
+ rb_define_method(cMessagePack_Packer, "write_nil", Packer_write_nil, 0);
279
+ rb_define_method(cMessagePack_Packer, "write_array_header", Packer_write_array_header, 1);
280
+ rb_define_method(cMessagePack_Packer, "write_map_header", Packer_write_map_header, 1);
281
+ rb_define_method(cMessagePack_Packer, "flush", Packer_flush, 0);
282
+
283
+ /* delegation methods */
284
+ rb_define_method(cMessagePack_Packer, "clear", Packer_clear, 0);
285
+ rb_define_method(cMessagePack_Packer, "size", Packer_size, 0);
286
+ rb_define_method(cMessagePack_Packer, "empty?", Packer_empty_p, 0);
287
+ rb_define_method(cMessagePack_Packer, "write_to", Packer_write_to, 1);
288
+ rb_define_method(cMessagePack_Packer, "to_str", Packer_to_str, 0);
289
+ rb_define_alias(cMessagePack_Packer, "to_s", "to_str");
290
+ rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0);
291
+ //rb_define_method(cMessagePack_Packer, "append", Packer_append, 1);
292
+ //rb_define_alias(cMessagePack_Packer, "<<", "append");
293
+
294
+ //s_packer_value = Packer_alloc(cMessagePack_Packer);
295
+ //rb_gc_register_address(&s_packer_value);
296
+ //Data_Get_Struct(s_packer_value, msgpack_packer_t, s_packer);
297
+
298
+ /* MessagePack.pack(x) */
299
+ rb_define_module_function(mMessagePack, "pack", MessagePack_pack_module_method, -1);
300
+ rb_define_module_function(mMessagePack, "dump", MessagePack_dump_module_method, -1);
301
+ }
302
+