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,152 @@
|
|
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_UNPACKER_H__
|
19
|
+
#define MSGPACK_RUBY_UNPACKER_H__
|
20
|
+
|
21
|
+
#include "buffer.h"
|
22
|
+
#include "unpacker_ext_registry.h"
|
23
|
+
|
24
|
+
#define MSGPACK_UNPACKER_STACK_CAPACITY 128
|
25
|
+
|
26
|
+
struct msgpack_unpacker_t;
|
27
|
+
typedef struct msgpack_unpacker_t msgpack_unpacker_t;
|
28
|
+
typedef struct msgpack_unpacker_stack_t msgpack_unpacker_stack_t;
|
29
|
+
|
30
|
+
enum stack_type_t {
|
31
|
+
STACK_TYPE_ARRAY,
|
32
|
+
STACK_TYPE_MAP_KEY,
|
33
|
+
STACK_TYPE_MAP_VALUE,
|
34
|
+
STACK_TYPE_RECURSIVE,
|
35
|
+
};
|
36
|
+
|
37
|
+
typedef struct {
|
38
|
+
size_t count;
|
39
|
+
enum stack_type_t type;
|
40
|
+
VALUE object;
|
41
|
+
VALUE key;
|
42
|
+
} msgpack_unpacker_stack_entry_t;
|
43
|
+
|
44
|
+
struct msgpack_unpacker_stack_t {
|
45
|
+
size_t depth;
|
46
|
+
size_t capacity;
|
47
|
+
msgpack_unpacker_stack_entry_t *data;
|
48
|
+
};
|
49
|
+
|
50
|
+
struct msgpack_unpacker_t {
|
51
|
+
msgpack_buffer_t buffer;
|
52
|
+
msgpack_unpacker_stack_t stack;
|
53
|
+
msgpack_key_cache_t key_cache;
|
54
|
+
|
55
|
+
VALUE self;
|
56
|
+
VALUE last_object;
|
57
|
+
|
58
|
+
VALUE reading_raw;
|
59
|
+
size_t reading_raw_remaining;
|
60
|
+
|
61
|
+
VALUE buffer_ref;
|
62
|
+
|
63
|
+
msgpack_unpacker_ext_registry_t *ext_registry;
|
64
|
+
|
65
|
+
int reading_raw_type;
|
66
|
+
unsigned int head_byte;
|
67
|
+
|
68
|
+
/* options */
|
69
|
+
int symbol_ext_type;
|
70
|
+
|
71
|
+
bool use_key_cache: 1;
|
72
|
+
bool symbolize_keys: 1;
|
73
|
+
bool freeze: 1;
|
74
|
+
bool allow_unknown_ext: 1;
|
75
|
+
bool optimized_symbol_ext_type: 1;
|
76
|
+
};
|
77
|
+
|
78
|
+
#define UNPACKER_BUFFER_(uk) (&(uk)->buffer)
|
79
|
+
|
80
|
+
enum msgpack_unpacker_object_type {
|
81
|
+
TYPE_NIL = 0,
|
82
|
+
TYPE_BOOLEAN,
|
83
|
+
TYPE_INTEGER,
|
84
|
+
TYPE_FLOAT,
|
85
|
+
TYPE_RAW,
|
86
|
+
TYPE_ARRAY,
|
87
|
+
TYPE_MAP,
|
88
|
+
};
|
89
|
+
|
90
|
+
void msgpack_unpacker_static_init(void);
|
91
|
+
|
92
|
+
void msgpack_unpacker_static_destroy(void);
|
93
|
+
|
94
|
+
void _msgpack_unpacker_init(msgpack_unpacker_t*);
|
95
|
+
|
96
|
+
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
|
97
|
+
|
98
|
+
void msgpack_unpacker_mark(msgpack_unpacker_t* uk);
|
99
|
+
|
100
|
+
void _msgpack_unpacker_reset(msgpack_unpacker_t* uk);
|
101
|
+
|
102
|
+
static inline void msgpack_unpacker_set_symbolized_keys(msgpack_unpacker_t* uk, bool enable)
|
103
|
+
{
|
104
|
+
uk->symbolize_keys = enable;
|
105
|
+
}
|
106
|
+
|
107
|
+
static inline void msgpack_unpacker_set_key_cache(msgpack_unpacker_t* uk, bool enable)
|
108
|
+
{
|
109
|
+
uk->use_key_cache = enable;
|
110
|
+
}
|
111
|
+
|
112
|
+
static inline void msgpack_unpacker_set_freeze(msgpack_unpacker_t* uk, bool enable)
|
113
|
+
{
|
114
|
+
uk->freeze = enable;
|
115
|
+
}
|
116
|
+
|
117
|
+
static inline void msgpack_unpacker_set_allow_unknown_ext(msgpack_unpacker_t* uk, bool enable)
|
118
|
+
{
|
119
|
+
uk->allow_unknown_ext = enable;
|
120
|
+
}
|
121
|
+
|
122
|
+
|
123
|
+
/* error codes */
|
124
|
+
#define PRIMITIVE_CONTAINER_START 1
|
125
|
+
#define PRIMITIVE_OBJECT_COMPLETE 0
|
126
|
+
#define PRIMITIVE_EOF -1
|
127
|
+
#define PRIMITIVE_INVALID_BYTE -2
|
128
|
+
#define PRIMITIVE_STACK_TOO_DEEP -3
|
129
|
+
#define PRIMITIVE_UNEXPECTED_TYPE -4
|
130
|
+
#define PRIMITIVE_UNEXPECTED_EXT_TYPE -5
|
131
|
+
#define PRIMITIVE_RECURSIVE_RAISED -6
|
132
|
+
|
133
|
+
int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth);
|
134
|
+
|
135
|
+
int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth);
|
136
|
+
|
137
|
+
static inline VALUE msgpack_unpacker_get_last_object(msgpack_unpacker_t* uk)
|
138
|
+
{
|
139
|
+
return uk->last_object;
|
140
|
+
}
|
141
|
+
|
142
|
+
|
143
|
+
int msgpack_unpacker_peek_next_object_type(msgpack_unpacker_t* uk);
|
144
|
+
|
145
|
+
int msgpack_unpacker_skip_nil(msgpack_unpacker_t* uk);
|
146
|
+
|
147
|
+
int msgpack_unpacker_read_array_header(msgpack_unpacker_t* uk, uint32_t* result_size);
|
148
|
+
|
149
|
+
int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint32_t* result_size);
|
150
|
+
|
151
|
+
#endif
|
152
|
+
|
@@ -0,0 +1,447 @@
|
|
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 "unpacker.h"
|
20
|
+
#include "unpacker_class.h"
|
21
|
+
#include "buffer_class.h"
|
22
|
+
#include "factory_class.h"
|
23
|
+
|
24
|
+
VALUE cMessagePack_Unpacker;
|
25
|
+
|
26
|
+
//static VALUE s_unpacker_value;
|
27
|
+
//static msgpack_unpacker_t* s_unpacker;
|
28
|
+
|
29
|
+
static VALUE eUnpackError;
|
30
|
+
static VALUE eMalformedFormatError;
|
31
|
+
static VALUE eStackError;
|
32
|
+
static VALUE eUnexpectedTypeError;
|
33
|
+
static VALUE eUnknownExtTypeError;
|
34
|
+
static VALUE mTypeError; // obsoleted. only for backward compatibility. See #86.
|
35
|
+
|
36
|
+
static VALUE sym_symbolize_keys;
|
37
|
+
static VALUE sym_key_cache;
|
38
|
+
static VALUE sym_freeze;
|
39
|
+
static VALUE sym_allow_unknown_ext;
|
40
|
+
|
41
|
+
static void Unpacker_free(void *ptr)
|
42
|
+
{
|
43
|
+
msgpack_unpacker_t* uk = ptr;
|
44
|
+
if(uk == NULL) {
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
msgpack_unpacker_ext_registry_release(uk->ext_registry);
|
48
|
+
_msgpack_unpacker_destroy(uk);
|
49
|
+
xfree(uk);
|
50
|
+
}
|
51
|
+
|
52
|
+
static void Unpacker_mark(void *ptr)
|
53
|
+
{
|
54
|
+
msgpack_unpacker_t* uk = ptr;
|
55
|
+
msgpack_buffer_mark(uk);
|
56
|
+
msgpack_unpacker_mark(uk);
|
57
|
+
msgpack_unpacker_ext_registry_mark(uk->ext_registry);
|
58
|
+
}
|
59
|
+
|
60
|
+
static size_t Unpacker_memsize(const void *ptr)
|
61
|
+
{
|
62
|
+
const msgpack_unpacker_t* uk = ptr;
|
63
|
+
|
64
|
+
size_t total_size = sizeof(msgpack_unpacker_t);
|
65
|
+
|
66
|
+
if (uk->ext_registry) {
|
67
|
+
total_size += sizeof(msgpack_unpacker_ext_registry_t) / (uk->ext_registry->borrow_count + 1);
|
68
|
+
}
|
69
|
+
|
70
|
+
if (uk->stack.data) {
|
71
|
+
total_size += (uk->stack.depth + 1) * sizeof(msgpack_unpacker_stack_t);
|
72
|
+
}
|
73
|
+
|
74
|
+
return total_size + msgpack_buffer_memsize(&uk->buffer);
|
75
|
+
}
|
76
|
+
|
77
|
+
const rb_data_type_t unpacker_data_type = {
|
78
|
+
.wrap_struct_name = "msgpack:unpacker",
|
79
|
+
.function = {
|
80
|
+
.dmark = Unpacker_mark,
|
81
|
+
.dfree = Unpacker_free,
|
82
|
+
.dsize = Unpacker_memsize,
|
83
|
+
},
|
84
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
85
|
+
};
|
86
|
+
|
87
|
+
VALUE MessagePack_Unpacker_alloc(VALUE klass)
|
88
|
+
{
|
89
|
+
msgpack_unpacker_t* uk;
|
90
|
+
VALUE self = TypedData_Make_Struct(klass, msgpack_unpacker_t, &unpacker_data_type, uk);
|
91
|
+
_msgpack_unpacker_init(uk);
|
92
|
+
uk->self = self;
|
93
|
+
return self;
|
94
|
+
}
|
95
|
+
|
96
|
+
VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
97
|
+
{
|
98
|
+
VALUE io = Qnil;
|
99
|
+
VALUE options = Qnil;
|
100
|
+
|
101
|
+
if(argc == 0 || (argc == 1 && argv[0] == Qnil)) {
|
102
|
+
/* Qnil */
|
103
|
+
|
104
|
+
} else if(argc == 1) {
|
105
|
+
VALUE v = argv[0];
|
106
|
+
if(rb_type(v) == T_HASH) {
|
107
|
+
options = v;
|
108
|
+
} else {
|
109
|
+
io = v;
|
110
|
+
}
|
111
|
+
|
112
|
+
} else if(argc == 2) {
|
113
|
+
io = argv[0];
|
114
|
+
options = argv[1];
|
115
|
+
if(options != Qnil && rb_type(options) != T_HASH) {
|
116
|
+
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
117
|
+
}
|
118
|
+
|
119
|
+
} else {
|
120
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
|
121
|
+
}
|
122
|
+
|
123
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
124
|
+
|
125
|
+
uk->buffer_ref = Qnil;
|
126
|
+
|
127
|
+
MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
|
128
|
+
|
129
|
+
if(options != Qnil) {
|
130
|
+
VALUE v;
|
131
|
+
|
132
|
+
v = rb_hash_aref(options, sym_key_cache);
|
133
|
+
msgpack_unpacker_set_key_cache(uk, RTEST(v));
|
134
|
+
|
135
|
+
v = rb_hash_aref(options, sym_symbolize_keys);
|
136
|
+
msgpack_unpacker_set_symbolized_keys(uk, RTEST(v));
|
137
|
+
|
138
|
+
v = rb_hash_aref(options, sym_freeze);
|
139
|
+
msgpack_unpacker_set_freeze(uk, RTEST(v));
|
140
|
+
|
141
|
+
v = rb_hash_aref(options, sym_allow_unknown_ext);
|
142
|
+
msgpack_unpacker_set_allow_unknown_ext(uk, RTEST(v));
|
143
|
+
}
|
144
|
+
|
145
|
+
return self;
|
146
|
+
}
|
147
|
+
|
148
|
+
static VALUE Unpacker_symbolized_keys_p(VALUE self)
|
149
|
+
{
|
150
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
151
|
+
return uk->symbolize_keys ? Qtrue : Qfalse;
|
152
|
+
}
|
153
|
+
|
154
|
+
static VALUE Unpacker_freeze_p(VALUE self)
|
155
|
+
{
|
156
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
157
|
+
return uk->freeze ? Qtrue : Qfalse;
|
158
|
+
}
|
159
|
+
|
160
|
+
static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
|
161
|
+
{
|
162
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
163
|
+
return uk->allow_unknown_ext ? Qtrue : Qfalse;
|
164
|
+
}
|
165
|
+
|
166
|
+
NORETURN(static void raise_unpacker_error(msgpack_unpacker_t *uk, int r))
|
167
|
+
{
|
168
|
+
uk->stack.depth = 0;
|
169
|
+
switch(r) {
|
170
|
+
case PRIMITIVE_EOF:
|
171
|
+
rb_raise(rb_eEOFError, "end of buffer reached");
|
172
|
+
break;
|
173
|
+
case PRIMITIVE_INVALID_BYTE:
|
174
|
+
rb_raise(eMalformedFormatError, "invalid byte");
|
175
|
+
break;
|
176
|
+
case PRIMITIVE_STACK_TOO_DEEP:
|
177
|
+
rb_raise(eStackError, "stack level too deep");
|
178
|
+
break;
|
179
|
+
case PRIMITIVE_UNEXPECTED_TYPE:
|
180
|
+
rb_raise(eUnexpectedTypeError, "unexpected type");
|
181
|
+
break;
|
182
|
+
case PRIMITIVE_UNEXPECTED_EXT_TYPE:
|
183
|
+
rb_raise(eUnknownExtTypeError, "unexpected extension type");
|
184
|
+
break;
|
185
|
+
case PRIMITIVE_RECURSIVE_RAISED:
|
186
|
+
rb_exc_raise(msgpack_unpacker_get_last_object(uk));
|
187
|
+
break;
|
188
|
+
default:
|
189
|
+
rb_raise(eUnpackError, "logically unknown error %d", r);
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
static VALUE Unpacker_buffer(VALUE self)
|
194
|
+
{
|
195
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
196
|
+
if (!RTEST(uk->buffer_ref)) {
|
197
|
+
uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
|
198
|
+
}
|
199
|
+
return uk->buffer_ref;
|
200
|
+
}
|
201
|
+
|
202
|
+
static VALUE Unpacker_read(VALUE self)
|
203
|
+
{
|
204
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
205
|
+
|
206
|
+
int r = msgpack_unpacker_read(uk, 0);
|
207
|
+
if(r < 0) {
|
208
|
+
raise_unpacker_error(uk, r);
|
209
|
+
}
|
210
|
+
|
211
|
+
return msgpack_unpacker_get_last_object(uk);
|
212
|
+
}
|
213
|
+
|
214
|
+
static VALUE Unpacker_skip(VALUE self)
|
215
|
+
{
|
216
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
217
|
+
|
218
|
+
int r = msgpack_unpacker_skip(uk, 0);
|
219
|
+
if(r < 0) {
|
220
|
+
raise_unpacker_error(uk, r);
|
221
|
+
}
|
222
|
+
|
223
|
+
return Qnil;
|
224
|
+
}
|
225
|
+
|
226
|
+
static VALUE Unpacker_skip_nil(VALUE self)
|
227
|
+
{
|
228
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
229
|
+
|
230
|
+
int r = msgpack_unpacker_skip_nil(uk);
|
231
|
+
if(r < 0) {
|
232
|
+
raise_unpacker_error(uk, r);
|
233
|
+
}
|
234
|
+
|
235
|
+
if(r) {
|
236
|
+
return Qtrue;
|
237
|
+
}
|
238
|
+
return Qfalse;
|
239
|
+
}
|
240
|
+
|
241
|
+
static VALUE Unpacker_read_array_header(VALUE self)
|
242
|
+
{
|
243
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
244
|
+
|
245
|
+
uint32_t size;
|
246
|
+
int r = msgpack_unpacker_read_array_header(uk, &size);
|
247
|
+
if(r < 0) {
|
248
|
+
raise_unpacker_error(uk, r);
|
249
|
+
}
|
250
|
+
|
251
|
+
return ULONG2NUM(size); // long at least 32 bits
|
252
|
+
}
|
253
|
+
|
254
|
+
static VALUE Unpacker_read_map_header(VALUE self)
|
255
|
+
{
|
256
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
257
|
+
|
258
|
+
uint32_t size;
|
259
|
+
int r = msgpack_unpacker_read_map_header(uk, &size);
|
260
|
+
if(r < 0) {
|
261
|
+
raise_unpacker_error(uk, r);
|
262
|
+
}
|
263
|
+
|
264
|
+
return ULONG2NUM(size); // long at least 32 bits
|
265
|
+
}
|
266
|
+
|
267
|
+
static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
268
|
+
{
|
269
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
270
|
+
|
271
|
+
StringValue(data);
|
272
|
+
|
273
|
+
msgpack_buffer_append_string_reference(UNPACKER_BUFFER_(uk), data);
|
274
|
+
|
275
|
+
return self;
|
276
|
+
}
|
277
|
+
|
278
|
+
static VALUE Unpacker_each_impl(VALUE self)
|
279
|
+
{
|
280
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
281
|
+
|
282
|
+
while(true) {
|
283
|
+
int r = msgpack_unpacker_read(uk, 0);
|
284
|
+
if(r < 0) {
|
285
|
+
if(r == PRIMITIVE_EOF) {
|
286
|
+
return Qnil;
|
287
|
+
}
|
288
|
+
raise_unpacker_error(uk, r);
|
289
|
+
}
|
290
|
+
VALUE v = msgpack_unpacker_get_last_object(uk);
|
291
|
+
rb_yield(v);
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
|
296
|
+
{
|
297
|
+
UNUSED(args);
|
298
|
+
UNUSED(error);
|
299
|
+
return Qnil;
|
300
|
+
}
|
301
|
+
|
302
|
+
static VALUE Unpacker_each(VALUE self)
|
303
|
+
{
|
304
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
305
|
+
|
306
|
+
#ifdef RETURN_ENUMERATOR
|
307
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
308
|
+
#endif
|
309
|
+
|
310
|
+
if(msgpack_buffer_has_io(UNPACKER_BUFFER_(uk))) {
|
311
|
+
/* rescue EOFError only if io is set */
|
312
|
+
return rb_rescue2(Unpacker_each_impl, self,
|
313
|
+
Unpacker_rescue_EOFError, self,
|
314
|
+
rb_eEOFError, NULL);
|
315
|
+
} else {
|
316
|
+
return Unpacker_each_impl(self);
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
320
|
+
static VALUE Unpacker_feed_each(VALUE self, VALUE data)
|
321
|
+
{
|
322
|
+
#ifdef RETURN_ENUMERATOR
|
323
|
+
{
|
324
|
+
VALUE argv[] = { data };
|
325
|
+
RETURN_ENUMERATOR(self, sizeof(argv) / sizeof(VALUE), argv);
|
326
|
+
}
|
327
|
+
#endif
|
328
|
+
|
329
|
+
Unpacker_feed_reference(self, data);
|
330
|
+
return Unpacker_each(self);
|
331
|
+
}
|
332
|
+
|
333
|
+
static VALUE Unpacker_reset(VALUE self)
|
334
|
+
{
|
335
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
336
|
+
|
337
|
+
_msgpack_unpacker_reset(uk);
|
338
|
+
|
339
|
+
return Qnil;
|
340
|
+
}
|
341
|
+
|
342
|
+
static VALUE Unpacker_registered_types_internal(VALUE self)
|
343
|
+
{
|
344
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
345
|
+
|
346
|
+
VALUE mapping = rb_hash_new();
|
347
|
+
if (uk->ext_registry) {
|
348
|
+
for(int i=0; i < 256; i++) {
|
349
|
+
if(uk->ext_registry->array[i] != Qnil) {
|
350
|
+
rb_hash_aset(mapping, INT2FIX(i - 128), uk->ext_registry->array[i]);
|
351
|
+
}
|
352
|
+
}
|
353
|
+
}
|
354
|
+
|
355
|
+
return mapping;
|
356
|
+
}
|
357
|
+
|
358
|
+
static VALUE Unpacker_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
|
359
|
+
{
|
360
|
+
if (OBJ_FROZEN(self)) {
|
361
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Unpacker");
|
362
|
+
}
|
363
|
+
|
364
|
+
int ext_type = NUM2INT(rb_ext_type);
|
365
|
+
if(ext_type < -128 || ext_type > 127) {
|
366
|
+
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
367
|
+
}
|
368
|
+
|
369
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
370
|
+
msgpack_unpacker_ext_registry_put(self, &uk->ext_registry, ext_module, ext_type, 0, proc);
|
371
|
+
|
372
|
+
return Qnil;
|
373
|
+
}
|
374
|
+
|
375
|
+
static VALUE Unpacker_full_unpack(VALUE self)
|
376
|
+
{
|
377
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
378
|
+
|
379
|
+
int r = msgpack_unpacker_read(uk, 0);
|
380
|
+
if(r < 0) {
|
381
|
+
raise_unpacker_error(uk, r);
|
382
|
+
}
|
383
|
+
|
384
|
+
/* raise if extra bytes follow */
|
385
|
+
size_t extra = msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk));
|
386
|
+
if(extra > 0) {
|
387
|
+
rb_raise(eMalformedFormatError, "%zd extra bytes after the deserialized object", extra);
|
388
|
+
}
|
389
|
+
|
390
|
+
return msgpack_unpacker_get_last_object(uk);
|
391
|
+
}
|
392
|
+
|
393
|
+
VALUE MessagePack_Unpacker_new(int argc, VALUE* argv)
|
394
|
+
{
|
395
|
+
VALUE self = MessagePack_Unpacker_alloc(cMessagePack_Unpacker);
|
396
|
+
MessagePack_Unpacker_initialize(argc, argv, self);
|
397
|
+
return self;
|
398
|
+
}
|
399
|
+
|
400
|
+
void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
401
|
+
{
|
402
|
+
msgpack_unpacker_static_init();
|
403
|
+
|
404
|
+
mTypeError = rb_define_module_under(mMessagePack, "TypeError");
|
405
|
+
|
406
|
+
cMessagePack_Unpacker = rb_define_class_under(mMessagePack, "Unpacker", rb_cObject);
|
407
|
+
|
408
|
+
eUnpackError = rb_define_class_under(mMessagePack, "UnpackError", rb_eStandardError);
|
409
|
+
|
410
|
+
eMalformedFormatError = rb_define_class_under(mMessagePack, "MalformedFormatError", eUnpackError);
|
411
|
+
|
412
|
+
eStackError = rb_define_class_under(mMessagePack, "StackError", eUnpackError);
|
413
|
+
|
414
|
+
eUnexpectedTypeError = rb_define_class_under(mMessagePack, "UnexpectedTypeError", eUnpackError);
|
415
|
+
rb_include_module(eUnexpectedTypeError, mTypeError);
|
416
|
+
|
417
|
+
eUnknownExtTypeError = rb_define_class_under(mMessagePack, "UnknownExtTypeError", eUnpackError);
|
418
|
+
|
419
|
+
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
|
420
|
+
sym_key_cache = ID2SYM(rb_intern("key_cache"));
|
421
|
+
sym_freeze = ID2SYM(rb_intern("freeze"));
|
422
|
+
sym_allow_unknown_ext = ID2SYM(rb_intern("allow_unknown_ext"));
|
423
|
+
|
424
|
+
rb_define_alloc_func(cMessagePack_Unpacker, MessagePack_Unpacker_alloc);
|
425
|
+
|
426
|
+
rb_define_method(cMessagePack_Unpacker, "initialize", MessagePack_Unpacker_initialize, -1);
|
427
|
+
rb_define_method(cMessagePack_Unpacker, "symbolize_keys?", Unpacker_symbolized_keys_p, 0);
|
428
|
+
rb_define_method(cMessagePack_Unpacker, "freeze?", Unpacker_freeze_p, 0);
|
429
|
+
rb_define_method(cMessagePack_Unpacker, "allow_unknown_ext?", Unpacker_allow_unknown_ext_p, 0);
|
430
|
+
rb_define_method(cMessagePack_Unpacker, "buffer", Unpacker_buffer, 0);
|
431
|
+
rb_define_method(cMessagePack_Unpacker, "read", Unpacker_read, 0);
|
432
|
+
rb_define_alias(cMessagePack_Unpacker, "unpack", "read");
|
433
|
+
rb_define_method(cMessagePack_Unpacker, "skip", Unpacker_skip, 0);
|
434
|
+
rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
|
435
|
+
rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
|
436
|
+
rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
|
437
|
+
rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed_reference, 1);
|
438
|
+
rb_define_alias(cMessagePack_Unpacker, "feed_reference", "feed");
|
439
|
+
rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
|
440
|
+
rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
|
441
|
+
rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
|
442
|
+
|
443
|
+
rb_define_private_method(cMessagePack_Unpacker, "registered_types_internal", Unpacker_registered_types_internal, 0);
|
444
|
+
rb_define_private_method(cMessagePack_Unpacker, "register_type_internal", Unpacker_register_type_internal, 3);
|
445
|
+
|
446
|
+
rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
|
447
|
+
}
|
@@ -0,0 +1,43 @@
|
|
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_UNPACKER_CLASS_H__
|
19
|
+
#define MSGPACK_RUBY_UNPACKER_CLASS_H__
|
20
|
+
|
21
|
+
#include "unpacker.h"
|
22
|
+
|
23
|
+
extern const rb_data_type_t unpacker_data_type;
|
24
|
+
|
25
|
+
static inline msgpack_unpacker_t *MessagePack_Unpacker_get(VALUE object) {
|
26
|
+
msgpack_unpacker_t *unpacker;
|
27
|
+
TypedData_Get_Struct(object, msgpack_unpacker_t, &unpacker_data_type, unpacker);
|
28
|
+
if (!unpacker) {
|
29
|
+
rb_raise(rb_eArgError, "Uninitialized Unpacker object");
|
30
|
+
}
|
31
|
+
return unpacker;
|
32
|
+
}
|
33
|
+
|
34
|
+
extern VALUE cMessagePack_Unpacker;
|
35
|
+
|
36
|
+
void MessagePack_Unpacker_module_init(VALUE mMessagePack);
|
37
|
+
|
38
|
+
VALUE MessagePack_Unpacker_alloc(VALUE klass);
|
39
|
+
|
40
|
+
VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self);
|
41
|
+
|
42
|
+
#endif
|
43
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
/*
|
2
|
+
* MessagePack for Ruby
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008-2015 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 "unpacker_ext_registry.h"
|
20
|
+
|
21
|
+
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
|
22
|
+
{
|
23
|
+
if (ukrg) {
|
24
|
+
for(int i=0; i < 256; i++) {
|
25
|
+
if (ukrg->array[i] != Qnil) {
|
26
|
+
rb_gc_mark(ukrg->array[i]);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
msgpack_unpacker_ext_registry_t* msgpack_unpacker_ext_registry_cow(msgpack_unpacker_ext_registry_t* src)
|
33
|
+
{
|
34
|
+
msgpack_unpacker_ext_registry_t* dst;
|
35
|
+
if (src) {
|
36
|
+
if (src->borrow_count) {
|
37
|
+
dst = ALLOC(msgpack_unpacker_ext_registry_t);
|
38
|
+
dst->borrow_count = 0;
|
39
|
+
MEMCPY(dst->array, src->array, VALUE, 256);
|
40
|
+
msgpack_unpacker_ext_registry_release(src);
|
41
|
+
return dst;
|
42
|
+
} else {
|
43
|
+
return src;
|
44
|
+
}
|
45
|
+
} else {
|
46
|
+
dst = ALLOC(msgpack_unpacker_ext_registry_t);
|
47
|
+
dst->borrow_count = 0;
|
48
|
+
for(int i=0; i < 256; i++) {
|
49
|
+
dst->array[i] = Qnil;
|
50
|
+
}
|
51
|
+
return dst;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg)
|
56
|
+
{
|
57
|
+
if (ukrg) {
|
58
|
+
if (ukrg->borrow_count) {
|
59
|
+
ukrg->borrow_count--;
|
60
|
+
} else {
|
61
|
+
xfree(ukrg);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
|
67
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc)
|
68
|
+
{
|
69
|
+
msgpack_unpacker_ext_registry_t* ext_registry = msgpack_unpacker_ext_registry_cow(*ukrg);
|
70
|
+
|
71
|
+
VALUE entry = rb_ary_new3(3, ext_module, proc, INT2FIX(flags));
|
72
|
+
RB_OBJ_WRITE(owner, &ext_registry->array[ext_type + 128], entry);
|
73
|
+
*ukrg = ext_registry;
|
74
|
+
}
|