msgpack 0.4.7 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/.gitignore +17 -0
  2. data/ChangeLog +47 -0
  3. data/README.rdoc +102 -0
  4. data/Rakefile +88 -0
  5. data/doclib/msgpack.rb +55 -0
  6. data/doclib/msgpack/buffer.rb +193 -0
  7. data/doclib/msgpack/core_ext.rb +101 -0
  8. data/doclib/msgpack/error.rb +14 -0
  9. data/doclib/msgpack/packer.rb +131 -0
  10. data/doclib/msgpack/unpacker.rb +130 -0
  11. data/ext/msgpack/buffer.c +679 -0
  12. data/ext/msgpack/buffer.h +442 -0
  13. data/ext/msgpack/buffer_class.c +507 -0
  14. data/ext/msgpack/buffer_class.h +32 -0
  15. data/ext/msgpack/compat.h +112 -0
  16. data/ext/msgpack/core_ext.c +129 -0
  17. data/ext/{pack.h → msgpack/core_ext.h} +7 -7
  18. data/ext/msgpack/extconf.rb +17 -0
  19. data/ext/msgpack/packer.c +137 -0
  20. data/ext/msgpack/packer.h +319 -0
  21. data/ext/msgpack/packer_class.c +285 -0
  22. data/ext/{unpack.h → msgpack/packer_class.h} +11 -7
  23. data/ext/msgpack/rbinit.c +33 -0
  24. data/ext/msgpack/rmem.c +110 -0
  25. data/ext/msgpack/rmem.h +100 -0
  26. data/ext/msgpack/sysdep.h +115 -0
  27. data/ext/msgpack/sysdep_endian.h +50 -0
  28. data/ext/msgpack/sysdep_types.h +46 -0
  29. data/ext/msgpack/unpacker.c +669 -0
  30. data/ext/msgpack/unpacker.h +112 -0
  31. data/ext/msgpack/unpacker_class.c +376 -0
  32. data/{msgpack/pack_define.h → ext/msgpack/unpacker_class.h} +12 -8
  33. data/lib/msgpack.rb +10 -0
  34. data/{ext → lib/msgpack}/version.rb +1 -1
  35. data/msgpack.gemspec +25 -0
  36. data/spec/buffer_io_spec.rb +237 -0
  37. data/spec/buffer_spec.rb +572 -0
  38. data/{test → spec}/cases.json +0 -0
  39. data/{test/cases.mpac → spec/cases.msg} +0 -0
  40. data/{test/cases_compact.mpac → spec/cases_compact.msg} +0 -0
  41. data/spec/cases_spec.rb +39 -0
  42. data/spec/format_spec.rb +225 -0
  43. data/spec/packer_spec.rb +127 -0
  44. data/spec/random_compat.rb +24 -0
  45. data/spec/spec_helper.rb +21 -0
  46. data/spec/unpacker_spec.rb +128 -0
  47. metadata +171 -34
  48. data/ext/compat.h +0 -99
  49. data/ext/extconf.rb +0 -7
  50. data/ext/pack.c +0 -314
  51. data/ext/rbinit.c +0 -66
  52. data/ext/unpack.c +0 -1001
  53. data/msgpack/pack_template.h +0 -771
  54. data/msgpack/sysdep.h +0 -195
  55. data/msgpack/unpack_define.h +0 -93
  56. data/msgpack/unpack_template.h +0 -413
  57. data/test/test_cases.rb +0 -46
  58. data/test/test_encoding.rb +0 -68
  59. data/test/test_helper.rb +0 -10
  60. data/test/test_pack_unpack.rb +0 -308
@@ -0,0 +1,319 @@
1
+ /*
2
+ * MessagePack for Ruby
3
+ *
4
+ * Copyright (C) 2008-2012 FURUHASHI Sadayuki
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_init(msgpack_packer_t* pk);
45
+
46
+ void msgpack_packer_destroy(msgpack_packer_t* pk);
47
+
48
+ void msgpack_packer_mark(msgpack_packer_t* pk);
49
+
50
+ static inline void msgpack_packer_set_to_msgpack_method(msgpack_packer_t* pk,
51
+ ID to_msgpack_method, VALUE to_msgpack_arg)
52
+ {
53
+ pk->to_msgpack_method = to_msgpack_method;
54
+ pk->to_msgpack_arg = to_msgpack_arg;
55
+ }
56
+
57
+ static inline void msgpack_packer_set_io(msgpack_packer_t* pk, VALUE io, ID io_write_all_method)
58
+ {
59
+ pk->io = io;
60
+ pk->io_write_all_method = io_write_all_method;
61
+ }
62
+
63
+ void msgpack_packer_reset(msgpack_packer_t* pk);
64
+
65
+
66
+ static inline void msgpack_packer_write_nil(msgpack_packer_t* pk)
67
+ {
68
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
69
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), 0xc0);
70
+ }
71
+
72
+ static inline void msgpack_packer_write_true(msgpack_packer_t* pk)
73
+ {
74
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
75
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), 0xc3);
76
+ }
77
+
78
+ static inline void msgpack_packer_write_false(msgpack_packer_t* pk)
79
+ {
80
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
81
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), 0xc2);
82
+ }
83
+
84
+ static inline void _msgpack_packer_write_fixint(msgpack_packer_t* pk, int8_t v)
85
+ {
86
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
87
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), v);
88
+ }
89
+
90
+ static inline void _msgpack_packer_write_uint8(msgpack_packer_t* pk, uint8_t v)
91
+ {
92
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 2);
93
+ msgpack_buffer_write_2(PACKER_BUFFER_(pk), 0xcc, v);
94
+ }
95
+
96
+ static inline void _msgpack_packer_write_uint16(msgpack_packer_t* pk, uint16_t v)
97
+ {
98
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
99
+ uint16_t be = _msgpack_be16(v);
100
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xcd, (const void*)&be, 2);
101
+ }
102
+
103
+ static inline void _msgpack_packer_write_uint32(msgpack_packer_t* pk, uint32_t v)
104
+ {
105
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
106
+ uint32_t be = _msgpack_be32(v);
107
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xce, (const void*)&be, 4);
108
+ }
109
+
110
+ static inline void _msgpack_packer_write_uint64(msgpack_packer_t* pk, uint64_t v)
111
+ {
112
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9);
113
+ uint64_t be = _msgpack_be64(v);
114
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xcf, (const void*)&be, 8);
115
+ }
116
+
117
+ static inline void _msgpack_packer_write_int8(msgpack_packer_t* pk, int8_t v)
118
+ {
119
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 2);
120
+ msgpack_buffer_write_2(PACKER_BUFFER_(pk), 0xd0, v);
121
+ }
122
+
123
+ static inline void _msgpack_packer_write_int16(msgpack_packer_t* pk, int16_t v)
124
+ {
125
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
126
+ uint16_t be = _msgpack_be16(v);
127
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xd1, (const void*)&be, 2);
128
+ }
129
+
130
+ static inline void _msgpack_packer_write_int32(msgpack_packer_t* pk, int32_t v)
131
+ {
132
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
133
+ uint32_t be = _msgpack_be32(v);
134
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xd2, (const void*)&be, 4);
135
+ }
136
+
137
+ static inline void _msgpack_packer_write_int64(msgpack_packer_t* pk, int64_t v)
138
+ {
139
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9);
140
+ uint64_t be = _msgpack_be64(v);
141
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xd3, (const void*)&be, 8);
142
+ }
143
+
144
+ static inline void msgpack_packer_write_long(msgpack_packer_t* pk, long v)
145
+ {
146
+ if(v < -0x20L) {
147
+ if(v < -0x8000L) {
148
+ if(v < -0x80000000L) {
149
+ _msgpack_packer_write_int64(pk, (int64_t) v);
150
+ } else {
151
+ _msgpack_packer_write_int32(pk, (int32_t) v);
152
+ }
153
+ } else {
154
+ if(v < -0x80L) {
155
+ _msgpack_packer_write_int16(pk, (int16_t) v);
156
+ } else {
157
+ _msgpack_packer_write_int8(pk, (int8_t) v);
158
+ }
159
+ }
160
+ } else if(v <= 0x7fL) {
161
+ _msgpack_packer_write_fixint(pk, (int8_t) v);
162
+ } else {
163
+ if(v <= 0xffffL) {
164
+ if(v <= 0xffL) {
165
+ _msgpack_packer_write_uint8(pk, (uint8_t) v);
166
+ } else {
167
+ _msgpack_packer_write_uint16(pk, (uint16_t) v);
168
+ }
169
+ } else {
170
+ if(v <= 0xffffffffL) {
171
+ _msgpack_packer_write_uint32(pk, (uint32_t) v);
172
+ } else {
173
+ _msgpack_packer_write_uint64(pk, (uint64_t) v);
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ static inline void msgpack_packer_write_u64(msgpack_packer_t* pk, uint64_t v)
180
+ {
181
+ if(v <= 0xffULL) {
182
+ if(v <= 0x7fULL) {
183
+ _msgpack_packer_write_fixint(pk, (int8_t) v);
184
+ } else {
185
+ _msgpack_packer_write_uint8(pk, (uint8_t) v);
186
+ }
187
+ } else {
188
+ if(v <= 0xffffULL) {
189
+ _msgpack_packer_write_uint16(pk, (uint16_t) v);
190
+ } else if(v <= 0xffffffffULL) {
191
+ _msgpack_packer_write_uint32(pk, (uint32_t) v);
192
+ } else {
193
+ _msgpack_packer_write_uint64(pk, (uint64_t) v);
194
+ }
195
+ }
196
+ }
197
+
198
+ static inline void msgpack_packer_write_double(msgpack_packer_t* pk, double v)
199
+ {
200
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9);
201
+ union {
202
+ double d;
203
+ uint64_t u64;
204
+ char mem[8];
205
+ } castbuf = { v };
206
+ castbuf.u64 = _msgpack_be_double(castbuf.u64);
207
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xcb, castbuf.mem, 8);
208
+ }
209
+
210
+ static inline void msgpack_packer_write_raw_header(msgpack_packer_t* pk, unsigned int n)
211
+ {
212
+ if(n < 32) {
213
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
214
+ unsigned char h = 0xa0 | (uint8_t) n;
215
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), h);
216
+ } else if(n < 65536) {
217
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
218
+ uint16_t be = _msgpack_be16(n);
219
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xda, (const void*)&be, 2);
220
+ } else {
221
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
222
+ uint32_t be = _msgpack_be32(n);
223
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdb, (const void*)&be, 4);
224
+ }
225
+ }
226
+
227
+ static inline void msgpack_packer_write_array_header(msgpack_packer_t* pk, unsigned int n)
228
+ {
229
+ if(n < 16) {
230
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
231
+ unsigned char h = 0x90 | (uint8_t) n;
232
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), h);
233
+ } else if(n < 65536) {
234
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
235
+ uint16_t be = _msgpack_be16(n);
236
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdc, (const void*)&be, 2);
237
+ } else {
238
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
239
+ uint32_t be = _msgpack_be32(n);
240
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdd, (const void*)&be, 4);
241
+ }
242
+ }
243
+
244
+ static inline void msgpack_packer_write_map_header(msgpack_packer_t* pk, unsigned int n)
245
+ {
246
+ if(n < 16) {
247
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1);
248
+ unsigned char h = 0x80 | (uint8_t) n;
249
+ msgpack_buffer_write_1(PACKER_BUFFER_(pk), h);
250
+ } else if(n < 65536) {
251
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3);
252
+ uint16_t be = _msgpack_be16(n);
253
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xde, (const void*)&be, 2);
254
+ } else {
255
+ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5);
256
+ uint32_t be = _msgpack_be32(n);
257
+ msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), 0xdf, (const void*)&be, 4);
258
+ }
259
+ }
260
+
261
+
262
+ void _msgpack_packer_write_string_to_io(msgpack_packer_t* pk, VALUE string);
263
+
264
+ static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE v)
265
+ {
266
+ /* TODO encoding conversion? */
267
+ size_t len = RSTRING_LEN(v);
268
+ if(len > 0xffffffffUL) {
269
+ // TODO rb_eArgError?
270
+ rb_raise(rb_eArgError, "size of string is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL);
271
+ }
272
+ msgpack_packer_write_raw_header(pk, (unsigned int)len);
273
+ msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
274
+ }
275
+
276
+ static inline void msgpack_packer_write_symbol_value(msgpack_packer_t* pk, VALUE v)
277
+ {
278
+ const char* name = rb_id2name(SYM2ID(v));
279
+ size_t len = strlen(name);
280
+ if(len > 0xffffffffUL) {
281
+ // TODO rb_eArgError?
282
+ rb_raise(rb_eArgError, "size of symbol is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL);
283
+ }
284
+ msgpack_packer_write_raw_header(pk, (unsigned int)len);
285
+ msgpack_buffer_append(PACKER_BUFFER_(pk), name, len);
286
+ }
287
+
288
+ static inline void msgpack_packer_write_fixnum_value(msgpack_packer_t* pk, VALUE v)
289
+ {
290
+ #ifdef JRUBY
291
+ msgpack_packer_write_long(pk, FIXNUM_P(v) ? FIX2LONG(v) : rb_num2ll(v));
292
+ #else
293
+ msgpack_packer_write_long(pk, FIX2LONG(v));
294
+ #endif
295
+ }
296
+
297
+ static inline void msgpack_packer_write_bignum_value(msgpack_packer_t* pk, VALUE v)
298
+ {
299
+ if(RBIGNUM_POSITIVE_P(v)) {
300
+ msgpack_packer_write_u64(pk, rb_big2ull(v));
301
+ } else {
302
+ msgpack_packer_write_long(pk, rb_big2ll(v)); /* TODO long long? */
303
+ }
304
+ }
305
+
306
+ static inline void msgpack_packer_write_float_value(msgpack_packer_t* pk, VALUE v)
307
+ {
308
+ msgpack_packer_write_double(pk, rb_num2dbl(v));
309
+ }
310
+
311
+ void msgpack_packer_write_array_value(msgpack_packer_t* pk, VALUE v);
312
+
313
+ void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v);
314
+
315
+ void msgpack_packer_write_value(msgpack_packer_t* pk, VALUE v);
316
+
317
+
318
+ #endif
319
+
@@ -0,0 +1,285 @@
1
+ /*
2
+ * MessagePack for Ruby
3
+ *
4
+ * Copyright (C) 2008-2012 FURUHASHI Sadayuki
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(io));
83
+ }
84
+
85
+ } else {
86
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc);
87
+ }
88
+
89
+ PACKER(self, pk);
90
+ if(io != Qnil || options != Qnil) {
91
+ MessagePack_Buffer_initialize(PACKER_BUFFER_(pk), io, options);
92
+ }
93
+
94
+ // TODO options
95
+
96
+ return self;
97
+ }
98
+
99
+ static VALUE Packer_buffer(VALUE self)
100
+ {
101
+ PACKER(self, pk);
102
+ return pk->buffer_ref;
103
+ }
104
+
105
+ static VALUE Packer_write(VALUE self, VALUE v)
106
+ {
107
+ PACKER(self, pk);
108
+ msgpack_packer_write_value(pk, v);
109
+ return self;
110
+ }
111
+
112
+ static VALUE Packer_write_nil(VALUE self)
113
+ {
114
+ PACKER(self, pk);
115
+ msgpack_packer_write_nil(pk);
116
+ return self;
117
+ }
118
+
119
+ static VALUE Packer_write_array_header(VALUE self, VALUE n)
120
+ {
121
+ PACKER(self, pk);
122
+ msgpack_packer_write_array_header(pk, NUM2UINT(n));
123
+ return self;
124
+ }
125
+
126
+ static VALUE Packer_write_map_header(VALUE self, VALUE n)
127
+ {
128
+ PACKER(self, pk);
129
+ msgpack_packer_write_map_header(pk, NUM2UINT(n));
130
+ return self;
131
+ }
132
+
133
+ static VALUE Packer_flush(VALUE self)
134
+ {
135
+ PACKER(self, pk);
136
+ msgpack_buffer_flush(PACKER_BUFFER_(pk));
137
+ return self;
138
+ }
139
+
140
+ static VALUE Packer_clear(VALUE self)
141
+ {
142
+ PACKER(self, pk);
143
+ msgpack_buffer_clear(PACKER_BUFFER_(pk));
144
+ return Qnil;
145
+ }
146
+
147
+ static VALUE Packer_size(VALUE self)
148
+ {
149
+ PACKER(self, pk);
150
+ size_t size = msgpack_buffer_all_readable_size(PACKER_BUFFER_(pk));
151
+ return SIZET2NUM(size);
152
+ }
153
+
154
+ static VALUE Packer_empty_p(VALUE self)
155
+ {
156
+ PACKER(self, pk);
157
+ if(msgpack_buffer_top_readable_size(PACKER_BUFFER_(pk)) == 0) {
158
+ return Qtrue;
159
+ } else {
160
+ return Qfalse;
161
+ }
162
+ }
163
+
164
+ static VALUE Packer_to_str(VALUE self)
165
+ {
166
+ PACKER(self, pk);
167
+ return msgpack_buffer_all_as_string(PACKER_BUFFER_(pk));
168
+ }
169
+
170
+ static VALUE Packer_to_a(VALUE self)
171
+ {
172
+ PACKER(self, pk);
173
+ return msgpack_buffer_all_as_string_array(PACKER_BUFFER_(pk));
174
+ }
175
+
176
+ static VALUE Packer_write_to(VALUE self, VALUE io)
177
+ {
178
+ PACKER(self, pk);
179
+ size_t sz = msgpack_buffer_flush_to_io(PACKER_BUFFER_(pk), io, s_write, true);
180
+ return ULONG2NUM(sz);
181
+ }
182
+
183
+ //static VALUE Packer_append(VALUE self, VALUE string_or_buffer)
184
+ //{
185
+ // PACKER(self, pk);
186
+ //
187
+ // // TODO if string_or_buffer is a Buffer
188
+ // VALUE string = string_or_buffer;
189
+ //
190
+ // msgpack_buffer_append_string(PACKER_BUFFER_(pk), string);
191
+ //
192
+ // return self;
193
+ //}
194
+
195
+ VALUE MessagePack_pack(int argc, VALUE* argv)
196
+ {
197
+ // TODO options
198
+
199
+ VALUE v;
200
+ VALUE io = Qnil;
201
+
202
+ switch(argc) {
203
+ case 2:
204
+ io = argv[1];
205
+ /* pass-through */
206
+ case 1:
207
+ v = argv[0];
208
+ break;
209
+ default:
210
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc);
211
+ }
212
+
213
+ VALUE self = Packer_alloc(cMessagePack_Packer);
214
+ PACKER(self, pk);
215
+ //msgpack_packer_reset(s_packer);
216
+ //msgpack_buffer_reset_io(PACKER_BUFFER_(s_packer));
217
+
218
+ if(io != Qnil) {
219
+ MessagePack_Buffer_initialize(PACKER_BUFFER_(pk), io, Qnil);
220
+ }
221
+
222
+ msgpack_packer_write_value(pk, v);
223
+
224
+ VALUE retval;
225
+ if(io != Qnil) {
226
+ msgpack_buffer_flush(PACKER_BUFFER_(pk));
227
+ retval = Qnil;
228
+ } else {
229
+ retval = msgpack_buffer_all_as_string(PACKER_BUFFER_(pk));
230
+ }
231
+
232
+ msgpack_buffer_clear(PACKER_BUFFER_(pk)); /* to free rmem before GC */
233
+ return retval;
234
+ }
235
+
236
+ static VALUE MessagePack_dump_module_method(int argc, VALUE* argv, VALUE mod)
237
+ {
238
+ UNUSED(mod);
239
+ return MessagePack_pack(argc, argv);
240
+ }
241
+
242
+ static VALUE MessagePack_pack_module_method(int argc, VALUE* argv, VALUE mod)
243
+ {
244
+ UNUSED(mod);
245
+ return MessagePack_pack(argc, argv);
246
+ }
247
+
248
+ void MessagePack_Packer_module_init(VALUE mMessagePack)
249
+ {
250
+ s_to_msgpack = rb_intern("to_msgpack");
251
+ s_write = rb_intern("write");
252
+
253
+ cMessagePack_Packer = rb_define_class_under(mMessagePack, "Packer", rb_cObject);
254
+
255
+ rb_define_alloc_func(cMessagePack_Packer, Packer_alloc);
256
+
257
+ rb_define_method(cMessagePack_Packer, "initialize", Packer_initialize, -1);
258
+ rb_define_method(cMessagePack_Packer, "buffer", Packer_buffer, 0);
259
+ rb_define_method(cMessagePack_Packer, "write", Packer_write, 1);
260
+ rb_define_alias(cMessagePack_Packer, "pack", "write");
261
+ rb_define_method(cMessagePack_Packer, "write_nil", Packer_write_nil, 0);
262
+ rb_define_method(cMessagePack_Packer, "write_array_header", Packer_write_array_header, 1);
263
+ rb_define_method(cMessagePack_Packer, "write_map_header", Packer_write_map_header, 1);
264
+ rb_define_method(cMessagePack_Packer, "flush", Packer_flush, 0);
265
+
266
+ /* delegation methods */
267
+ rb_define_method(cMessagePack_Packer, "clear", Packer_clear, 0);
268
+ rb_define_method(cMessagePack_Packer, "size", Packer_size, 0);
269
+ rb_define_method(cMessagePack_Packer, "empty?", Packer_empty_p, 0);
270
+ rb_define_method(cMessagePack_Packer, "write_to", Packer_write_to, 1);
271
+ rb_define_method(cMessagePack_Packer, "to_str", Packer_to_str, 0);
272
+ rb_define_alias(cMessagePack_Packer, "to_s", "to_str");
273
+ rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0);
274
+ //rb_define_method(cMessagePack_Packer, "append", Packer_append, 1);
275
+ //rb_define_alias(cMessagePack_Packer, "<<", "append");
276
+
277
+ //s_packer_value = Packer_alloc(cMessagePack_Packer);
278
+ //rb_gc_register_address(&s_packer_value);
279
+ //Data_Get_Struct(s_packer_value, msgpack_packer_t, s_packer);
280
+
281
+ /* MessagePack.pack(x) */
282
+ rb_define_module_function(mMessagePack, "pack", MessagePack_pack_module_method, -1);
283
+ rb_define_module_function(mMessagePack, "dump", MessagePack_dump_module_method, -1);
284
+ }
285
+