ed-precompiled_msgpack 1.8.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 +7 -0
- data/ChangeLog +368 -0
- data/LICENSE +177 -0
- data/README.md +302 -0
- data/ext/java/org/msgpack/jruby/Buffer.java +233 -0
- data/ext/java/org/msgpack/jruby/Decoder.java +307 -0
- data/ext/java/org/msgpack/jruby/Encoder.java +456 -0
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +167 -0
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +128 -0
- data/ext/java/org/msgpack/jruby/Factory.java +130 -0
- data/ext/java/org/msgpack/jruby/MessagePackLibrary.java +45 -0
- data/ext/java/org/msgpack/jruby/Packer.java +266 -0
- data/ext/java/org/msgpack/jruby/Types.java +37 -0
- data/ext/java/org/msgpack/jruby/Unpacker.java +336 -0
- data/ext/msgpack/buffer.c +669 -0
- data/ext/msgpack/buffer.h +604 -0
- data/ext/msgpack/buffer_class.c +616 -0
- data/ext/msgpack/buffer_class.h +33 -0
- data/ext/msgpack/compat.h +26 -0
- data/ext/msgpack/extconf.rb +53 -0
- data/ext/msgpack/extension_value_class.c +34 -0
- data/ext/msgpack/extension_value_class.h +31 -0
- data/ext/msgpack/factory_class.c +276 -0
- data/ext/msgpack/factory_class.h +33 -0
- data/ext/msgpack/packer.c +199 -0
- data/ext/msgpack/packer.h +513 -0
- data/ext/msgpack/packer_class.c +442 -0
- data/ext/msgpack/packer_class.h +43 -0
- data/ext/msgpack/packer_ext_registry.c +74 -0
- data/ext/msgpack/packer_ext_registry.h +140 -0
- data/ext/msgpack/rbinit.c +35 -0
- data/ext/msgpack/rmem.c +93 -0
- data/ext/msgpack/rmem.h +109 -0
- data/ext/msgpack/sysdep.h +118 -0
- data/ext/msgpack/sysdep_endian.h +50 -0
- data/ext/msgpack/sysdep_types.h +46 -0
- data/ext/msgpack/unpacker.c +986 -0
- data/ext/msgpack/unpacker.h +152 -0
- data/ext/msgpack/unpacker_class.c +447 -0
- data/ext/msgpack/unpacker_class.h +43 -0
- data/ext/msgpack/unpacker_ext_registry.c +74 -0
- data/ext/msgpack/unpacker_ext_registry.h +62 -0
- data/lib/msgpack/bigint.rb +69 -0
- data/lib/msgpack/buffer.rb +9 -0
- data/lib/msgpack/core_ext.rb +139 -0
- data/lib/msgpack/factory.rb +211 -0
- data/lib/msgpack/packer.rb +37 -0
- data/lib/msgpack/symbol.rb +26 -0
- data/lib/msgpack/time.rb +29 -0
- data/lib/msgpack/timestamp.rb +76 -0
- data/lib/msgpack/unpacker.rb +41 -0
- data/lib/msgpack/version.rb +6 -0
- data/lib/msgpack.rb +53 -0
- data/msgpack.gemspec +41 -0
- metadata +216 -0
@@ -0,0 +1,616 @@
|
|
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 "buffer.h"
|
22
|
+
#include "buffer_class.h"
|
23
|
+
|
24
|
+
VALUE cMessagePack_Buffer = Qnil;
|
25
|
+
VALUE cMessagePack_HeldBuffer = Qnil;
|
26
|
+
|
27
|
+
static ID s_read;
|
28
|
+
static ID s_readpartial;
|
29
|
+
static ID s_write;
|
30
|
+
static ID s_append;
|
31
|
+
static ID s_close;
|
32
|
+
static ID s_at_owner;
|
33
|
+
|
34
|
+
static VALUE sym_read_reference_threshold;
|
35
|
+
static VALUE sym_write_reference_threshold;
|
36
|
+
static VALUE sym_io_buffer_size;
|
37
|
+
|
38
|
+
typedef struct msgpack_held_buffer_t msgpack_held_buffer_t;
|
39
|
+
struct msgpack_held_buffer_t {
|
40
|
+
size_t size;
|
41
|
+
VALUE mapped_strings[];
|
42
|
+
};
|
43
|
+
|
44
|
+
static void HeldBuffer_mark(void *data)
|
45
|
+
{
|
46
|
+
msgpack_held_buffer_t* held_buffer = (msgpack_held_buffer_t*)data;
|
47
|
+
for (size_t index = 0; index < held_buffer->size; index++) {
|
48
|
+
rb_gc_mark(held_buffer->mapped_strings[index]);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
static size_t HeldBuffer_memsize(const void *data)
|
53
|
+
{
|
54
|
+
const msgpack_held_buffer_t* held_buffer = (msgpack_held_buffer_t*)data;
|
55
|
+
return sizeof(size_t) + sizeof(VALUE) * held_buffer->size;
|
56
|
+
}
|
57
|
+
|
58
|
+
static const rb_data_type_t held_buffer_data_type = {
|
59
|
+
.wrap_struct_name = "msgpack:held_buffer",
|
60
|
+
.function = {
|
61
|
+
.dmark = HeldBuffer_mark,
|
62
|
+
.dfree = RUBY_TYPED_DEFAULT_FREE,
|
63
|
+
.dsize = HeldBuffer_memsize,
|
64
|
+
},
|
65
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
66
|
+
};
|
67
|
+
|
68
|
+
VALUE MessagePack_Buffer_hold(msgpack_buffer_t* buffer)
|
69
|
+
{
|
70
|
+
size_t mapped_strings_count = 0;
|
71
|
+
msgpack_buffer_chunk_t* c = buffer->head;
|
72
|
+
while (c != &buffer->tail) {
|
73
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
74
|
+
mapped_strings_count++;
|
75
|
+
}
|
76
|
+
c = c->next;
|
77
|
+
}
|
78
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
79
|
+
mapped_strings_count++;
|
80
|
+
}
|
81
|
+
|
82
|
+
if (mapped_strings_count == 0) {
|
83
|
+
return Qnil;
|
84
|
+
}
|
85
|
+
|
86
|
+
msgpack_held_buffer_t* held_buffer = xmalloc(sizeof(msgpack_held_buffer_t) + mapped_strings_count * sizeof(VALUE));
|
87
|
+
|
88
|
+
c = buffer->head;
|
89
|
+
mapped_strings_count = 0;
|
90
|
+
while (c != &buffer->tail) {
|
91
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
92
|
+
held_buffer->mapped_strings[mapped_strings_count] = c->mapped_string;
|
93
|
+
mapped_strings_count++;
|
94
|
+
}
|
95
|
+
c = c->next;
|
96
|
+
}
|
97
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
98
|
+
held_buffer->mapped_strings[mapped_strings_count] = c->mapped_string;
|
99
|
+
mapped_strings_count++;
|
100
|
+
}
|
101
|
+
held_buffer->size = mapped_strings_count;
|
102
|
+
return TypedData_Wrap_Struct(cMessagePack_HeldBuffer, &held_buffer_data_type, held_buffer);
|
103
|
+
}
|
104
|
+
|
105
|
+
|
106
|
+
#define CHECK_STRING_TYPE(value) \
|
107
|
+
value = rb_check_string_type(value); \
|
108
|
+
if( NIL_P(value) ) { \
|
109
|
+
rb_raise(rb_eTypeError, "instance of String needed"); \
|
110
|
+
}
|
111
|
+
|
112
|
+
static void Buffer_free(void* data)
|
113
|
+
{
|
114
|
+
if(data == NULL) {
|
115
|
+
return;
|
116
|
+
}
|
117
|
+
msgpack_buffer_t* b = (msgpack_buffer_t*) data;
|
118
|
+
msgpack_buffer_destroy(b);
|
119
|
+
xfree(b);
|
120
|
+
}
|
121
|
+
|
122
|
+
static size_t Buffer_memsize(const void *data)
|
123
|
+
{
|
124
|
+
return sizeof(msgpack_buffer_t) + msgpack_buffer_memsize(data);
|
125
|
+
}
|
126
|
+
|
127
|
+
static const rb_data_type_t buffer_data_type = {
|
128
|
+
.wrap_struct_name = "msgpack:buffer",
|
129
|
+
.function = {
|
130
|
+
.dmark = msgpack_buffer_mark,
|
131
|
+
.dfree = Buffer_free,
|
132
|
+
.dsize = Buffer_memsize,
|
133
|
+
},
|
134
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
135
|
+
};
|
136
|
+
|
137
|
+
static const rb_data_type_t buffer_view_data_type = {
|
138
|
+
.wrap_struct_name = "msgpack:buffer_view",
|
139
|
+
.function = {
|
140
|
+
.dmark = NULL,
|
141
|
+
.dfree = NULL,
|
142
|
+
.dsize = NULL,
|
143
|
+
},
|
144
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
145
|
+
};
|
146
|
+
|
147
|
+
static inline msgpack_buffer_t *MessagePack_Buffer_get(VALUE object)
|
148
|
+
{
|
149
|
+
msgpack_buffer_t *buffer;
|
150
|
+
bool view = RTEST(rb_ivar_get(object, s_at_owner));
|
151
|
+
TypedData_Get_Struct(object, msgpack_buffer_t, view ? &buffer_view_data_type : &buffer_data_type, buffer);
|
152
|
+
if (!buffer) {
|
153
|
+
rb_raise(rb_eArgError, "Uninitialized Buffer object");
|
154
|
+
}
|
155
|
+
return buffer;
|
156
|
+
}
|
157
|
+
|
158
|
+
static VALUE Buffer_alloc(VALUE klass)
|
159
|
+
{
|
160
|
+
msgpack_buffer_t* b;
|
161
|
+
VALUE buffer = TypedData_Make_Struct(klass, msgpack_buffer_t, &buffer_data_type, b);
|
162
|
+
msgpack_buffer_init(b);
|
163
|
+
rb_ivar_set(buffer, s_at_owner, Qnil);
|
164
|
+
return buffer;
|
165
|
+
}
|
166
|
+
|
167
|
+
static ID get_partial_read_method(VALUE io)
|
168
|
+
{
|
169
|
+
if(io != Qnil && rb_respond_to(io, s_readpartial)) {
|
170
|
+
return s_readpartial;
|
171
|
+
}
|
172
|
+
return s_read;
|
173
|
+
}
|
174
|
+
|
175
|
+
static ID get_write_all_method(VALUE io)
|
176
|
+
{
|
177
|
+
if(io != Qnil) {
|
178
|
+
if(rb_respond_to(io, s_write)) {
|
179
|
+
return s_write;
|
180
|
+
} else if(rb_respond_to(io, s_append)) {
|
181
|
+
return s_append;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
return s_write;
|
185
|
+
}
|
186
|
+
|
187
|
+
void MessagePack_Buffer_set_options(msgpack_buffer_t* b, VALUE io, VALUE options)
|
188
|
+
{
|
189
|
+
b->io = io;
|
190
|
+
b->io_partial_read_method = get_partial_read_method(io);
|
191
|
+
b->io_write_all_method = get_write_all_method(io);
|
192
|
+
|
193
|
+
if(options != Qnil) {
|
194
|
+
VALUE v;
|
195
|
+
|
196
|
+
v = rb_hash_aref(options, sym_read_reference_threshold);
|
197
|
+
if(v != Qnil) {
|
198
|
+
msgpack_buffer_set_read_reference_threshold(b, NUM2SIZET(v));
|
199
|
+
}
|
200
|
+
|
201
|
+
v = rb_hash_aref(options, sym_write_reference_threshold);
|
202
|
+
if(v != Qnil) {
|
203
|
+
msgpack_buffer_set_write_reference_threshold(b, NUM2SIZET(v));
|
204
|
+
}
|
205
|
+
|
206
|
+
v = rb_hash_aref(options, sym_io_buffer_size);
|
207
|
+
if(v != Qnil) {
|
208
|
+
msgpack_buffer_set_io_buffer_size(b, NUM2SIZET(v));
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
VALUE MessagePack_Buffer_wrap(msgpack_buffer_t* b, VALUE owner)
|
214
|
+
{
|
215
|
+
VALUE buffer = TypedData_Wrap_Struct(cMessagePack_Buffer, &buffer_view_data_type, b);
|
216
|
+
rb_ivar_set(buffer, s_at_owner, owner);
|
217
|
+
return buffer;
|
218
|
+
}
|
219
|
+
|
220
|
+
static VALUE Buffer_initialize(int argc, VALUE* argv, VALUE self)
|
221
|
+
{
|
222
|
+
VALUE io = Qnil;
|
223
|
+
VALUE options = Qnil;
|
224
|
+
|
225
|
+
if(argc == 0 || (argc == 1 && argv[0] == Qnil)) {
|
226
|
+
/* Qnil */
|
227
|
+
|
228
|
+
} else if(argc == 1) {
|
229
|
+
VALUE v = argv[0];
|
230
|
+
if(rb_type(v) == T_HASH) {
|
231
|
+
options = v;
|
232
|
+
} else {
|
233
|
+
io = v;
|
234
|
+
}
|
235
|
+
|
236
|
+
} else if(argc == 2) {
|
237
|
+
io = argv[0];
|
238
|
+
options = argv[1];
|
239
|
+
if(rb_type(options) != T_HASH) {
|
240
|
+
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(io));
|
241
|
+
}
|
242
|
+
|
243
|
+
} else {
|
244
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc);
|
245
|
+
}
|
246
|
+
|
247
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
248
|
+
|
249
|
+
MessagePack_Buffer_set_options(b, io, options);
|
250
|
+
|
251
|
+
return self;
|
252
|
+
}
|
253
|
+
|
254
|
+
static VALUE Buffer_clear(VALUE self)
|
255
|
+
{
|
256
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
257
|
+
msgpack_buffer_clear(b);
|
258
|
+
return Qnil;
|
259
|
+
}
|
260
|
+
|
261
|
+
static VALUE Buffer_size(VALUE self)
|
262
|
+
{
|
263
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
264
|
+
size_t size = msgpack_buffer_all_readable_size(b);
|
265
|
+
return SIZET2NUM(size);
|
266
|
+
}
|
267
|
+
|
268
|
+
static VALUE Buffer_empty_p(VALUE self)
|
269
|
+
{
|
270
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
271
|
+
if(msgpack_buffer_top_readable_size(b) == 0) {
|
272
|
+
return Qtrue;
|
273
|
+
} else {
|
274
|
+
return Qfalse;
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
static VALUE Buffer_write(VALUE self, VALUE string_or_buffer)
|
279
|
+
{
|
280
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
281
|
+
|
282
|
+
VALUE string = string_or_buffer; // TODO optimize if string_or_buffer is a Buffer
|
283
|
+
StringValue(string);
|
284
|
+
|
285
|
+
size_t length = msgpack_buffer_append_string(b, string);
|
286
|
+
|
287
|
+
return SIZET2NUM(length);
|
288
|
+
}
|
289
|
+
|
290
|
+
static VALUE Buffer_append(VALUE self, VALUE string_or_buffer)
|
291
|
+
{
|
292
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
293
|
+
|
294
|
+
VALUE string = string_or_buffer; // TODO optimize if string_or_buffer is a Buffer
|
295
|
+
StringValue(string);
|
296
|
+
|
297
|
+
msgpack_buffer_append_string(b, string);
|
298
|
+
|
299
|
+
return self;
|
300
|
+
}
|
301
|
+
|
302
|
+
|
303
|
+
#define MAKE_EMPTY_STRING(orig) \
|
304
|
+
if(orig == Qnil) { \
|
305
|
+
orig = rb_str_buf_new(0); \
|
306
|
+
} else { \
|
307
|
+
rb_str_resize(orig, 0); \
|
308
|
+
}
|
309
|
+
|
310
|
+
static VALUE read_until_eof_rescue(VALUE args)
|
311
|
+
{
|
312
|
+
msgpack_buffer_t* b = (void*) ((VALUE*) args)[0];
|
313
|
+
VALUE out = ((VALUE*) args)[1];
|
314
|
+
unsigned long max = ((VALUE*) args)[2];
|
315
|
+
size_t* sz = (void*) ((VALUE*) args)[3];
|
316
|
+
|
317
|
+
while(true) {
|
318
|
+
size_t rl;
|
319
|
+
if(max == 0) {
|
320
|
+
if(out == Qnil) {
|
321
|
+
rl = msgpack_buffer_skip(b, b->io_buffer_size);
|
322
|
+
} else {
|
323
|
+
rl = msgpack_buffer_read_to_string(b, out, b->io_buffer_size);
|
324
|
+
}
|
325
|
+
if(rl == 0) {
|
326
|
+
break;
|
327
|
+
}
|
328
|
+
*sz += rl;
|
329
|
+
|
330
|
+
} else {
|
331
|
+
if(out == Qnil) {
|
332
|
+
rl = msgpack_buffer_skip(b, max);
|
333
|
+
} else {
|
334
|
+
rl = msgpack_buffer_read_to_string(b, out, max);
|
335
|
+
}
|
336
|
+
if(rl == 0) {
|
337
|
+
break;
|
338
|
+
}
|
339
|
+
*sz += rl;
|
340
|
+
if(max <= rl) {
|
341
|
+
break;
|
342
|
+
} else {
|
343
|
+
max -= rl;
|
344
|
+
}
|
345
|
+
}
|
346
|
+
}
|
347
|
+
|
348
|
+
return Qnil;
|
349
|
+
}
|
350
|
+
|
351
|
+
static VALUE read_until_eof_error(VALUE args, VALUE error)
|
352
|
+
{
|
353
|
+
/* ignore EOFError */
|
354
|
+
UNUSED(args);
|
355
|
+
UNUSED(error);
|
356
|
+
return Qnil;
|
357
|
+
}
|
358
|
+
|
359
|
+
static inline size_t read_until_eof(msgpack_buffer_t* b, VALUE out, unsigned long max)
|
360
|
+
{
|
361
|
+
if(msgpack_buffer_has_io(b)) {
|
362
|
+
size_t sz = 0;
|
363
|
+
VALUE args[4] = { (VALUE)(void*) b, out, (VALUE) max, (VALUE)(void*) &sz };
|
364
|
+
rb_rescue2(read_until_eof_rescue, (VALUE)(void*) args,
|
365
|
+
read_until_eof_error, (VALUE)(void*) args,
|
366
|
+
rb_eEOFError, NULL);
|
367
|
+
return sz;
|
368
|
+
|
369
|
+
} else {
|
370
|
+
if(max == 0) {
|
371
|
+
max = ULONG_MAX;
|
372
|
+
}
|
373
|
+
if(out == Qnil) {
|
374
|
+
return msgpack_buffer_skip_nonblock(b, max);
|
375
|
+
} else {
|
376
|
+
return msgpack_buffer_read_to_string_nonblock(b, out, max);
|
377
|
+
}
|
378
|
+
}
|
379
|
+
}
|
380
|
+
|
381
|
+
static inline VALUE read_all(msgpack_buffer_t* b, VALUE out)
|
382
|
+
{
|
383
|
+
if(out == Qnil && !msgpack_buffer_has_io(b)) {
|
384
|
+
/* same as to_s && clear; optimize */
|
385
|
+
VALUE str = msgpack_buffer_all_as_string(b);
|
386
|
+
msgpack_buffer_clear(b);
|
387
|
+
return str;
|
388
|
+
}
|
389
|
+
|
390
|
+
MAKE_EMPTY_STRING(out);
|
391
|
+
read_until_eof(b, out, 0);
|
392
|
+
return out;
|
393
|
+
}
|
394
|
+
|
395
|
+
static VALUE Buffer_skip(VALUE self, VALUE sn)
|
396
|
+
{
|
397
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
398
|
+
|
399
|
+
unsigned long n = FIX2ULONG(sn);
|
400
|
+
|
401
|
+
/* do nothing */
|
402
|
+
if(n == 0) {
|
403
|
+
return INT2NUM(0);
|
404
|
+
}
|
405
|
+
|
406
|
+
size_t sz = read_until_eof(b, Qnil, n);
|
407
|
+
return SIZET2NUM(sz);
|
408
|
+
}
|
409
|
+
|
410
|
+
static VALUE Buffer_skip_all(VALUE self, VALUE sn)
|
411
|
+
{
|
412
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
413
|
+
|
414
|
+
unsigned long n = FIX2ULONG(sn);
|
415
|
+
|
416
|
+
/* do nothing */
|
417
|
+
if(n == 0) {
|
418
|
+
return self;
|
419
|
+
}
|
420
|
+
|
421
|
+
if(!msgpack_buffer_ensure_readable(b, n)) {
|
422
|
+
rb_raise(rb_eEOFError, "end of buffer reached");
|
423
|
+
}
|
424
|
+
|
425
|
+
msgpack_buffer_skip_nonblock(b, n);
|
426
|
+
|
427
|
+
return self;
|
428
|
+
}
|
429
|
+
|
430
|
+
static VALUE Buffer_read_all(int argc, VALUE* argv, VALUE self)
|
431
|
+
{
|
432
|
+
VALUE out = Qnil;
|
433
|
+
unsigned long n = 0;
|
434
|
+
bool all = false;
|
435
|
+
|
436
|
+
switch(argc) {
|
437
|
+
case 2:
|
438
|
+
out = argv[1];
|
439
|
+
/* pass through */
|
440
|
+
case 1:
|
441
|
+
n = FIX2ULONG(argv[0]);
|
442
|
+
break;
|
443
|
+
case 0:
|
444
|
+
all = true;
|
445
|
+
break;
|
446
|
+
default:
|
447
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
|
448
|
+
}
|
449
|
+
|
450
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
451
|
+
|
452
|
+
if(out != Qnil) {
|
453
|
+
CHECK_STRING_TYPE(out);
|
454
|
+
}
|
455
|
+
|
456
|
+
if(all) {
|
457
|
+
return read_all(b, out);
|
458
|
+
}
|
459
|
+
|
460
|
+
if(n == 0) {
|
461
|
+
/* do nothing */
|
462
|
+
MAKE_EMPTY_STRING(out);
|
463
|
+
return out;
|
464
|
+
}
|
465
|
+
|
466
|
+
if(!msgpack_buffer_ensure_readable(b, n)) {
|
467
|
+
rb_raise(rb_eEOFError, "end of buffer reached");
|
468
|
+
}
|
469
|
+
|
470
|
+
MAKE_EMPTY_STRING(out);
|
471
|
+
msgpack_buffer_read_to_string_nonblock(b, out, n);
|
472
|
+
|
473
|
+
return out;
|
474
|
+
}
|
475
|
+
|
476
|
+
static VALUE Buffer_read(int argc, VALUE* argv, VALUE self)
|
477
|
+
{
|
478
|
+
VALUE out = Qnil;
|
479
|
+
unsigned long n = -1;
|
480
|
+
bool all = false;
|
481
|
+
|
482
|
+
switch(argc) {
|
483
|
+
case 2:
|
484
|
+
out = argv[1];
|
485
|
+
/* pass through */
|
486
|
+
case 1:
|
487
|
+
n = FIX2ULONG(argv[0]);
|
488
|
+
break;
|
489
|
+
case 0:
|
490
|
+
all = true;
|
491
|
+
break;
|
492
|
+
default:
|
493
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
|
494
|
+
}
|
495
|
+
|
496
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
497
|
+
|
498
|
+
if(out != Qnil) {
|
499
|
+
CHECK_STRING_TYPE(out);
|
500
|
+
}
|
501
|
+
|
502
|
+
if(all) {
|
503
|
+
return read_all(b, out);
|
504
|
+
}
|
505
|
+
|
506
|
+
if(n == 0) {
|
507
|
+
/* do nothing */
|
508
|
+
MAKE_EMPTY_STRING(out);
|
509
|
+
return out;
|
510
|
+
}
|
511
|
+
|
512
|
+
if(!msgpack_buffer_has_io(b) && out == Qnil &&
|
513
|
+
msgpack_buffer_all_readable_size(b) <= n) {
|
514
|
+
/* same as to_s && clear; optimize */
|
515
|
+
VALUE str = msgpack_buffer_all_as_string(b);
|
516
|
+
msgpack_buffer_clear(b);
|
517
|
+
|
518
|
+
if(RSTRING_LEN(str) == 0) {
|
519
|
+
return Qnil;
|
520
|
+
} else {
|
521
|
+
return str;
|
522
|
+
}
|
523
|
+
}
|
524
|
+
|
525
|
+
MAKE_EMPTY_STRING(out);
|
526
|
+
read_until_eof(b, out, n);
|
527
|
+
|
528
|
+
if(RSTRING_LEN(out) == 0) {
|
529
|
+
return Qnil;
|
530
|
+
} else {
|
531
|
+
return out;
|
532
|
+
}
|
533
|
+
}
|
534
|
+
|
535
|
+
static VALUE Buffer_to_str(VALUE self)
|
536
|
+
{
|
537
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
538
|
+
return msgpack_buffer_all_as_string(b);
|
539
|
+
}
|
540
|
+
|
541
|
+
static VALUE Buffer_to_a(VALUE self)
|
542
|
+
{
|
543
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
544
|
+
return msgpack_buffer_all_as_string_array(b);
|
545
|
+
}
|
546
|
+
|
547
|
+
static VALUE Buffer_flush(VALUE self)
|
548
|
+
{
|
549
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
550
|
+
msgpack_buffer_flush(b);
|
551
|
+
return self;
|
552
|
+
}
|
553
|
+
|
554
|
+
static VALUE Buffer_io(VALUE self)
|
555
|
+
{
|
556
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
557
|
+
return b->io;
|
558
|
+
}
|
559
|
+
|
560
|
+
static VALUE Buffer_close(VALUE self)
|
561
|
+
{
|
562
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
563
|
+
if(b->io != Qnil) {
|
564
|
+
return rb_funcall(b->io, s_close, 0);
|
565
|
+
}
|
566
|
+
return Qnil;
|
567
|
+
}
|
568
|
+
|
569
|
+
static VALUE Buffer_write_to(VALUE self, VALUE io)
|
570
|
+
{
|
571
|
+
msgpack_buffer_t *b = MessagePack_Buffer_get(self);
|
572
|
+
size_t sz = msgpack_buffer_flush_to_io(b, io, s_write, true);
|
573
|
+
return SIZET2NUM(sz);
|
574
|
+
}
|
575
|
+
|
576
|
+
void MessagePack_Buffer_module_init(VALUE mMessagePack)
|
577
|
+
{
|
578
|
+
s_read = rb_intern("read");
|
579
|
+
s_readpartial = rb_intern("readpartial");
|
580
|
+
s_write = rb_intern("write");
|
581
|
+
s_append = rb_intern("<<");
|
582
|
+
s_close = rb_intern("close");
|
583
|
+
s_at_owner = rb_intern("@owner");
|
584
|
+
|
585
|
+
sym_read_reference_threshold = ID2SYM(rb_intern("read_reference_threshold"));
|
586
|
+
sym_write_reference_threshold = ID2SYM(rb_intern("write_reference_threshold"));
|
587
|
+
sym_io_buffer_size = ID2SYM(rb_intern("io_buffer_size"));
|
588
|
+
|
589
|
+
msgpack_buffer_static_init();
|
590
|
+
|
591
|
+
cMessagePack_HeldBuffer = rb_define_class_under(mMessagePack, "HeldBuffer", rb_cBasicObject);
|
592
|
+
rb_undef_alloc_func(cMessagePack_HeldBuffer);
|
593
|
+
|
594
|
+
cMessagePack_Buffer = rb_define_class_under(mMessagePack, "Buffer", rb_cObject);
|
595
|
+
|
596
|
+
rb_define_alloc_func(cMessagePack_Buffer, Buffer_alloc);
|
597
|
+
|
598
|
+
rb_define_method(cMessagePack_Buffer, "initialize", Buffer_initialize, -1);
|
599
|
+
rb_define_method(cMessagePack_Buffer, "clear", Buffer_clear, 0);
|
600
|
+
rb_define_method(cMessagePack_Buffer, "size", Buffer_size, 0);
|
601
|
+
rb_define_method(cMessagePack_Buffer, "empty?", Buffer_empty_p, 0);
|
602
|
+
rb_define_method(cMessagePack_Buffer, "write", Buffer_write, 1);
|
603
|
+
rb_define_method(cMessagePack_Buffer, "<<", Buffer_append, 1);
|
604
|
+
rb_define_method(cMessagePack_Buffer, "skip", Buffer_skip, 1);
|
605
|
+
rb_define_method(cMessagePack_Buffer, "skip_all", Buffer_skip_all, 1);
|
606
|
+
rb_define_method(cMessagePack_Buffer, "read", Buffer_read, -1);
|
607
|
+
rb_define_method(cMessagePack_Buffer, "read_all", Buffer_read_all, -1);
|
608
|
+
rb_define_method(cMessagePack_Buffer, "io", Buffer_io, 0);
|
609
|
+
rb_define_method(cMessagePack_Buffer, "flush", Buffer_flush, 0);
|
610
|
+
rb_define_method(cMessagePack_Buffer, "close", Buffer_close, 0);
|
611
|
+
rb_define_method(cMessagePack_Buffer, "write_to", Buffer_write_to, 1);
|
612
|
+
rb_define_method(cMessagePack_Buffer, "to_str", Buffer_to_str, 0);
|
613
|
+
rb_define_alias(cMessagePack_Buffer, "to_s", "to_str");
|
614
|
+
rb_define_method(cMessagePack_Buffer, "to_a", Buffer_to_a, 0);
|
615
|
+
}
|
616
|
+
|
@@ -0,0 +1,33 @@
|
|
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_BUFFER_CLASS_H__
|
19
|
+
#define MSGPACK_RUBY_BUFFER_CLASS_H__
|
20
|
+
|
21
|
+
#include "buffer.h"
|
22
|
+
|
23
|
+
extern VALUE cMessagePack_Buffer;
|
24
|
+
|
25
|
+
void MessagePack_Buffer_module_init(VALUE mMessagePack);
|
26
|
+
|
27
|
+
VALUE MessagePack_Buffer_wrap(msgpack_buffer_t* b, VALUE owner);
|
28
|
+
VALUE MessagePack_Buffer_hold(msgpack_buffer_t* b);
|
29
|
+
|
30
|
+
void MessagePack_Buffer_set_options(msgpack_buffer_t* b, VALUE io, VALUE options);
|
31
|
+
|
32
|
+
#endif
|
33
|
+
|
@@ -0,0 +1,26 @@
|
|
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_COMPAT_H__
|
19
|
+
#define MSGPACK_RUBY_COMPAT_H__
|
20
|
+
|
21
|
+
#include <stdbool.h>
|
22
|
+
#include "ruby.h"
|
23
|
+
#include "ruby/encoding.h"
|
24
|
+
|
25
|
+
#endif
|
26
|
+
|