gitlab-cbor 1.0.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/.gitignore +25 -0
- data/.gitlab-ci.yml +44 -0
- data/.travis.yml +24 -0
- data/CHANGELOG.md +30 -0
- data/ChangeLog +106 -0
- data/Gemfile +11 -0
- data/README.rdoc +191 -0
- data/Rakefile +97 -0
- data/ci/test.rb +31 -0
- data/doclib/cbor/buffer.rb +193 -0
- data/doclib/cbor/core_ext.rb +133 -0
- data/doclib/cbor/error.rb +14 -0
- data/doclib/cbor/packer.rb +133 -0
- data/doclib/cbor/simple.rb +15 -0
- data/doclib/cbor/tagged.rb +16 -0
- data/doclib/cbor/unpacker.rb +138 -0
- data/doclib/cbor.rb +80 -0
- data/ext/cbor/buffer.c +693 -0
- data/ext/cbor/buffer.h +484 -0
- data/ext/cbor/buffer_class.c +561 -0
- data/ext/cbor/buffer_class.h +41 -0
- data/ext/cbor/cbor.h +69 -0
- data/ext/cbor/compat.h +147 -0
- data/ext/cbor/core_ext.c +199 -0
- data/ext/cbor/core_ext.h +35 -0
- data/ext/cbor/extconf.rb +29 -0
- data/ext/cbor/packer.c +169 -0
- data/ext/cbor/packer.h +370 -0
- data/ext/cbor/packer_class.c +345 -0
- data/ext/cbor/packer_class.h +40 -0
- data/ext/cbor/rbinit.c +57 -0
- data/ext/cbor/renamer.h +56 -0
- data/ext/cbor/rmem.c +103 -0
- data/ext/cbor/rmem.h +118 -0
- data/ext/cbor/sysdep.h +139 -0
- data/ext/cbor/sysdep_endian.h +59 -0
- data/ext/cbor/sysdep_types.h +55 -0
- data/ext/cbor/unpacker.c +787 -0
- data/ext/cbor/unpacker.h +135 -0
- data/ext/cbor/unpacker_class.c +483 -0
- data/ext/cbor/unpacker_class.h +39 -0
- data/gitlab-cbor.gemspec +27 -0
- data/lib/cbor/version.rb +3 -0
- data/lib/cbor.rb +6 -0
- data/spec/buffer_io_spec.rb +260 -0
- data/spec/buffer_spec.rb +576 -0
- data/spec/cases.cbor +0 -0
- data/spec/cases.cbor_stream +0 -0
- data/spec/cases.json +1 -0
- data/spec/cases.msg +0 -0
- data/spec/cases_compact.msg +0 -0
- data/spec/cases_spec.rb +39 -0
- data/spec/format_spec.rb +603 -0
- data/spec/packer_spec.rb +127 -0
- data/spec/random_compat.rb +24 -0
- data/spec/spec_helper.rb +68 -0
- data/spec/unpacker_spec.rb +260 -0
- metadata +189 -0
data/ext/cbor/unpacker.h
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* CBOR for Ruby
|
|
3
|
+
*
|
|
4
|
+
* Copyright (C) 2013 Carsten Bormann
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License").
|
|
7
|
+
*
|
|
8
|
+
* Based on:
|
|
9
|
+
***********/
|
|
10
|
+
/*
|
|
11
|
+
* MessagePack for Ruby
|
|
12
|
+
*
|
|
13
|
+
* Copyright (C) 2008-2013 Sadayuki Furuhashi
|
|
14
|
+
*
|
|
15
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
16
|
+
* you may not use this file except in compliance with the License.
|
|
17
|
+
* You may obtain a copy of the License at
|
|
18
|
+
*
|
|
19
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
20
|
+
*
|
|
21
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
22
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
23
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
24
|
+
* See the License for the specific language governing permissions and
|
|
25
|
+
* limitations under the License.
|
|
26
|
+
*/
|
|
27
|
+
#ifndef MSGPACK_RUBY_UNPACKER_H__
|
|
28
|
+
#define MSGPACK_RUBY_UNPACKER_H__
|
|
29
|
+
|
|
30
|
+
#include "buffer.h"
|
|
31
|
+
|
|
32
|
+
#ifndef MSGPACK_UNPACKER_STACK_CAPACITY
|
|
33
|
+
#define MSGPACK_UNPACKER_STACK_CAPACITY 128
|
|
34
|
+
#endif
|
|
35
|
+
|
|
36
|
+
struct msgpack_unpacker_t;
|
|
37
|
+
typedef struct msgpack_unpacker_t msgpack_unpacker_t;
|
|
38
|
+
|
|
39
|
+
enum stack_type_t {
|
|
40
|
+
STACK_TYPE_ARRAY,
|
|
41
|
+
STACK_TYPE_MAP_KEY,
|
|
42
|
+
STACK_TYPE_MAP_VALUE,
|
|
43
|
+
STACK_TYPE_TAG, /* > TAG = indef */
|
|
44
|
+
STACK_TYPE_MAP_VALUE_INDEF, /* Cannot BREAK up to here */
|
|
45
|
+
STACK_TYPE_MAP_KEY_INDEF,
|
|
46
|
+
STACK_TYPE_ARRAY_INDEF,
|
|
47
|
+
STACK_TYPE_STRING_INDEF,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
typedef struct {
|
|
51
|
+
size_t count;
|
|
52
|
+
enum stack_type_t type;
|
|
53
|
+
VALUE object;
|
|
54
|
+
VALUE key;
|
|
55
|
+
uint64_t tag; /* could be union... */
|
|
56
|
+
} msgpack_unpacker_stack_t;
|
|
57
|
+
|
|
58
|
+
#define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
|
|
59
|
+
|
|
60
|
+
struct msgpack_unpacker_t {
|
|
61
|
+
msgpack_buffer_t buffer;
|
|
62
|
+
|
|
63
|
+
unsigned int head_byte;
|
|
64
|
+
|
|
65
|
+
msgpack_unpacker_stack_t* stack;
|
|
66
|
+
size_t stack_depth;
|
|
67
|
+
size_t stack_capacity;
|
|
68
|
+
|
|
69
|
+
VALUE last_object;
|
|
70
|
+
|
|
71
|
+
VALUE reading_raw;
|
|
72
|
+
size_t reading_raw_remaining;
|
|
73
|
+
int textflag;
|
|
74
|
+
|
|
75
|
+
bool keys_as_symbols; /* Experimental */
|
|
76
|
+
bool reconstruct_regexp; /* reconstruct tag 35 (Regexp); opt-in */
|
|
77
|
+
bool reconstruct_uri; /* reconstruct tag 32 (URI); opt-in */
|
|
78
|
+
|
|
79
|
+
VALUE buffer_ref;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
#define UNPACKER_BUFFER_(uk) (&(uk)->buffer)
|
|
83
|
+
|
|
84
|
+
enum msgpack_unpacker_object_type {
|
|
85
|
+
TYPE_NIL = 0,
|
|
86
|
+
TYPE_BOOLEAN,
|
|
87
|
+
TYPE_INTEGER,
|
|
88
|
+
TYPE_FLOAT,
|
|
89
|
+
TYPE_RAW,
|
|
90
|
+
TYPE_ARRAY,
|
|
91
|
+
TYPE_MAP,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
void msgpack_unpacker_static_init();
|
|
95
|
+
|
|
96
|
+
void msgpack_unpacker_static_destroy();
|
|
97
|
+
|
|
98
|
+
void msgpack_unpacker_init(msgpack_unpacker_t* uk);
|
|
99
|
+
|
|
100
|
+
void msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
|
|
101
|
+
|
|
102
|
+
void msgpack_unpacker_mark(msgpack_unpacker_t* uk);
|
|
103
|
+
|
|
104
|
+
void msgpack_unpacker_reset(msgpack_unpacker_t* uk);
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
/* error codes */
|
|
108
|
+
#define PRIMITIVE_CONTAINER_START 1
|
|
109
|
+
#define PRIMITIVE_OBJECT_COMPLETE 0
|
|
110
|
+
#define PRIMITIVE_EOF -1
|
|
111
|
+
#define PRIMITIVE_INVALID_BYTE -2
|
|
112
|
+
#define PRIMITIVE_STACK_TOO_DEEP -3
|
|
113
|
+
#define PRIMITIVE_UNEXPECTED_TYPE -4
|
|
114
|
+
#define PRIMITIVE_BREAK 2
|
|
115
|
+
|
|
116
|
+
int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth);
|
|
117
|
+
|
|
118
|
+
int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth);
|
|
119
|
+
|
|
120
|
+
static inline VALUE msgpack_unpacker_get_last_object(msgpack_unpacker_t* uk)
|
|
121
|
+
{
|
|
122
|
+
return uk->last_object;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
int msgpack_unpacker_peek_next_object_type(msgpack_unpacker_t* uk);
|
|
127
|
+
|
|
128
|
+
int msgpack_unpacker_skip_nil(msgpack_unpacker_t* uk);
|
|
129
|
+
|
|
130
|
+
int msgpack_unpacker_read_array_header(msgpack_unpacker_t* uk, uint64_t* result_size);
|
|
131
|
+
|
|
132
|
+
int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint64_t* result_size);
|
|
133
|
+
|
|
134
|
+
#endif
|
|
135
|
+
|
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* CBOR for Ruby
|
|
3
|
+
*
|
|
4
|
+
* Copyright (C) 2013 Carsten Bormann
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License").
|
|
7
|
+
*
|
|
8
|
+
* Based on:
|
|
9
|
+
***********/
|
|
10
|
+
/*
|
|
11
|
+
* MessagePack for Ruby
|
|
12
|
+
*
|
|
13
|
+
* Copyright (C) 2008-2013 Sadayuki Furuhashi
|
|
14
|
+
*
|
|
15
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
16
|
+
* you may not use this file except in compliance with the License.
|
|
17
|
+
* You may obtain a copy of the License at
|
|
18
|
+
*
|
|
19
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
20
|
+
*
|
|
21
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
22
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
23
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
24
|
+
* See the License for the specific language governing permissions and
|
|
25
|
+
* limitations under the License.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
#include "unpacker.h"
|
|
29
|
+
#include "unpacker_class.h"
|
|
30
|
+
#include "buffer_class.h"
|
|
31
|
+
|
|
32
|
+
VALUE cMessagePack_Unpacker;
|
|
33
|
+
|
|
34
|
+
//static VALUE s_unpacker_value;
|
|
35
|
+
//static msgpack_unpacker_t* s_unpacker;
|
|
36
|
+
|
|
37
|
+
static VALUE eUnpackError;
|
|
38
|
+
static VALUE eMalformedFormatError;
|
|
39
|
+
static VALUE eStackError;
|
|
40
|
+
static VALUE eTypeError;
|
|
41
|
+
|
|
42
|
+
static msgpack_unpacker_t* Unpacker_get(VALUE self);
|
|
43
|
+
|
|
44
|
+
#define UNPACKER(from, name) \
|
|
45
|
+
msgpack_unpacker_t *name = Unpacker_get(from); \
|
|
46
|
+
if(name == NULL) { \
|
|
47
|
+
rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static void Unpacker_mark(void* data)
|
|
51
|
+
{
|
|
52
|
+
msgpack_unpacker_t* uk = data;
|
|
53
|
+
msgpack_unpacker_mark(uk);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static void Unpacker_free(void* data)
|
|
57
|
+
{
|
|
58
|
+
msgpack_unpacker_t* uk = data;
|
|
59
|
+
if(uk == NULL) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
msgpack_unpacker_destroy(uk);
|
|
63
|
+
xfree(uk);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
#ifdef TypedData_Make_Struct
|
|
67
|
+
static size_t Unpacker_memsize(const void* data)
|
|
68
|
+
{
|
|
69
|
+
return data == NULL ? 0 : sizeof(msgpack_unpacker_t);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static const rb_data_type_t unpacker_data_type = {
|
|
73
|
+
"CBOR::Unpacker",
|
|
74
|
+
{Unpacker_mark, Unpacker_free, Unpacker_memsize,},
|
|
75
|
+
NULL, NULL, 0
|
|
76
|
+
};
|
|
77
|
+
#endif
|
|
78
|
+
|
|
79
|
+
static msgpack_unpacker_t* Unpacker_get(VALUE self)
|
|
80
|
+
{
|
|
81
|
+
msgpack_unpacker_t* uk = NULL;
|
|
82
|
+
#ifdef TypedData_Make_Struct
|
|
83
|
+
TypedData_Get_Struct(self, msgpack_unpacker_t, &unpacker_data_type, uk);
|
|
84
|
+
#else
|
|
85
|
+
Data_Get_Struct(self, msgpack_unpacker_t, uk);
|
|
86
|
+
#endif
|
|
87
|
+
return uk;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static VALUE Unpacker_alloc(VALUE klass)
|
|
91
|
+
{
|
|
92
|
+
msgpack_unpacker_t* uk;
|
|
93
|
+
VALUE self;
|
|
94
|
+
#ifdef TypedData_Make_Struct
|
|
95
|
+
self = TypedData_Make_Struct(klass, msgpack_unpacker_t, &unpacker_data_type, uk);
|
|
96
|
+
#else
|
|
97
|
+
self = Data_Make_Struct(klass, msgpack_unpacker_t, Unpacker_mark, Unpacker_free, uk);
|
|
98
|
+
#endif
|
|
99
|
+
msgpack_unpacker_init(uk);
|
|
100
|
+
|
|
101
|
+
uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
|
|
102
|
+
|
|
103
|
+
return self;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* reconstruct_from_tags: a list of CBOR tag numbers whose decoded value should be
|
|
107
|
+
reconstructed into a live Ruby object. Only the object-constructing tags
|
|
108
|
+
are gated (35 -> Regexp, 32 -> URI); anything else decodes to CBOR::Tagged.
|
|
109
|
+
Absent or non-Array means "none", the safe default. */
|
|
110
|
+
static void set_reconstruct_from_tags(msgpack_unpacker_t* uk, VALUE options)
|
|
111
|
+
{
|
|
112
|
+
VALUE tags;
|
|
113
|
+
if (!RB_TYPE_P(options, T_HASH))
|
|
114
|
+
return;
|
|
115
|
+
tags = rb_hash_aref(options, ID2SYM(rb_intern("reconstruct_from_tags")));
|
|
116
|
+
if (RB_TYPE_P(tags, T_ARRAY)) {
|
|
117
|
+
ID include_p = rb_intern("include?");
|
|
118
|
+
uk->reconstruct_regexp = RTEST(rb_funcall(tags, include_p, 1, INT2FIX(TAG_RE)));
|
|
119
|
+
uk->reconstruct_uri = RTEST(rb_funcall(tags, include_p, 1, INT2FIX(TAG_URI)));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static VALUE Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
124
|
+
{
|
|
125
|
+
VALUE io = Qnil;
|
|
126
|
+
VALUE options = Qnil;
|
|
127
|
+
|
|
128
|
+
if(argc == 0 || (argc == 1 && argv[0] == Qnil)) {
|
|
129
|
+
/* Qnil */
|
|
130
|
+
|
|
131
|
+
} else if(argc == 1) {
|
|
132
|
+
VALUE v = argv[0];
|
|
133
|
+
if(rb_type(v) == T_HASH) {
|
|
134
|
+
options = v;
|
|
135
|
+
} else {
|
|
136
|
+
io = v;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
} else if(argc == 2) {
|
|
140
|
+
io = argv[0];
|
|
141
|
+
options = argv[1];
|
|
142
|
+
if(rb_type(options) != T_HASH) {
|
|
143
|
+
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
} else {
|
|
147
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
UNPACKER(self, uk);
|
|
151
|
+
if(io != Qnil || options != Qnil) {
|
|
152
|
+
MessagePack_Buffer_initialize(UNPACKER_BUFFER_(uk), io, options);
|
|
153
|
+
if (options != Qnil) {
|
|
154
|
+
VALUE v;
|
|
155
|
+
v = rb_hash_aref(options, ID2SYM(rb_intern("symbolize_keys")));
|
|
156
|
+
uk->keys_as_symbols = RTEST(v);
|
|
157
|
+
set_reconstruct_from_tags(uk, options);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// TODO options
|
|
162
|
+
|
|
163
|
+
return self;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
static void raise_unpacker_error(int r)
|
|
167
|
+
{
|
|
168
|
+
switch(r) {
|
|
169
|
+
case PRIMITIVE_EOF:
|
|
170
|
+
rb_raise(rb_eEOFError, "end of buffer reached");
|
|
171
|
+
case PRIMITIVE_INVALID_BYTE:
|
|
172
|
+
rb_raise(eMalformedFormatError, "invalid byte");
|
|
173
|
+
case PRIMITIVE_STACK_TOO_DEEP:
|
|
174
|
+
rb_raise(eStackError, "stack level too deep");
|
|
175
|
+
case PRIMITIVE_UNEXPECTED_TYPE:
|
|
176
|
+
rb_raise(eTypeError, "unexpected type");
|
|
177
|
+
default:
|
|
178
|
+
rb_raise(eUnpackError, "logically unknown error %d", r);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
static VALUE Unpacker_buffer(VALUE self)
|
|
183
|
+
{
|
|
184
|
+
UNPACKER(self, uk);
|
|
185
|
+
return uk->buffer_ref;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
static VALUE Unpacker_read(VALUE self)
|
|
189
|
+
{
|
|
190
|
+
UNPACKER(self, uk);
|
|
191
|
+
|
|
192
|
+
int r = msgpack_unpacker_read(uk, 0);
|
|
193
|
+
if(r < 0) {
|
|
194
|
+
raise_unpacker_error(r);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return msgpack_unpacker_get_last_object(uk);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
static VALUE Unpacker_skip(VALUE self)
|
|
201
|
+
{
|
|
202
|
+
UNPACKER(self, uk);
|
|
203
|
+
|
|
204
|
+
int r = msgpack_unpacker_skip(uk, 0);
|
|
205
|
+
if(r < 0) {
|
|
206
|
+
raise_unpacker_error(r);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return Qnil;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
static VALUE Unpacker_skip_nil(VALUE self)
|
|
213
|
+
{
|
|
214
|
+
UNPACKER(self, uk);
|
|
215
|
+
|
|
216
|
+
int r = msgpack_unpacker_skip_nil(uk);
|
|
217
|
+
if(r < 0) {
|
|
218
|
+
raise_unpacker_error(r);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if(r) {
|
|
222
|
+
return Qtrue;
|
|
223
|
+
}
|
|
224
|
+
return Qfalse;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
static VALUE Unpacker_read_array_header(VALUE self)
|
|
228
|
+
{
|
|
229
|
+
UNPACKER(self, uk);
|
|
230
|
+
|
|
231
|
+
uint64_t size;
|
|
232
|
+
int r = msgpack_unpacker_read_array_header(uk, &size);
|
|
233
|
+
if(r < 0) {
|
|
234
|
+
raise_unpacker_error(r);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return rb_ull2inum(size);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
static VALUE Unpacker_read_map_header(VALUE self)
|
|
241
|
+
{
|
|
242
|
+
UNPACKER(self, uk);
|
|
243
|
+
|
|
244
|
+
uint64_t size;
|
|
245
|
+
int r = msgpack_unpacker_read_map_header(uk, &size);
|
|
246
|
+
if(r < 0) {
|
|
247
|
+
raise_unpacker_error((int)r);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return rb_ull2inum(size);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
#if 0
|
|
254
|
+
static VALUE Unpacker_peek_next_type(VALUE self)
|
|
255
|
+
{
|
|
256
|
+
UNPACKER(self, uk);
|
|
257
|
+
|
|
258
|
+
int r = msgpack_unpacker_peek_next_object_type(uk);
|
|
259
|
+
if(r < 0) {
|
|
260
|
+
raise_unpacker_error(r);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
switch((enum msgpack_unpacker_object_type) r) {
|
|
264
|
+
case TYPE_NIL:
|
|
265
|
+
return rb_intern("nil");
|
|
266
|
+
case TYPE_BOOLEAN:
|
|
267
|
+
return rb_intern("boolean");
|
|
268
|
+
case TYPE_INTEGER:
|
|
269
|
+
return rb_intern("integer");
|
|
270
|
+
case TYPE_FLOAT:
|
|
271
|
+
return rb_intern("float");
|
|
272
|
+
case TYPE_RAW:
|
|
273
|
+
return rb_intern("raw");
|
|
274
|
+
case TYPE_ARRAY:
|
|
275
|
+
return rb_intern("array");
|
|
276
|
+
case TYPE_MAP:
|
|
277
|
+
return rb_intern("map");
|
|
278
|
+
default:
|
|
279
|
+
rb_raise(eUnpackError, "logically unknown type %d", r);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
#endif
|
|
283
|
+
|
|
284
|
+
static VALUE Unpacker_feed(VALUE self, VALUE data)
|
|
285
|
+
{
|
|
286
|
+
UNPACKER(self, uk);
|
|
287
|
+
|
|
288
|
+
StringValue(data);
|
|
289
|
+
|
|
290
|
+
msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data);
|
|
291
|
+
|
|
292
|
+
return self;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
static VALUE Unpacker_each_impl(VALUE self)
|
|
296
|
+
{
|
|
297
|
+
UNPACKER(self, uk);
|
|
298
|
+
|
|
299
|
+
while(true) {
|
|
300
|
+
int r = msgpack_unpacker_read(uk, 0);
|
|
301
|
+
if(r < 0) {
|
|
302
|
+
if(r == PRIMITIVE_EOF) {
|
|
303
|
+
return Qnil;
|
|
304
|
+
}
|
|
305
|
+
raise_unpacker_error(r);
|
|
306
|
+
}
|
|
307
|
+
VALUE v = msgpack_unpacker_get_last_object(uk);
|
|
308
|
+
#ifdef JRUBY
|
|
309
|
+
/* TODO JRuby's rb_yield behaves differently from Ruby 1.9.3 or Rubinius. */
|
|
310
|
+
if(rb_type(v) == T_ARRAY) {
|
|
311
|
+
v = rb_ary_new3(1, v);
|
|
312
|
+
}
|
|
313
|
+
#endif
|
|
314
|
+
rb_yield(v);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
static VALUE Unpacker_rescue_EOFError(VALUE self, VALUE error)
|
|
319
|
+
{
|
|
320
|
+
UNUSED(self);
|
|
321
|
+
UNUSED(error);
|
|
322
|
+
return Qnil;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
static VALUE Unpacker_each(VALUE self)
|
|
326
|
+
{
|
|
327
|
+
UNPACKER(self, uk);
|
|
328
|
+
|
|
329
|
+
#ifdef RETURN_ENUMERATOR
|
|
330
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
|
331
|
+
#endif
|
|
332
|
+
|
|
333
|
+
if(msgpack_buffer_has_io(UNPACKER_BUFFER_(uk))) {
|
|
334
|
+
/* rescue EOFError only if io is set */
|
|
335
|
+
return rb_rescue2(Unpacker_each_impl, self,
|
|
336
|
+
Unpacker_rescue_EOFError, self,
|
|
337
|
+
rb_eEOFError, NULL);
|
|
338
|
+
} else {
|
|
339
|
+
return Unpacker_each_impl(self);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
static VALUE Unpacker_feed_each(VALUE self, VALUE data)
|
|
344
|
+
{
|
|
345
|
+
// TODO optimize
|
|
346
|
+
Unpacker_feed(self, data);
|
|
347
|
+
return Unpacker_each(self);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
static VALUE Unpacker_reset(VALUE self)
|
|
351
|
+
{
|
|
352
|
+
UNPACKER(self, uk);
|
|
353
|
+
|
|
354
|
+
msgpack_unpacker_reset(uk);
|
|
355
|
+
|
|
356
|
+
return Qnil;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
VALUE MessagePack_unpack(int argc, VALUE* argv)
|
|
360
|
+
{
|
|
361
|
+
VALUE src;
|
|
362
|
+
VALUE options = Qnil;
|
|
363
|
+
bool keys_as_symbols = false;
|
|
364
|
+
|
|
365
|
+
switch(argc) {
|
|
366
|
+
case 2:
|
|
367
|
+
options = argv[1]; /* Experimental! */
|
|
368
|
+
if (options == ID2SYM(rb_intern("keys_as_symbols"))) /* backward compat */
|
|
369
|
+
keys_as_symbols = true;
|
|
370
|
+
else if (options != Qnil) {
|
|
371
|
+
VALUE v;
|
|
372
|
+
if (!RB_TYPE_P(options, T_HASH)) {
|
|
373
|
+
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
|
374
|
+
}
|
|
375
|
+
v = rb_hash_aref(options, ID2SYM(rb_intern("symbolize_keys")));
|
|
376
|
+
keys_as_symbols = RTEST(v);
|
|
377
|
+
}
|
|
378
|
+
/* fall through */
|
|
379
|
+
case 1:
|
|
380
|
+
src = argv[0];
|
|
381
|
+
break;
|
|
382
|
+
default:
|
|
383
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
VALUE io = Qnil;
|
|
387
|
+
if(rb_type(src) != T_STRING) {
|
|
388
|
+
io = src;
|
|
389
|
+
src = Qnil;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
VALUE self = Unpacker_alloc(cMessagePack_Unpacker);
|
|
393
|
+
UNPACKER(self, uk);
|
|
394
|
+
//msgpack_unpacker_reset(s_unpacker);
|
|
395
|
+
//msgpack_buffer_reset_io(UNPACKER_BUFFER_(s_unpacker));
|
|
396
|
+
|
|
397
|
+
/* prefer reference than copying */
|
|
398
|
+
msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(uk), 0);
|
|
399
|
+
|
|
400
|
+
uk->keys_as_symbols = keys_as_symbols;
|
|
401
|
+
set_reconstruct_from_tags(uk, options);
|
|
402
|
+
|
|
403
|
+
if(io != Qnil) {
|
|
404
|
+
MessagePack_Buffer_initialize(UNPACKER_BUFFER_(uk), io, Qnil);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if(src != Qnil) {
|
|
408
|
+
/* prefer reference than copying; see MessagePack_Unpacker_module_init */
|
|
409
|
+
msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), src);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
int r = msgpack_unpacker_read(uk, 0);
|
|
413
|
+
if(r < 0) {
|
|
414
|
+
raise_unpacker_error(r);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/* raise if extra bytes follow */
|
|
418
|
+
if(msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk)) > 0) {
|
|
419
|
+
rb_raise(eMalformedFormatError, "extra bytes follow after a deserialized object");
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
#ifdef RB_GC_GUARD
|
|
423
|
+
/* This prevents compilers from optimizing out the `self` variable
|
|
424
|
+
* from stack. Otherwise GC free()s it. */
|
|
425
|
+
RB_GC_GUARD(self);
|
|
426
|
+
#endif
|
|
427
|
+
|
|
428
|
+
return msgpack_unpacker_get_last_object(uk);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
static VALUE MessagePack_load_module_method(int argc, VALUE* argv, VALUE mod)
|
|
432
|
+
{
|
|
433
|
+
UNUSED(mod);
|
|
434
|
+
return MessagePack_unpack(argc, argv);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
static VALUE MessagePack_unpack_module_method(int argc, VALUE* argv, VALUE mod)
|
|
438
|
+
{
|
|
439
|
+
UNUSED(mod);
|
|
440
|
+
return MessagePack_unpack(argc, argv);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
444
|
+
{
|
|
445
|
+
msgpack_unpacker_static_init();
|
|
446
|
+
|
|
447
|
+
cMessagePack_Unpacker = rb_define_class_under(mMessagePack, "Unpacker", rb_cObject);
|
|
448
|
+
|
|
449
|
+
eUnpackError = rb_define_class_under(mMessagePack, "UnpackError", rb_eStandardError);
|
|
450
|
+
|
|
451
|
+
eMalformedFormatError = rb_define_class_under(mMessagePack, "MalformedFormatError", eUnpackError);
|
|
452
|
+
|
|
453
|
+
eStackError = rb_define_class_under(mMessagePack, "StackError", eUnpackError);
|
|
454
|
+
|
|
455
|
+
eTypeError = rb_define_class_under(mMessagePack, "TypeError", rb_eStandardError);
|
|
456
|
+
|
|
457
|
+
rb_define_alloc_func(cMessagePack_Unpacker, Unpacker_alloc);
|
|
458
|
+
|
|
459
|
+
rb_define_method(cMessagePack_Unpacker, "initialize", Unpacker_initialize, -1);
|
|
460
|
+
rb_define_method(cMessagePack_Unpacker, "buffer", Unpacker_buffer, 0);
|
|
461
|
+
rb_define_method(cMessagePack_Unpacker, "read", Unpacker_read, 0);
|
|
462
|
+
rb_define_alias(cMessagePack_Unpacker, "unpack", "read");
|
|
463
|
+
rb_define_method(cMessagePack_Unpacker, "skip", Unpacker_skip, 0);
|
|
464
|
+
rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
|
|
465
|
+
rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
|
|
466
|
+
rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
|
|
467
|
+
//rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0); // TODO
|
|
468
|
+
rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
|
|
469
|
+
rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
|
|
470
|
+
rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
|
|
471
|
+
rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
|
|
472
|
+
|
|
473
|
+
//s_unpacker_value = Unpacker_alloc(cMessagePack_Unpacker);
|
|
474
|
+
//rb_gc_register_address(&s_unpacker_value);
|
|
475
|
+
//Data_Get_Struct(s_unpacker_value, msgpack_unpacker_t, s_unpacker);
|
|
476
|
+
/* prefer reference than copying */
|
|
477
|
+
//msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(s_unpacker), 0);
|
|
478
|
+
|
|
479
|
+
/* MessagePack.unpack(x) */
|
|
480
|
+
rb_define_module_function(mMessagePack, "load", MessagePack_load_module_method, -1);
|
|
481
|
+
rb_define_module_function(mMessagePack, "unpack", MessagePack_unpack_module_method, -1);
|
|
482
|
+
rb_define_module_function(mMessagePack, "decode", MessagePack_unpack_module_method, -1);
|
|
483
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* CBOR for Ruby
|
|
3
|
+
*
|
|
4
|
+
* Copyright (C) 2013 Carsten Bormann
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License").
|
|
7
|
+
*
|
|
8
|
+
* Based on:
|
|
9
|
+
***********/
|
|
10
|
+
/*
|
|
11
|
+
* MessagePack for Ruby
|
|
12
|
+
*
|
|
13
|
+
* Copyright (C) 2008-2013 Sadayuki Furuhashi
|
|
14
|
+
*
|
|
15
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
16
|
+
* you may not use this file except in compliance with the License.
|
|
17
|
+
* You may obtain a copy of the License at
|
|
18
|
+
*
|
|
19
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
20
|
+
*
|
|
21
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
22
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
23
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
24
|
+
* See the License for the specific language governing permissions and
|
|
25
|
+
* limitations under the License.
|
|
26
|
+
*/
|
|
27
|
+
#ifndef MSGPACK_RUBY_UNPACKER_CLASS_H__
|
|
28
|
+
#define MSGPACK_RUBY_UNPACKER_CLASS_H__
|
|
29
|
+
|
|
30
|
+
#include "unpacker.h"
|
|
31
|
+
|
|
32
|
+
extern VALUE cMessagePack_Unpacker;
|
|
33
|
+
|
|
34
|
+
void MessagePack_Unpacker_module_init(VALUE mMessagePack);
|
|
35
|
+
|
|
36
|
+
VALUE MessagePack_unpack(int argc, VALUE* argv);
|
|
37
|
+
|
|
38
|
+
#endif
|
|
39
|
+
|
data/gitlab-cbor.gemspec
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = "gitlab-cbor"
|
|
3
|
+
# The fork has its own version line, independent of upstream's. This
|
|
4
|
+
# release is based on upstream cbor 0.6.1.1; see CHANGELOG.md.
|
|
5
|
+
s.version = "1.0.0"
|
|
6
|
+
s.summary = "CBOR, Concise Binary Object Representation (GitLab security fork)."
|
|
7
|
+
s.description = %q{GitLab's fork of the cbor gem. Decoding no longer reconstructs object-constructing tags (Regexp, URI) unless the caller opts in via reconstruct_from_tags:, so an untrusted CBOR.decode cannot reach Regexp.new. Based on Carsten Bormann's cbor, itself based on Sadayuki Furuhashi's MessagePack library.}
|
|
8
|
+
s.author = "Carsten Bormann, standing on the tall shoulders of Sadayuki Furuhashi"
|
|
9
|
+
s.email = "cabo@tzi.org"
|
|
10
|
+
s.license = "Apache-2.0"
|
|
11
|
+
s.homepage = "https://gitlab.com/gitlab-org/ruby/gems/gitlab-cbor"
|
|
12
|
+
s.metadata = {
|
|
13
|
+
"source_code_uri" => "https://gitlab.com/gitlab-org/ruby/gems/gitlab-cbor",
|
|
14
|
+
"upstream_uri" => "https://rubygems.org/gems/cbor"
|
|
15
|
+
}
|
|
16
|
+
s.files = `git ls-files`.split("\n")
|
|
17
|
+
s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
|
|
18
|
+
s.require_paths = ["lib"]
|
|
19
|
+
s.extensions = ["ext/cbor/extconf.rb"]
|
|
20
|
+
|
|
21
|
+
s.add_development_dependency 'bundler'
|
|
22
|
+
s.add_development_dependency 'rake', ['~> 0.9.2']
|
|
23
|
+
s.add_development_dependency 'rake-compiler', ['~> 0.8.3']
|
|
24
|
+
s.add_development_dependency 'rspec', ['~> 2.11']
|
|
25
|
+
s.add_development_dependency 'json', ['~> 1.7']
|
|
26
|
+
s.add_development_dependency 'yard', ['~> 0.9.11']
|
|
27
|
+
end
|
data/lib/cbor/version.rb
ADDED