mochilo 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +9 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +30 -0
- data/README.md +56 -0
- data/Rakefile +33 -0
- data/docs/format-spec.md +46 -0
- data/docs/why-banana-pack.md +25 -0
- data/ext/mochilo/buffer.c +141 -0
- data/ext/mochilo/buffer.h +146 -0
- data/ext/mochilo/encodings.h +400 -0
- data/ext/mochilo/extconf.rb +5 -0
- data/ext/mochilo/mochilo.h +158 -0
- data/ext/mochilo/mochilo.rb.c +119 -0
- data/ext/mochilo/mochilo_api.h +91 -0
- data/ext/mochilo/mochilo_pack.c +331 -0
- data/ext/mochilo/mochilo_unpack.c +279 -0
- data/genperf.rb +14 -0
- data/lib/mochilo.rb +11 -0
- data/lib/mochilo/console.rb +5 -0
- data/lib/mochilo/version.rb +3 -0
- data/mochilo.gemspec +24 -0
- data/script/benchmark +43 -0
- data/script/bootstrap +16 -0
- data/script/console +7 -0
- data/script/testsuite +10 -0
- data/test/assets/pulls.json +6934 -0
- data/test/pack_test.rb +172 -0
- data/test/setup.rb +16 -0
- data/test/unpack_test.rb +159 -0
- metadata +116 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2012, GitHub, Inc
|
3
|
+
*
|
4
|
+
* Permission to use, copy, modify, and distribute this software for any
|
5
|
+
* purpose with or without fee is hereby granted, provided that the above
|
6
|
+
* copyright notice and this permission notice appear in all copies.
|
7
|
+
*
|
8
|
+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
9
|
+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
10
|
+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
11
|
+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
12
|
+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
13
|
+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
14
|
+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
15
|
+
*/
|
16
|
+
#include <stdio.h>
|
17
|
+
#include "mochilo.h"
|
18
|
+
|
19
|
+
#define CSTR2SYM(s) (ID2SYM(rb_intern((s))))
|
20
|
+
|
21
|
+
static VALUE rb_mMochilo;
|
22
|
+
static VALUE rb_eMochiloError;
|
23
|
+
VALUE rb_eMochiloPackError;
|
24
|
+
VALUE rb_eMochiloUnpackError;
|
25
|
+
|
26
|
+
extern void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object, int trusted);
|
27
|
+
|
28
|
+
static VALUE rb_mochilo__unpack(VALUE rb_buffer, int trusted)
|
29
|
+
{
|
30
|
+
VALUE rb_result;
|
31
|
+
int error = -1;
|
32
|
+
mochilo_src source;
|
33
|
+
|
34
|
+
Check_Type(rb_buffer, T_STRING);
|
35
|
+
|
36
|
+
source.ptr = RSTRING_PTR(rb_buffer);
|
37
|
+
source.end = source.ptr + RSTRING_LEN(rb_buffer);
|
38
|
+
source.trusted = trusted;
|
39
|
+
|
40
|
+
error = mochilo_unpack_one((mo_value)&rb_result, &source);
|
41
|
+
if (error < 0)
|
42
|
+
rb_raise(rb_eMochiloUnpackError, "unpack failed (%d)", error);
|
43
|
+
|
44
|
+
return rb_result;
|
45
|
+
}
|
46
|
+
|
47
|
+
/* Document-method: unpack
|
48
|
+
*
|
49
|
+
* call-seq:
|
50
|
+
* Mochilo.unpack(banana_pack_str) -> Object
|
51
|
+
*
|
52
|
+
* Unpacks a BananaPack stream into a Ruby object.
|
53
|
+
*/
|
54
|
+
static VALUE rb_mochilo_unpack(VALUE self, VALUE rb_buffer)
|
55
|
+
{
|
56
|
+
return rb_mochilo__unpack(rb_buffer, 0);
|
57
|
+
}
|
58
|
+
|
59
|
+
/* Document-method: unpack_unsafe
|
60
|
+
*
|
61
|
+
* call-seq:
|
62
|
+
* Mochilo.unpack_unsafe(banana_pack_str) -> Object
|
63
|
+
*
|
64
|
+
* Unpacks a BananaPack stream into a Ruby object, in unsafe mode.
|
65
|
+
* Only use this function if +banana_pack_str+ is trusted; otherwise
|
66
|
+
* symbol DoS attacks are possible.
|
67
|
+
*/
|
68
|
+
static VALUE rb_mochilo_unpack_unsafe(VALUE self, VALUE rb_buffer)
|
69
|
+
{
|
70
|
+
return rb_mochilo__unpack(rb_buffer, 1);
|
71
|
+
}
|
72
|
+
|
73
|
+
/* Document-method: pack
|
74
|
+
*
|
75
|
+
* call-seq:
|
76
|
+
* Mochilo.pack(obj) -> String
|
77
|
+
*
|
78
|
+
* Packs a Ruby object into BananaPack format.
|
79
|
+
*/
|
80
|
+
static VALUE rb_mochilo_pack(VALUE self, VALUE rb_obj)
|
81
|
+
{
|
82
|
+
mochilo_buf buf;
|
83
|
+
|
84
|
+
mochilo_buf_init(&buf);
|
85
|
+
mochilo_pack_one(&buf, rb_obj, 0);
|
86
|
+
return mochilo_buf_flush(&buf);
|
87
|
+
}
|
88
|
+
|
89
|
+
/* Document-method: pack
|
90
|
+
*
|
91
|
+
* call-seq:
|
92
|
+
* Mochilo.pack_unsafe(obj) -> String
|
93
|
+
*
|
94
|
+
* Packs a Ruby object into BananaPack format, in unsafe mode.
|
95
|
+
* This enables the Symbol type durring serialization and will
|
96
|
+
* have to be deserialized in unsafe mode as well.
|
97
|
+
*/
|
98
|
+
static VALUE rb_mochilo_pack_unsafe(VALUE self, VALUE rb_obj)
|
99
|
+
{
|
100
|
+
mochilo_buf buf;
|
101
|
+
|
102
|
+
mochilo_buf_init(&buf);
|
103
|
+
mochilo_pack_one(&buf, rb_obj, 1);
|
104
|
+
return mochilo_buf_flush(&buf);
|
105
|
+
}
|
106
|
+
|
107
|
+
void Init_mochilo()
|
108
|
+
{
|
109
|
+
rb_mMochilo = rb_define_module("Mochilo");
|
110
|
+
rb_define_method(rb_mMochilo, "unpack", rb_mochilo_unpack, 1);
|
111
|
+
rb_define_method(rb_mMochilo, "unpack_unsafe", rb_mochilo_unpack_unsafe, 1);
|
112
|
+
rb_define_method(rb_mMochilo, "pack", rb_mochilo_pack, 1);
|
113
|
+
rb_define_method(rb_mMochilo, "pack_unsafe", rb_mochilo_pack_unsafe, 1);
|
114
|
+
|
115
|
+
rb_eMochiloError = rb_define_class_under(rb_mMochilo, "Error", rb_eStandardError);
|
116
|
+
rb_eMochiloPackError = rb_define_class_under(rb_mMochilo, "PackError", rb_eMochiloError);
|
117
|
+
rb_eMochiloUnpackError = rb_define_class_under(rb_mMochilo, "UnpackError", rb_eMochiloError);
|
118
|
+
}
|
119
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
|
2
|
+
MOAPI mo_value moapi_bytes_new(const char *src, size_t len)
|
3
|
+
{
|
4
|
+
return (mo_value)rb_str_new(src, len);
|
5
|
+
}
|
6
|
+
|
7
|
+
MOAPI mo_value moapi_sym_new(const char *src, size_t len)
|
8
|
+
{
|
9
|
+
char *symbol;
|
10
|
+
|
11
|
+
if (len > 0xFF)
|
12
|
+
rb_raise(rb_eArgError, "Symbol too long to encode in BananaPack");
|
13
|
+
|
14
|
+
symbol = alloca(len + 1);
|
15
|
+
memcpy(symbol, src, len);
|
16
|
+
symbol[len] = '\0';
|
17
|
+
|
18
|
+
return (mo_value)ID2SYM(rb_intern(symbol));
|
19
|
+
}
|
20
|
+
|
21
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
22
|
+
MOAPI mo_value moapi_str_new(const char *src, size_t len, enum msgpack_enc_t encoding)
|
23
|
+
{
|
24
|
+
int index = 0;
|
25
|
+
VALUE str;
|
26
|
+
|
27
|
+
if (encoding < sizeof(mochilo_enc_lookup)/sizeof(mochilo_enc_lookup[0]))
|
28
|
+
index = rb_enc_find_index(mochilo_enc_lookup[encoding]);
|
29
|
+
|
30
|
+
str = rb_str_new(src, len);
|
31
|
+
rb_enc_set_index(str, index);
|
32
|
+
|
33
|
+
return (mo_value)str;
|
34
|
+
}
|
35
|
+
#endif
|
36
|
+
|
37
|
+
MOAPI mo_value moapi_array_new(size_t array_size)
|
38
|
+
{
|
39
|
+
return (mo_value)rb_ary_new2(array_size);
|
40
|
+
}
|
41
|
+
|
42
|
+
MOAPI void moapi_array_append(mo_value array, mo_value element)
|
43
|
+
{
|
44
|
+
rb_ary_push((VALUE)array, (VALUE)element);
|
45
|
+
}
|
46
|
+
|
47
|
+
MOAPI mo_value moapi_hash_new(void)
|
48
|
+
{
|
49
|
+
return (mo_value)rb_hash_new();
|
50
|
+
}
|
51
|
+
|
52
|
+
MOAPI void moapi_hash_set(mo_value hash, mo_value key, mo_value val)
|
53
|
+
{
|
54
|
+
rb_hash_aset((VALUE)hash, (VALUE)key, (VALUE)val);
|
55
|
+
}
|
56
|
+
|
57
|
+
MOAPI mo_value moapi_uint64_new(uint64_t value)
|
58
|
+
{
|
59
|
+
return (mo_value)rb_ull2inum((long long)value);
|
60
|
+
}
|
61
|
+
|
62
|
+
MOAPI mo_value moapi_int64_new(int64_t value)
|
63
|
+
{
|
64
|
+
return (mo_value)rb_ll2inum(value);
|
65
|
+
}
|
66
|
+
|
67
|
+
MOAPI mo_value moapi_atom_new(enum msgpack_t type)
|
68
|
+
{
|
69
|
+
switch (type) {
|
70
|
+
case MSGPACK_T_NIL: return (mo_value)Qnil;
|
71
|
+
case MSGPACK_T_TRUE: return (mo_value)Qtrue;
|
72
|
+
case MSGPACK_T_FALSE: return (mo_value)Qfalse;
|
73
|
+
default: return NULL;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
MOAPI mo_value moapi_double_new(double d)
|
78
|
+
{
|
79
|
+
return (mo_value)rb_float_new(d);
|
80
|
+
}
|
81
|
+
|
82
|
+
|
83
|
+
#define moapi_uint8_new(n) (mo_value)INT2FIX((int)n)
|
84
|
+
#define moapi_uint16_new(n) (mo_value)INT2FIX((int)n)
|
85
|
+
#define moapi_uint32_new(n) (mo_value)ULONG2NUM((unsigned long)n)
|
86
|
+
|
87
|
+
#define moapi_int8_new(n) (mo_value)INT2FIX((int)n)
|
88
|
+
#define moapi_int16_new(n) (mo_value)INT2FIX((int)n)
|
89
|
+
#define moapi_int32_new(n) (mo_value)LONG2FIX((long)n)
|
90
|
+
|
91
|
+
#define moapi_float_new moapi_double_new
|
@@ -0,0 +1,331 @@
|
|
1
|
+
#include <stdint.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <string.h>
|
5
|
+
|
6
|
+
#include "mochilo.h"
|
7
|
+
|
8
|
+
extern VALUE rb_eMochiloPackError;
|
9
|
+
|
10
|
+
void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object, int trusted);
|
11
|
+
|
12
|
+
void mochilo_pack_fixnum(mochilo_buf *buf, VALUE rb_fixnum)
|
13
|
+
{
|
14
|
+
long fixnum = NUM2LONG(rb_fixnum);
|
15
|
+
|
16
|
+
if (fixnum < -0x20L) {
|
17
|
+
if (fixnum < -0x8000L) {
|
18
|
+
if (sizeof(long) > 4 && fixnum < -0x80000000L) {
|
19
|
+
mochilo_buf_putc(buf, MSGPACK_T_INT64);
|
20
|
+
mochilo_buf_put64be(buf, &fixnum);
|
21
|
+
} else {
|
22
|
+
int32_t fixnum32 = (int32_t)fixnum;
|
23
|
+
mochilo_buf_putc(buf, MSGPACK_T_INT32);
|
24
|
+
mochilo_buf_put32be(buf, &fixnum32);
|
25
|
+
}
|
26
|
+
} else {
|
27
|
+
if (fixnum < -0x80L) {
|
28
|
+
int16_t fixnum16 = (int16_t)fixnum;
|
29
|
+
mochilo_buf_putc(buf, MSGPACK_T_INT16);
|
30
|
+
mochilo_buf_put16be(buf, &fixnum16);
|
31
|
+
} else {
|
32
|
+
mochilo_buf_putc(buf, MSGPACK_T_INT8);
|
33
|
+
mochilo_buf_putc(buf, (int8_t)fixnum);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
} else if (fixnum <= 0x7fL) {
|
37
|
+
mochilo_buf_putc(buf, (uint8_t)fixnum);
|
38
|
+
} else {
|
39
|
+
if (fixnum <= 0xffffL) {
|
40
|
+
if (fixnum <= 0xffL) {
|
41
|
+
mochilo_buf_putc(buf, MSGPACK_T_UINT8);
|
42
|
+
mochilo_buf_putc(buf, (uint8_t)fixnum);
|
43
|
+
} else {
|
44
|
+
uint16_t fixnum16 = (uint16_t)fixnum;
|
45
|
+
mochilo_buf_putc(buf, MSGPACK_T_UINT16);
|
46
|
+
mochilo_buf_put16be(buf, &fixnum16);
|
47
|
+
}
|
48
|
+
} else {
|
49
|
+
if (fixnum <= 0xffffffffL) {
|
50
|
+
uint32_t fixnum32 = (uint32_t)fixnum;
|
51
|
+
mochilo_buf_putc(buf, MSGPACK_T_UINT32);
|
52
|
+
mochilo_buf_put32be(buf, &fixnum32);
|
53
|
+
} else if (sizeof(long) > 4) {
|
54
|
+
mochilo_buf_putc(buf, MSGPACK_T_UINT64);
|
55
|
+
mochilo_buf_put64be(buf, &fixnum);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
void mochilo_pack_bignum(mochilo_buf *buf, VALUE rb_bignum)
|
62
|
+
{
|
63
|
+
if (RBIGNUM_POSITIVE_P(rb_bignum)) {
|
64
|
+
uint64_t bignum = rb_big2ull(rb_bignum);
|
65
|
+
|
66
|
+
mochilo_buf_putc(buf, MSGPACK_T_UINT64);
|
67
|
+
mochilo_buf_put64be(buf, &bignum);
|
68
|
+
} else {
|
69
|
+
int64_t bignum = rb_big2ll(rb_bignum);
|
70
|
+
|
71
|
+
mochilo_buf_putc(buf, MSGPACK_T_INT64);
|
72
|
+
mochilo_buf_put64be(buf, &bignum);
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
struct mochilo_hash_pack {
|
77
|
+
mochilo_buf *buf;
|
78
|
+
int trusted;
|
79
|
+
};
|
80
|
+
|
81
|
+
static int hash_callback(VALUE key, VALUE val, VALUE opaque)
|
82
|
+
{
|
83
|
+
struct mochilo_hash_pack *hash_pack = (struct mochilo_hash_pack*)opaque;
|
84
|
+
mochilo_pack_one(hash_pack->buf, key, hash_pack->trusted);
|
85
|
+
mochilo_pack_one(hash_pack->buf, val, hash_pack->trusted);
|
86
|
+
return 0;
|
87
|
+
}
|
88
|
+
|
89
|
+
void mochilo_pack_double(mochilo_buf *buf, VALUE rb_double)
|
90
|
+
{
|
91
|
+
double d = RFLOAT_VALUE(rb_double);
|
92
|
+
mochilo_buf_putc(buf, MSGPACK_T_DOUBLE);
|
93
|
+
mochilo_buf_put64be(buf, &d);
|
94
|
+
}
|
95
|
+
|
96
|
+
void mochilo_pack_hash(mochilo_buf *buf, VALUE rb_hash, int trusted)
|
97
|
+
{
|
98
|
+
struct mochilo_hash_pack hash_pack;
|
99
|
+
long size = RHASH_SIZE(rb_hash);
|
100
|
+
|
101
|
+
hash_pack.buf = buf;
|
102
|
+
hash_pack.trusted = trusted;
|
103
|
+
|
104
|
+
if (size < 0x10) {
|
105
|
+
uint8_t lead = 0x80 | size;
|
106
|
+
mochilo_buf_putc(buf, lead);
|
107
|
+
}
|
108
|
+
|
109
|
+
else if (size < 0x10000) {
|
110
|
+
uint16_t lead = size;
|
111
|
+
mochilo_buf_putc(buf, MSGPACK_T_MAP16);
|
112
|
+
mochilo_buf_put16be(buf, &lead);
|
113
|
+
}
|
114
|
+
|
115
|
+
else {
|
116
|
+
mochilo_buf_putc(buf, MSGPACK_T_MAP32);
|
117
|
+
mochilo_buf_put32be(buf, &size);
|
118
|
+
}
|
119
|
+
|
120
|
+
rb_hash_foreach(rb_hash, &hash_callback, (VALUE)&hash_pack);
|
121
|
+
}
|
122
|
+
|
123
|
+
void mochilo_pack_bytes(mochilo_buf *buf, VALUE rb_bytes)
|
124
|
+
{
|
125
|
+
long size = RSTRING_LEN(rb_bytes);
|
126
|
+
|
127
|
+
if (size < 0x20) {
|
128
|
+
uint8_t lead = 0xA0 | size;
|
129
|
+
mochilo_buf_putc(buf, lead);
|
130
|
+
}
|
131
|
+
|
132
|
+
else if (size < 0x10000) {
|
133
|
+
uint16_t lead = size;
|
134
|
+
mochilo_buf_putc(buf, MSGPACK_T_RAW16);
|
135
|
+
mochilo_buf_put16be(buf, &lead);
|
136
|
+
}
|
137
|
+
|
138
|
+
else {
|
139
|
+
mochilo_buf_putc(buf, MSGPACK_T_RAW32);
|
140
|
+
mochilo_buf_put32be(buf, &size);
|
141
|
+
}
|
142
|
+
|
143
|
+
mochilo_buf_put(buf, RSTRING_PTR(rb_bytes), size);
|
144
|
+
}
|
145
|
+
|
146
|
+
void mochilo_pack_symbol(mochilo_buf *buf, VALUE rb_symbol)
|
147
|
+
{
|
148
|
+
long size;
|
149
|
+
const char *name;
|
150
|
+
|
151
|
+
name = rb_id2name(SYM2ID(rb_symbol));
|
152
|
+
size = strlen(name);
|
153
|
+
|
154
|
+
if (size < 0x100) {
|
155
|
+
uint8_t lead = size;
|
156
|
+
mochilo_buf_putc(buf, MSGPACK_T_SYM);
|
157
|
+
mochilo_buf_putc(buf, lead);
|
158
|
+
} else {
|
159
|
+
rb_raise(rb_eMochiloPackError,
|
160
|
+
"Symbol too long: must be under %d bytes, %ld given", 0x100, size);
|
161
|
+
}
|
162
|
+
|
163
|
+
mochilo_buf_put(buf, name, size);
|
164
|
+
}
|
165
|
+
|
166
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
167
|
+
void mochilo_pack_str(mochilo_buf *buf, VALUE rb_str)
|
168
|
+
{
|
169
|
+
long size = RSTRING_LEN(rb_str);
|
170
|
+
rb_encoding *encoding;
|
171
|
+
|
172
|
+
const struct mochilo_enc_map *enc2id;
|
173
|
+
const char *enc_name;
|
174
|
+
|
175
|
+
if (size < 0x10000) {
|
176
|
+
uint16_t lead = size;
|
177
|
+
mochilo_buf_putc(buf, MSGPACK_T_STR16);
|
178
|
+
mochilo_buf_put16be(buf, &lead);
|
179
|
+
}
|
180
|
+
|
181
|
+
else {
|
182
|
+
mochilo_buf_putc(buf, MSGPACK_T_STR32);
|
183
|
+
mochilo_buf_put32be(buf, &size);
|
184
|
+
}
|
185
|
+
|
186
|
+
encoding = rb_enc_get(rb_str);
|
187
|
+
enc_name = rb_enc_name(encoding);
|
188
|
+
enc2id = mochilo_encoding_to_id(enc_name, (unsigned int)strlen(enc_name));
|
189
|
+
|
190
|
+
mochilo_buf_putc(buf, enc2id ? enc2id->id : 0);
|
191
|
+
mochilo_buf_put(buf, RSTRING_PTR(rb_str), size);
|
192
|
+
}
|
193
|
+
#endif
|
194
|
+
|
195
|
+
void mochilo_pack_array(mochilo_buf *buf, VALUE rb_array, int trusted)
|
196
|
+
{
|
197
|
+
long i, size = RARRAY_LEN(rb_array);
|
198
|
+
|
199
|
+
if (size < 0x10) {
|
200
|
+
uint8_t lead = 0x90 | size;
|
201
|
+
mochilo_buf_putc(buf, lead);
|
202
|
+
}
|
203
|
+
|
204
|
+
else if (size < 0x10000) {
|
205
|
+
uint16_t lead = size;
|
206
|
+
mochilo_buf_putc(buf, MSGPACK_T_ARRAY16);
|
207
|
+
mochilo_buf_put16be(buf, &lead);
|
208
|
+
}
|
209
|
+
|
210
|
+
else {
|
211
|
+
mochilo_buf_putc(buf, MSGPACK_T_ARRAY32);
|
212
|
+
mochilo_buf_put32be(buf, &size);
|
213
|
+
}
|
214
|
+
|
215
|
+
for (i = 0; i < size; i++) {
|
216
|
+
mochilo_pack_one(buf, rb_ary_entry(rb_array, i), trusted);
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object, int trusted)
|
221
|
+
{
|
222
|
+
#ifndef RUBINIUS
|
223
|
+
if (rb_object == Qnil) {
|
224
|
+
mochilo_buf_putc(buf, MSGPACK_T_NIL);
|
225
|
+
}
|
226
|
+
else if (rb_object == Qtrue) {
|
227
|
+
mochilo_buf_putc(buf, MSGPACK_T_TRUE);
|
228
|
+
}
|
229
|
+
else if (rb_object == Qfalse) {
|
230
|
+
mochilo_buf_putc(buf, MSGPACK_T_FALSE);
|
231
|
+
}
|
232
|
+
else if (FIXNUM_P(rb_object)) {
|
233
|
+
mochilo_pack_fixnum(buf, rb_object);
|
234
|
+
}
|
235
|
+
else if (SYMBOL_P(rb_object)) {
|
236
|
+
if (trusted)
|
237
|
+
mochilo_pack_symbol(buf, rb_object);
|
238
|
+
else
|
239
|
+
mochilo_pack_str(buf, rb_obj_as_string(rb_object));
|
240
|
+
}
|
241
|
+
else {
|
242
|
+
switch (BUILTIN_TYPE(rb_object)) {
|
243
|
+
case T_STRING:
|
244
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
245
|
+
if (ENCODING_GET(rb_object) != 0)
|
246
|
+
mochilo_pack_str(buf, rb_object);
|
247
|
+
else
|
248
|
+
#endif
|
249
|
+
mochilo_pack_bytes(buf, rb_object);
|
250
|
+
return;
|
251
|
+
|
252
|
+
case T_HASH:
|
253
|
+
mochilo_pack_hash(buf, rb_object, trusted);
|
254
|
+
return;
|
255
|
+
|
256
|
+
case T_ARRAY:
|
257
|
+
mochilo_pack_array(buf, rb_object, trusted);
|
258
|
+
return;
|
259
|
+
|
260
|
+
case T_FLOAT:
|
261
|
+
mochilo_pack_double(buf, rb_object);
|
262
|
+
return;
|
263
|
+
|
264
|
+
case T_BIGNUM:
|
265
|
+
mochilo_pack_bignum(buf, rb_object);
|
266
|
+
return;
|
267
|
+
|
268
|
+
default:
|
269
|
+
rb_raise(rb_eMochiloPackError,
|
270
|
+
"Unsupported object type: %s", rb_obj_classname(rb_object));
|
271
|
+
return;
|
272
|
+
}
|
273
|
+
}
|
274
|
+
#else // RUBINIUS
|
275
|
+
switch (rb_type(rb_object)) {
|
276
|
+
case T_NIL:
|
277
|
+
mochilo_buf_putc(buf, MSGPACK_T_NIL);
|
278
|
+
return;
|
279
|
+
|
280
|
+
case T_FALSE:
|
281
|
+
mochilo_buf_putc(buf, MSGPACK_T_FALSE);
|
282
|
+
return;
|
283
|
+
|
284
|
+
case T_TRUE:
|
285
|
+
mochilo_buf_putc(buf, MSGPACK_T_TRUE);
|
286
|
+
return;
|
287
|
+
|
288
|
+
case T_FIXNUM:
|
289
|
+
mochilo_pack_fixnum(buf, rb_object);
|
290
|
+
return;
|
291
|
+
|
292
|
+
case T_BIGNUM:
|
293
|
+
mochilo_pack_bignum(buf, rb_object);
|
294
|
+
return;
|
295
|
+
|
296
|
+
case T_SYMBOL:
|
297
|
+
if (trusted)
|
298
|
+
mochilo_pack_symbol(buf, rb_object);
|
299
|
+
else
|
300
|
+
mochilo_pack_str(buf, rb_obj_as_string(rb_object));
|
301
|
+
return;
|
302
|
+
|
303
|
+
case T_STRING:
|
304
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
305
|
+
if (ENCODING_GET(rb_object) != 0)
|
306
|
+
mochilo_pack_str(buf, rb_object);
|
307
|
+
else
|
308
|
+
#endif
|
309
|
+
mochilo_pack_bytes(buf, rb_object);
|
310
|
+
return;
|
311
|
+
|
312
|
+
case T_HASH:
|
313
|
+
mochilo_pack_hash(buf, rb_object, trusted);
|
314
|
+
return;
|
315
|
+
|
316
|
+
case T_ARRAY:
|
317
|
+
mochilo_pack_array(buf, rb_object, trusted);
|
318
|
+
return;
|
319
|
+
|
320
|
+
case T_FLOAT:
|
321
|
+
mochilo_pack_double(buf, rb_object);
|
322
|
+
return;
|
323
|
+
|
324
|
+
default:
|
325
|
+
rb_raise(rb_eMochiloPackError,
|
326
|
+
"Unsupported object type: %s", rb_obj_classname(rb_object));
|
327
|
+
return;
|
328
|
+
}
|
329
|
+
#endif
|
330
|
+
}
|
331
|
+
|