mochilo 1.3.0 → 2.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 +5 -5
- data/.travis.yml +2 -5
- data/Gemfile +0 -4
- data/Gemfile.lock +1 -1
- data/LICENSE +21 -0
- data/README.md +12 -26
- data/docs/format-spec.md +23 -54
- data/docs/why-banana-pack.md +5 -3
- data/ext/mochilo/buffer.c +11 -14
- data/ext/mochilo/buffer.h +4 -5
- data/ext/mochilo/mochilo.h +26 -27
- data/ext/mochilo/mochilo.rb.c +15 -42
- data/ext/mochilo/mochilo_api.h +0 -39
- data/ext/mochilo/mochilo_pack.c +65 -130
- data/ext/mochilo/mochilo_unpack.c +51 -32
- data/lib/mochilo/version.rb +1 -1
- data/mochilo.gemspec +3 -1
- data/script/bootstrap +1 -1
- data/test/pack_test.rb +162 -80
- data/test/setup.rb +0 -9
- data/test/unpack_test.rb +206 -48
- metadata +24 -13
- data/MIT-LICENSE +0 -20
data/ext/mochilo/mochilo_pack.c
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
extern VALUE rb_eMochiloPackError;
|
9
9
|
|
10
|
-
void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object
|
10
|
+
void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object);
|
11
11
|
|
12
12
|
void mochilo_pack_fixnum(mochilo_buf *buf, VALUE rb_fixnum)
|
13
13
|
{
|
@@ -73,66 +73,15 @@ void mochilo_pack_bignum(mochilo_buf *buf, VALUE rb_bignum)
|
|
73
73
|
}
|
74
74
|
}
|
75
75
|
|
76
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
77
|
-
void mochilo_pack_regexp(mochilo_buf *buf, VALUE rb_regexp)
|
78
|
-
{
|
79
|
-
size_t size;
|
80
|
-
rb_encoding *encoding;
|
81
|
-
char *enc_name;
|
82
|
-
const struct mochilo_enc_map *enc2id;
|
83
|
-
uint32_t options;
|
84
|
-
const char *regexp;
|
85
|
-
|
86
|
-
size = RREGEXP_SRC_LEN(rb_regexp);
|
87
|
-
|
88
|
-
if (size < (1<<16)) {
|
89
|
-
uint16_t packed_size = size;
|
90
|
-
|
91
|
-
encoding = rb_enc_get(rb_regexp);
|
92
|
-
enc_name = rb_enc_name(encoding);
|
93
|
-
enc2id = mochilo_encoding_to_id(enc_name, (unsigned int)strlen(enc_name));
|
94
|
-
|
95
|
-
options = rb_reg_options(rb_regexp);
|
96
|
-
regexp = RREGEXP_SRC_PTR(rb_regexp);
|
97
|
-
|
98
|
-
mochilo_buf_putc(buf, MSGPACK_T_REGEXP);
|
99
|
-
mochilo_buf_put16be(buf, &packed_size);
|
100
|
-
mochilo_buf_put32be(buf, &options);
|
101
|
-
mochilo_buf_putc(buf, enc2id ? enc2id->id : 0);
|
102
|
-
mochilo_buf_put(buf, regexp, size);
|
103
|
-
} else {
|
104
|
-
rb_raise(rb_eMochiloPackError,
|
105
|
-
"Regexp too long: must be under %d bytes, %ld given", 1<<16, size);
|
106
|
-
}
|
107
|
-
}
|
108
|
-
#endif
|
109
|
-
|
110
|
-
void mochilo_pack_time(mochilo_buf *buf, VALUE rb_time)
|
111
|
-
{
|
112
|
-
uint64_t sec;
|
113
|
-
uint64_t usec;
|
114
|
-
int32_t utc_offset;
|
115
|
-
|
116
|
-
sec = NUM2ULONG(rb_funcall(rb_time, rb_intern("to_i"), 0));
|
117
|
-
usec = NUM2ULONG(rb_funcall(rb_time, rb_intern("usec"), 0));
|
118
|
-
utc_offset = NUM2INT(rb_funcall(rb_time, rb_intern("utc_offset"), 0));
|
119
|
-
|
120
|
-
mochilo_buf_putc(buf, MSGPACK_T_TIME);
|
121
|
-
mochilo_buf_put64be(buf, &sec);
|
122
|
-
mochilo_buf_put64be(buf, &usec);
|
123
|
-
mochilo_buf_put32be(buf, &utc_offset);
|
124
|
-
}
|
125
|
-
|
126
76
|
struct mochilo_hash_pack {
|
127
77
|
mochilo_buf *buf;
|
128
|
-
int trusted;
|
129
78
|
};
|
130
79
|
|
131
80
|
static int hash_callback(VALUE key, VALUE val, VALUE opaque)
|
132
81
|
{
|
133
82
|
struct mochilo_hash_pack *hash_pack = (struct mochilo_hash_pack*)opaque;
|
134
|
-
mochilo_pack_one(hash_pack->buf, key
|
135
|
-
mochilo_pack_one(hash_pack->buf, val
|
83
|
+
mochilo_pack_one(hash_pack->buf, key);
|
84
|
+
mochilo_pack_one(hash_pack->buf, val);
|
136
85
|
return 0;
|
137
86
|
}
|
138
87
|
|
@@ -143,13 +92,12 @@ void mochilo_pack_double(mochilo_buf *buf, VALUE rb_double)
|
|
143
92
|
mochilo_buf_put64be(buf, &d);
|
144
93
|
}
|
145
94
|
|
146
|
-
void mochilo_pack_hash(mochilo_buf *buf, VALUE rb_hash
|
95
|
+
void mochilo_pack_hash(mochilo_buf *buf, VALUE rb_hash)
|
147
96
|
{
|
148
97
|
struct mochilo_hash_pack hash_pack;
|
149
98
|
long size = RHASH_SIZE(rb_hash);
|
150
99
|
|
151
100
|
hash_pack.buf = buf;
|
152
|
-
hash_pack.trusted = trusted;
|
153
101
|
|
154
102
|
if (size < 0x10) {
|
155
103
|
uint8_t lead = 0x80 | size;
|
@@ -174,46 +122,26 @@ void mochilo_pack_bytes(mochilo_buf *buf, VALUE rb_bytes)
|
|
174
122
|
{
|
175
123
|
long size = RSTRING_LEN(rb_bytes);
|
176
124
|
|
177
|
-
if (size <
|
178
|
-
uint8_t lead =
|
125
|
+
if (size < 0x100) {
|
126
|
+
uint8_t lead = size;
|
127
|
+
mochilo_buf_putc(buf, MSGPACK_T_BIN8);
|
179
128
|
mochilo_buf_putc(buf, lead);
|
180
|
-
}
|
181
|
-
|
182
|
-
else if (size < 0x10000) {
|
129
|
+
} else if (size < 0x10000) {
|
183
130
|
uint16_t lead = size;
|
184
|
-
mochilo_buf_putc(buf,
|
131
|
+
mochilo_buf_putc(buf, MSGPACK_T_BIN16);
|
185
132
|
mochilo_buf_put16be(buf, &lead);
|
186
|
-
}
|
187
|
-
|
188
|
-
else {
|
189
|
-
mochilo_buf_putc(buf, MSGPACK_T_RAW32);
|
133
|
+
} else if (size < 0x100000000) {
|
134
|
+
mochilo_buf_putc(buf, MSGPACK_T_BIN32);
|
190
135
|
mochilo_buf_put32be(buf, &size);
|
191
|
-
}
|
192
|
-
|
193
|
-
mochilo_buf_put(buf, RSTRING_PTR(rb_bytes), size);
|
194
|
-
}
|
195
|
-
|
196
|
-
void mochilo_pack_symbol(mochilo_buf *buf, VALUE rb_symbol)
|
197
|
-
{
|
198
|
-
long size;
|
199
|
-
const char *name;
|
200
|
-
|
201
|
-
name = rb_id2name(SYM2ID(rb_symbol));
|
202
|
-
size = strlen(name);
|
203
|
-
|
204
|
-
if (size < 0x100) {
|
205
|
-
uint8_t lead = size;
|
206
|
-
mochilo_buf_putc(buf, MSGPACK_T_SYM);
|
207
|
-
mochilo_buf_putc(buf, lead);
|
208
136
|
} else {
|
137
|
+
// there is no bin 64
|
209
138
|
rb_raise(rb_eMochiloPackError,
|
210
|
-
"
|
139
|
+
"Binary string cannot be larger than %ld bytes", 0x100000000);
|
211
140
|
}
|
212
141
|
|
213
|
-
mochilo_buf_put(buf,
|
142
|
+
mochilo_buf_put(buf, RSTRING_PTR(rb_bytes), size);
|
214
143
|
}
|
215
144
|
|
216
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
217
145
|
void mochilo_pack_str(mochilo_buf *buf, VALUE rb_str)
|
218
146
|
{
|
219
147
|
long size = RSTRING_LEN(rb_str);
|
@@ -222,27 +150,57 @@ void mochilo_pack_str(mochilo_buf *buf, VALUE rb_str)
|
|
222
150
|
const struct mochilo_enc_map *enc2id;
|
223
151
|
const char *enc_name;
|
224
152
|
|
225
|
-
if (size < 0x10000) {
|
226
|
-
uint16_t lead = size;
|
227
|
-
mochilo_buf_putc(buf, MSGPACK_T_STR16);
|
228
|
-
mochilo_buf_put16be(buf, &lead);
|
229
|
-
}
|
230
|
-
|
231
|
-
else {
|
232
|
-
mochilo_buf_putc(buf, MSGPACK_T_STR32);
|
233
|
-
mochilo_buf_put32be(buf, &size);
|
234
|
-
}
|
235
|
-
|
236
153
|
encoding = rb_enc_get(rb_str);
|
237
154
|
enc_name = rb_enc_name(encoding);
|
238
|
-
enc2id = mochilo_encoding_to_id(enc_name, (unsigned int)strlen(enc_name));
|
239
155
|
|
240
|
-
|
156
|
+
if (encoding == rb_utf8_encoding()) {
|
157
|
+
// use str type from msgpack spec
|
158
|
+
if (size < 0x20) {
|
159
|
+
uint8_t lead = 0xa0 | size;
|
160
|
+
mochilo_buf_putc(buf, lead);
|
161
|
+
} else if (size < 0x100) {
|
162
|
+
uint8_t lead = size;
|
163
|
+
mochilo_buf_putc(buf, MSGPACK_T_STR8);
|
164
|
+
mochilo_buf_putc(buf, lead);
|
165
|
+
} else if (size < 0x10000) {
|
166
|
+
uint16_t lead = size;
|
167
|
+
mochilo_buf_putc(buf, MSGPACK_T_STR16);
|
168
|
+
mochilo_buf_put16be(buf, &lead);
|
169
|
+
} else if (size < 0x100000000) {
|
170
|
+
mochilo_buf_putc(buf, MSGPACK_T_STR32);
|
171
|
+
mochilo_buf_put32be(buf, &size);
|
172
|
+
} else {
|
173
|
+
// there is no str 64
|
174
|
+
rb_raise(rb_eMochiloPackError,
|
175
|
+
"String cannot be larger than %ld bytes", 0x100000000);
|
176
|
+
}
|
177
|
+
} else {
|
178
|
+
// if another encoding is used we need to use our custom types
|
179
|
+
if (size < 0x100) {
|
180
|
+
uint8_t lead = size;
|
181
|
+
mochilo_buf_putc(buf, MSGPACK_T_ENC8);
|
182
|
+
mochilo_buf_putc(buf, lead);
|
183
|
+
} else if (size < 0x10000) {
|
184
|
+
uint16_t lead = size;
|
185
|
+
mochilo_buf_putc(buf, MSGPACK_T_ENC16);
|
186
|
+
mochilo_buf_put16be(buf, &lead);
|
187
|
+
} else if (size < 0x100000000) {
|
188
|
+
mochilo_buf_putc(buf, MSGPACK_T_ENC32);
|
189
|
+
mochilo_buf_put32be(buf, &size);
|
190
|
+
} else {
|
191
|
+
// there is no ext 64
|
192
|
+
rb_raise(rb_eMochiloPackError,
|
193
|
+
"String cannot be larger than %ld bytes", 0x100000000);
|
194
|
+
}
|
195
|
+
|
196
|
+
enc2id = mochilo_encoding_to_id(enc_name, (unsigned int)strlen(enc_name));
|
197
|
+
mochilo_buf_putc(buf, enc2id ? enc2id->id : 0);
|
198
|
+
}
|
199
|
+
|
241
200
|
mochilo_buf_put(buf, RSTRING_PTR(rb_str), size);
|
242
201
|
}
|
243
|
-
#endif
|
244
202
|
|
245
|
-
void mochilo_pack_array(mochilo_buf *buf, VALUE rb_array
|
203
|
+
void mochilo_pack_array(mochilo_buf *buf, VALUE rb_array)
|
246
204
|
{
|
247
205
|
long i, size = RARRAY_LEN(rb_array);
|
248
206
|
|
@@ -263,11 +221,11 @@ void mochilo_pack_array(mochilo_buf *buf, VALUE rb_array, int trusted)
|
|
263
221
|
}
|
264
222
|
|
265
223
|
for (i = 0; i < size; i++) {
|
266
|
-
mochilo_pack_one(buf, rb_ary_entry(rb_array, i)
|
224
|
+
mochilo_pack_one(buf, rb_ary_entry(rb_array, i));
|
267
225
|
}
|
268
226
|
}
|
269
227
|
|
270
|
-
void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object
|
228
|
+
void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object)
|
271
229
|
{
|
272
230
|
switch (rb_type(rb_object)) {
|
273
231
|
case T_NIL:
|
@@ -286,28 +244,19 @@ void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object, int trusted)
|
|
286
244
|
mochilo_pack_fixnum(buf, rb_object);
|
287
245
|
return;
|
288
246
|
|
289
|
-
case T_SYMBOL:
|
290
|
-
if (trusted)
|
291
|
-
mochilo_pack_symbol(buf, rb_object);
|
292
|
-
else
|
293
|
-
mochilo_pack_str(buf, rb_obj_as_string(rb_object));
|
294
|
-
return;
|
295
|
-
|
296
247
|
case T_STRING:
|
297
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
298
248
|
if (ENCODING_GET(rb_object) != 0)
|
299
249
|
mochilo_pack_str(buf, rb_object);
|
300
250
|
else
|
301
|
-
#endif
|
302
251
|
mochilo_pack_bytes(buf, rb_object);
|
303
252
|
return;
|
304
253
|
|
305
254
|
case T_HASH:
|
306
|
-
mochilo_pack_hash(buf, rb_object
|
255
|
+
mochilo_pack_hash(buf, rb_object);
|
307
256
|
return;
|
308
257
|
|
309
258
|
case T_ARRAY:
|
310
|
-
mochilo_pack_array(buf, rb_object
|
259
|
+
mochilo_pack_array(buf, rb_object);
|
311
260
|
return;
|
312
261
|
|
313
262
|
case T_FLOAT:
|
@@ -318,23 +267,9 @@ void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object, int trusted)
|
|
318
267
|
mochilo_pack_bignum(buf, rb_object);
|
319
268
|
return;
|
320
269
|
|
321
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
322
|
-
case T_REGEXP:
|
323
|
-
mochilo_pack_regexp(buf, rb_object);
|
324
|
-
return;
|
325
|
-
#endif
|
326
|
-
|
327
270
|
default:
|
328
|
-
|
329
|
-
|
330
|
-
} else if (rb_respond_to(rb_object, rb_intern("to_bpack"))) {
|
331
|
-
VALUE bpack = rb_funcall(rb_object, rb_intern("to_bpack"), 0);
|
332
|
-
|
333
|
-
mochilo_buf_put(buf, RSTRING_PTR(bpack), RSTRING_LEN(bpack));
|
334
|
-
} else {
|
335
|
-
rb_raise(rb_eMochiloPackError,
|
336
|
-
"Unsupported object type: %s", rb_obj_classname(rb_object));
|
337
|
-
}
|
271
|
+
rb_raise(rb_eMochiloPackError,
|
272
|
+
"Unsupported object type: %s", rb_obj_classname(rb_object));
|
338
273
|
return;
|
339
274
|
}
|
340
275
|
}
|
@@ -159,14 +159,10 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
|
|
159
159
|
return unpack_hash(_value, (size_t)length, src);
|
160
160
|
}
|
161
161
|
|
162
|
-
case
|
162
|
+
case MSGPACK_T_STR8:
|
163
163
|
{
|
164
164
|
uint8_t length;
|
165
165
|
const char *ptr;
|
166
|
-
|
167
|
-
if (!src->trusted) {
|
168
|
-
return MSGPACK_EUNSAFE;
|
169
|
-
}
|
170
166
|
|
171
167
|
SRC_ENSURE_AVAIL(src, 1);
|
172
168
|
mochilo_src_get8be(src, &length);
|
@@ -174,48 +170,58 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
|
|
174
170
|
if (!(ptr = mochilo_src_peek(src, length)))
|
175
171
|
return -1;
|
176
172
|
|
177
|
-
*_value =
|
173
|
+
*_value = moapi_str_new(ptr, length, MSGPACK_ENC_UTF_8);
|
178
174
|
return 0;
|
179
175
|
}
|
180
176
|
|
181
|
-
|
182
|
-
case MSGPACK_T_REGEXP:
|
177
|
+
case MSGPACK_T_STR16:
|
183
178
|
{
|
184
179
|
uint16_t length;
|
185
|
-
uint32_t options;
|
186
|
-
uint8_t encoding;
|
187
180
|
const char *ptr;
|
188
181
|
|
189
|
-
SRC_ENSURE_AVAIL(src, 2+
|
182
|
+
SRC_ENSURE_AVAIL(src, 2 + 1);
|
190
183
|
mochilo_src_get16be(src, &length);
|
191
|
-
mochilo_src_get32be(src, &options);
|
192
|
-
mochilo_src_get8be(src, &encoding);
|
193
184
|
|
194
185
|
if (!(ptr = mochilo_src_peek(src, length)))
|
195
186
|
return -1;
|
196
187
|
|
197
|
-
*_value =
|
188
|
+
*_value = moapi_str_new(ptr, length, MSGPACK_ENC_UTF_8);
|
198
189
|
return 0;
|
199
190
|
}
|
200
|
-
#endif
|
201
191
|
|
202
|
-
case
|
192
|
+
case MSGPACK_T_STR32:
|
203
193
|
{
|
204
|
-
|
205
|
-
|
206
|
-
int32_t utc_offset;
|
194
|
+
uint32_t length;
|
195
|
+
const char *ptr;
|
207
196
|
|
208
|
-
SRC_ENSURE_AVAIL(src,
|
209
|
-
|
210
|
-
mochilo_src_get64be(src, &usec);
|
211
|
-
mochilo_src_get32be(src, &utc_offset);
|
197
|
+
SRC_ENSURE_AVAIL(src, 4 + 1);
|
198
|
+
mochilo_src_get32be(src, &length);
|
212
199
|
|
213
|
-
|
200
|
+
if (!(ptr = mochilo_src_peek(src, length)))
|
201
|
+
return -1;
|
202
|
+
|
203
|
+
*_value = moapi_str_new(ptr, length, MSGPACK_ENC_UTF_8);
|
214
204
|
return 0;
|
215
205
|
}
|
216
206
|
|
217
|
-
|
218
|
-
|
207
|
+
case MSGPACK_T_ENC8:
|
208
|
+
{
|
209
|
+
uint8_t length;
|
210
|
+
uint8_t encoding;
|
211
|
+
const char *ptr;
|
212
|
+
|
213
|
+
SRC_ENSURE_AVAIL(src, 1 + 1);
|
214
|
+
mochilo_src_get8be(src, &length);
|
215
|
+
mochilo_src_get8be(src, &encoding);
|
216
|
+
|
217
|
+
if (!(ptr = mochilo_src_peek(src, length)))
|
218
|
+
return -1;
|
219
|
+
|
220
|
+
*_value = moapi_str_new(ptr, length, encoding);
|
221
|
+
return 0;
|
222
|
+
}
|
223
|
+
|
224
|
+
case MSGPACK_T_ENC16:
|
219
225
|
{
|
220
226
|
uint16_t length;
|
221
227
|
uint8_t encoding;
|
@@ -232,7 +238,7 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
|
|
232
238
|
return 0;
|
233
239
|
}
|
234
240
|
|
235
|
-
case
|
241
|
+
case MSGPACK_T_ENC32:
|
236
242
|
{
|
237
243
|
uint32_t length;
|
238
244
|
uint8_t encoding;
|
@@ -248,9 +254,23 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
|
|
248
254
|
*_value = moapi_str_new(ptr, length, encoding);
|
249
255
|
return 0;
|
250
256
|
}
|
251
|
-
#endif
|
252
257
|
|
253
|
-
case
|
258
|
+
case MSGPACK_T_BIN8:
|
259
|
+
{
|
260
|
+
uint8_t length;
|
261
|
+
const char *ptr;
|
262
|
+
|
263
|
+
SRC_ENSURE_AVAIL(src, 1);
|
264
|
+
mochilo_src_get8be(src, &length);
|
265
|
+
|
266
|
+
if (!(ptr = mochilo_src_peek(src, length)))
|
267
|
+
return -1;
|
268
|
+
|
269
|
+
*_value = moapi_bytes_new(ptr, length);
|
270
|
+
return 0;
|
271
|
+
}
|
272
|
+
|
273
|
+
case MSGPACK_T_BIN16:
|
254
274
|
{
|
255
275
|
uint16_t length;
|
256
276
|
const char *ptr;
|
@@ -265,7 +285,7 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
|
|
265
285
|
return 0;
|
266
286
|
}
|
267
287
|
|
268
|
-
case
|
288
|
+
case MSGPACK_T_BIN32:
|
269
289
|
{
|
270
290
|
uint32_t length;
|
271
291
|
const char *ptr;
|
@@ -304,7 +324,7 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
|
|
304
324
|
if (!(ptr = mochilo_src_peek(src, length)))
|
305
325
|
return -1;
|
306
326
|
|
307
|
-
*_value =
|
327
|
+
*_value = moapi_str_new(ptr, length, MSGPACK_ENC_UTF_8);
|
308
328
|
return 0;
|
309
329
|
}
|
310
330
|
|
@@ -312,4 +332,3 @@ int mochilo_unpack_one(mo_value *_value, mochilo_src *src)
|
|
312
332
|
}
|
313
333
|
}
|
314
334
|
}
|
315
|
-
|
data/lib/mochilo/version.rb
CHANGED
data/mochilo.gemspec
CHANGED
@@ -13,10 +13,12 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.require_paths = ["lib"]
|
14
14
|
s.rubygems_version = %q{1.4.2}
|
15
15
|
s.summary = %q{A ruby library for BananaPack}
|
16
|
-
s.test_files = `git ls-files
|
16
|
+
s.test_files = `git ls-files spec`.split("\n")
|
17
17
|
s.required_ruby_version = ">= 1.9.3"
|
18
18
|
|
19
19
|
# tests
|
20
20
|
s.add_development_dependency 'rake-compiler', ">= 0.8.1"
|
21
21
|
s.add_development_dependency 'minitest', ">= 4.1.0"
|
22
|
+
# benchmarks
|
23
|
+
s.add_development_dependency 'msgpack'
|
22
24
|
end
|
data/script/bootstrap
CHANGED