bson 4.7.1 → 4.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 +4 -4
- checksums.yaml.gz.sig +2 -2
- data.tar.gz.sig +0 -0
- data/README.md +5 -1
- data/ext/bson/bson-native.h +14 -4
- data/ext/bson/init.c +25 -2
- data/ext/bson/read.c +61 -15
- data/ext/bson/util.c +40 -0
- data/ext/bson/write.c +17 -13
- data/lib/bson.rb +3 -0
- data/lib/bson/array.rb +21 -3
- data/lib/bson/binary.rb +41 -3
- data/lib/bson/boolean.rb +3 -1
- data/lib/bson/code.rb +15 -1
- data/lib/bson/code_with_scope.rb +17 -3
- data/lib/bson/db_pointer.rb +104 -0
- data/lib/bson/decimal128.rb +15 -1
- data/lib/bson/error.rb +17 -0
- data/lib/bson/ext_json.rb +374 -0
- data/lib/bson/float.rb +47 -1
- data/lib/bson/hash.rb +23 -3
- data/lib/bson/int32.rb +21 -1
- data/lib/bson/int64.rb +28 -3
- data/lib/bson/integer.rb +34 -0
- data/lib/bson/max_key.rb +12 -0
- data/lib/bson/min_key.rb +12 -0
- data/lib/bson/nil_class.rb +3 -1
- data/lib/bson/object.rb +27 -0
- data/lib/bson/object_id.rb +15 -1
- data/lib/bson/regexp.rb +19 -2
- data/lib/bson/specialized.rb +3 -1
- data/lib/bson/string.rb +3 -1
- data/lib/bson/symbol.rb +92 -3
- data/lib/bson/time.rb +28 -3
- data/lib/bson/timestamp.rb +15 -1
- data/lib/bson/undefined.rb +11 -0
- data/lib/bson/version.rb +1 -1
- data/spec/bson/binary_spec.rb +33 -3
- data/spec/bson/ext_json_parse_spec.rb +276 -0
- data/spec/bson/float_spec.rb +36 -0
- data/spec/bson/hash_spec.rb +70 -0
- data/spec/bson/int32_spec.rb +20 -0
- data/spec/bson/int64_spec.rb +38 -0
- data/spec/bson/integer_spec.rb +26 -0
- data/spec/bson/raw_spec.rb +22 -1
- data/spec/bson/symbol_raw_spec.rb +45 -0
- data/spec/bson/symbol_spec.rb +60 -0
- data/spec/{support → runners}/common_driver.rb +0 -0
- data/spec/runners/corpus.rb +182 -0
- data/spec/{support/corpus.rb → runners/corpus_legacy.rb} +40 -58
- data/spec/spec_helper.rb +9 -2
- data/spec/{bson/driver_bson_spec.rb → spec_tests/common_driver_spec.rb} +1 -0
- data/spec/{bson/corpus_spec.rb → spec_tests/corpus_legacy_spec.rb} +4 -4
- data/spec/spec_tests/corpus_spec.rb +124 -0
- data/spec/spec_tests/data/corpus/README.md +15 -0
- data/spec/spec_tests/data/corpus/array.json +49 -0
- data/spec/spec_tests/data/corpus/binary.json +85 -0
- data/spec/spec_tests/data/corpus/boolean.json +27 -0
- data/spec/spec_tests/data/corpus/code.json +67 -0
- data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
- data/spec/spec_tests/data/corpus/datetime.json +42 -0
- data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
- data/spec/spec_tests/data/corpus/dbref.json +31 -0
- data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
- data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
- data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
- data/spec/spec_tests/data/corpus/decimal128-4.json +117 -0
- data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
- data/spec/spec_tests/data/corpus/decimal128-6.json +119 -0
- data/spec/spec_tests/data/corpus/decimal128-7.json +323 -0
- data/spec/spec_tests/data/corpus/document.json +36 -0
- data/spec/spec_tests/data/corpus/double.json +87 -0
- data/spec/spec_tests/data/corpus/int32.json +43 -0
- data/spec/spec_tests/data/corpus/int64.json +43 -0
- data/spec/spec_tests/data/corpus/maxkey.json +12 -0
- data/spec/spec_tests/data/corpus/minkey.json +12 -0
- data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
- data/spec/spec_tests/data/corpus/multi-type.json +11 -0
- data/spec/spec_tests/data/corpus/null.json +12 -0
- data/spec/spec_tests/data/corpus/oid.json +28 -0
- data/spec/spec_tests/data/corpus/regex.json +65 -0
- data/spec/spec_tests/data/corpus/string.json +72 -0
- data/spec/spec_tests/data/corpus/symbol.json +80 -0
- data/spec/spec_tests/data/corpus/timestamp.json +24 -0
- data/spec/spec_tests/data/corpus/top.json +240 -0
- data/spec/spec_tests/data/corpus/undefined.json +15 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/array.json +0 -0
- data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/binary.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/boolean.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code_w_scope.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/document.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/double.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/datetime.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/dbpointer.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/int64.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/symbol.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/int32.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/maxkey.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/minkey.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/null.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/oid.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/regex.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/string.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/timestamp.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/top.json +0 -0
- data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/undefined.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-1.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-2.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-3.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-4.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-5.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-6.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-7.json +0 -0
- metadata +170 -95
- metadata.gz.sig +2 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c37081fa823c2700f07a23ca6ecbec6fc67cffbf7915b4a21e59940b332b678d
|
4
|
+
data.tar.gz: 16d483a311c4252f4ef1463be2f86240450b82294a972d8bb5bb2bb332fd7b17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1618b74348d155c904b2f24739d7b9403bc0b1c23e67cc6ce89a92ac19070dd5965dc1fccc6353c2eefb82993bf5fec30702bccaaf6bb8171777421253832cce
|
7
|
+
data.tar.gz: 1362710c9b36348437bf266a52c18347c1228ddd92231b520e6b068b1742f42895c2108a64cdff2487c5b874c12e3af5ce4d4435c00cebad942b83f1ea9e17ab
|
checksums.yaml.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
��)
|
1
|
+
�}
|
2
|
+
O��t���9�a���2)����=%Zf{ms 3VeB�L)¡o�crp�e��r��@�K�~�
|
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
BSON [](http://travis-ci.org/mongodb/bson-ruby)
|
2
|
+
[](https://ci.appveyor.com/project/p-mongo/bson-ruby/branch/master)
|
3
|
+
[](https://codeclimate.com/github/mongodb/bson-ruby)
|
4
|
+
[](https://coveralls.io/r/mongodb/bson-ruby?branch=master)
|
5
|
+
[](http://inch-ci.org/github/mongodb/bson-ruby)
|
2
6
|
====
|
3
7
|
|
4
8
|
An implementation of the BSON specification in Ruby.
|
data/ext/bson/bson-native.h
CHANGED
@@ -33,13 +33,15 @@ rb_bson_utf8_validate (const char *utf8, /* IN */
|
|
33
33
|
#define HOST_NAME_HASH_MAX 256
|
34
34
|
#endif
|
35
35
|
|
36
|
+
/* See the type list in http://bsonspec.org/spec.html. */
|
36
37
|
#define BSON_TYPE_DOUBLE 1
|
37
38
|
#define BSON_TYPE_STRING 2
|
38
39
|
#define BSON_TYPE_DOCUMENT 3
|
39
40
|
#define BSON_TYPE_ARRAY 4
|
40
41
|
#define BSON_TYPE_BOOLEAN 8
|
41
|
-
#define
|
42
|
-
#define
|
42
|
+
#define BSON_TYPE_SYMBOL 0x0E
|
43
|
+
#define BSON_TYPE_INT32 0x10
|
44
|
+
#define BSON_TYPE_INT64 0x12
|
43
45
|
|
44
46
|
typedef struct {
|
45
47
|
size_t size;
|
@@ -76,8 +78,8 @@ VALUE rb_bson_byte_buffer_get_double(VALUE self);
|
|
76
78
|
VALUE rb_bson_byte_buffer_get_int32(VALUE self);
|
77
79
|
VALUE rb_bson_byte_buffer_get_int64(VALUE self);
|
78
80
|
VALUE rb_bson_byte_buffer_get_string(VALUE self);
|
79
|
-
VALUE rb_bson_byte_buffer_get_hash(VALUE self);
|
80
|
-
VALUE rb_bson_byte_buffer_get_array(VALUE self);
|
81
|
+
VALUE rb_bson_byte_buffer_get_hash(int argc, VALUE *argv, VALUE self);
|
82
|
+
VALUE rb_bson_byte_buffer_get_array(int argc, VALUE *argv, VALUE self);
|
81
83
|
VALUE rb_bson_byte_buffer_put_byte(VALUE self, VALUE byte);
|
82
84
|
VALUE rb_bson_byte_buffer_put_bytes(VALUE self, VALUE bytes);
|
83
85
|
VALUE rb_bson_byte_buffer_put_cstring(VALUE self, VALUE string);
|
@@ -101,6 +103,14 @@ void rb_bson_byte_buffer_free(void *ptr);
|
|
101
103
|
void rb_bson_expand_buffer(byte_buffer_t* buffer_ptr, size_t length);
|
102
104
|
void rb_bson_generate_machine_id(VALUE rb_md5_class, char *rb_bson_machine_id);
|
103
105
|
|
106
|
+
VALUE pvt_const_get_2(const char *c1, const char *c2);
|
107
|
+
VALUE pvt_const_get_3(const char *c1, const char *c2, const char *c3);
|
108
|
+
|
109
|
+
#define BSON_MODE_DEFAULT 0
|
110
|
+
#define BSON_MODE_BSON 1
|
111
|
+
|
112
|
+
int pvt_get_mode_option(int argc, VALUE *argv);
|
113
|
+
|
104
114
|
/**
|
105
115
|
* The counter for incrementing object ids.
|
106
116
|
*/
|
data/ext/bson/init.c
CHANGED
@@ -70,8 +70,31 @@ void Init_bson_native()
|
|
70
70
|
rb_define_method(rb_byte_buffer_class, "get_cstring", rb_bson_byte_buffer_get_cstring, 0);
|
71
71
|
rb_define_method(rb_byte_buffer_class, "get_decimal128_bytes", rb_bson_byte_buffer_get_decimal128_bytes, 0);
|
72
72
|
rb_define_method(rb_byte_buffer_class, "get_double", rb_bson_byte_buffer_get_double, 0);
|
73
|
-
|
74
|
-
|
73
|
+
|
74
|
+
/*
|
75
|
+
* call-seq:
|
76
|
+
* buffer.get_hash(**options) -> Hash
|
77
|
+
*
|
78
|
+
* Reads a document from the byte buffer and returns it as a BSON::Document.
|
79
|
+
*
|
80
|
+
* @option options [ nil | :bson ] :mode Decoding mode to use.
|
81
|
+
*
|
82
|
+
* @return [ BSON::Document ] The decoded document.
|
83
|
+
*/
|
84
|
+
rb_define_method(rb_byte_buffer_class, "get_hash", rb_bson_byte_buffer_get_hash, -1);
|
85
|
+
|
86
|
+
/*
|
87
|
+
* call-seq:
|
88
|
+
* buffer.get_array(**options) -> Array
|
89
|
+
*
|
90
|
+
* Reads an array from the byte buffer..
|
91
|
+
*
|
92
|
+
* @option options [ nil | :bson ] :mode Decoding mode to use.
|
93
|
+
*
|
94
|
+
* @return [ Array ] The decoded array.
|
95
|
+
*/
|
96
|
+
rb_define_method(rb_byte_buffer_class, "get_array", rb_bson_byte_buffer_get_array, -1);
|
97
|
+
|
75
98
|
rb_define_method(rb_byte_buffer_class, "get_int32", rb_bson_byte_buffer_get_int32, 0);
|
76
99
|
rb_define_method(rb_byte_buffer_class, "get_int64", rb_bson_byte_buffer_get_int64, 0);
|
77
100
|
rb_define_method(rb_byte_buffer_class, "get_string", rb_bson_byte_buffer_get_string, 0);
|
data/ext/bson/read.c
CHANGED
@@ -20,11 +20,12 @@
|
|
20
20
|
static void pvt_validate_length(byte_buffer_t *b);
|
21
21
|
static uint8_t pvt_get_type_byte(byte_buffer_t *b);
|
22
22
|
static VALUE pvt_get_int32(byte_buffer_t *b);
|
23
|
-
static VALUE pvt_get_int64(byte_buffer_t *b);
|
23
|
+
static VALUE pvt_get_int64(byte_buffer_t *b, int argc, VALUE *argv);
|
24
24
|
static VALUE pvt_get_double(byte_buffer_t *b);
|
25
25
|
static VALUE pvt_get_string(byte_buffer_t *b);
|
26
|
+
static VALUE pvt_get_symbol(byte_buffer_t *b, VALUE rb_buffer, int argc, VALUE *argv);
|
26
27
|
static VALUE pvt_get_boolean(byte_buffer_t *b);
|
27
|
-
static VALUE pvt_read_field(byte_buffer_t *b, VALUE rb_buffer, uint8_t type);
|
28
|
+
static VALUE pvt_read_field(byte_buffer_t *b, VALUE rb_buffer, uint8_t type, int argc, VALUE *argv);
|
28
29
|
static void pvt_skip_cstring(byte_buffer_t *b);
|
29
30
|
|
30
31
|
/**
|
@@ -57,14 +58,16 @@ void pvt_validate_length(byte_buffer_t *b)
|
|
57
58
|
/**
|
58
59
|
* Read a single field from a hash or array
|
59
60
|
*/
|
60
|
-
VALUE pvt_read_field(byte_buffer_t *b, VALUE rb_buffer, uint8_t type)
|
61
|
+
VALUE pvt_read_field(byte_buffer_t *b, VALUE rb_buffer, uint8_t type, int argc, VALUE *argv)
|
62
|
+
{
|
61
63
|
switch(type) {
|
62
64
|
case BSON_TYPE_INT32: return pvt_get_int32(b);
|
63
|
-
case BSON_TYPE_INT64: return pvt_get_int64(b);
|
65
|
+
case BSON_TYPE_INT64: return pvt_get_int64(b, argc, argv);
|
64
66
|
case BSON_TYPE_DOUBLE: return pvt_get_double(b);
|
65
67
|
case BSON_TYPE_STRING: return pvt_get_string(b);
|
66
|
-
case
|
67
|
-
case
|
68
|
+
case BSON_TYPE_SYMBOL: return pvt_get_symbol(b, rb_buffer, argc, argv);
|
69
|
+
case BSON_TYPE_ARRAY: return rb_bson_byte_buffer_get_array(argc, argv, rb_buffer);
|
70
|
+
case BSON_TYPE_DOCUMENT: return rb_bson_byte_buffer_get_hash(argc, argv, rb_buffer);
|
68
71
|
case BSON_TYPE_BOOLEAN: return pvt_get_boolean(b);
|
69
72
|
default:
|
70
73
|
{
|
@@ -150,6 +153,31 @@ VALUE pvt_get_string(byte_buffer_t *b)
|
|
150
153
|
return string;
|
151
154
|
}
|
152
155
|
|
156
|
+
/**
|
157
|
+
* Reads a UTF-8 string out of the byte buffer. If the argc/argv arguments
|
158
|
+
* have a :mode option with the value of :bson, wraps the string in a
|
159
|
+
* BSON::Symbol::Raw. Otherwise consults the BSON registry to determine
|
160
|
+
* which class to instantiate (String in bson-ruby, overridden to Symbol by
|
161
|
+
* the Ruby driver). Returns either a BSON::Symbol::Raw, Symbol or String
|
162
|
+
* value.
|
163
|
+
*/
|
164
|
+
VALUE pvt_get_symbol(byte_buffer_t *b, VALUE rb_buffer, int argc, VALUE *argv)
|
165
|
+
{
|
166
|
+
VALUE value, klass;
|
167
|
+
|
168
|
+
if (pvt_get_mode_option(argc, argv) == BSON_MODE_BSON) {
|
169
|
+
value = pvt_get_string(b);
|
170
|
+
klass = pvt_const_get_3("BSON", "Symbol", "Raw");
|
171
|
+
value = rb_funcall(klass, rb_intern("new"), 1, value);
|
172
|
+
} else {
|
173
|
+
klass = rb_funcall(rb_bson_registry, rb_intern("get"), 1, INT2FIX(BSON_TYPE_SYMBOL));
|
174
|
+
value = rb_funcall(klass, rb_intern("from_bson"), 1, rb_buffer);
|
175
|
+
}
|
176
|
+
|
177
|
+
RB_GC_GUARD(klass);
|
178
|
+
return value;
|
179
|
+
}
|
180
|
+
|
153
181
|
/**
|
154
182
|
* Get a cstring from the buffer.
|
155
183
|
*/
|
@@ -206,17 +234,35 @@ VALUE rb_bson_byte_buffer_get_int64(VALUE self)
|
|
206
234
|
{
|
207
235
|
byte_buffer_t *b;
|
208
236
|
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
209
|
-
return pvt_get_int64(b);
|
237
|
+
return pvt_get_int64(b, 0, NULL);
|
210
238
|
}
|
211
239
|
|
212
|
-
|
240
|
+
/**
|
241
|
+
* Reads a 64-bit integer out of the byte buffer into a Ruby Integer instance.
|
242
|
+
* If the argc/argv arguments have a :mode option with the value of :bson,
|
243
|
+
* wraps the integer in a BSON::Int64. Returns either the Integer or the
|
244
|
+
* BSON::Int64 instance.
|
245
|
+
*/
|
246
|
+
VALUE pvt_get_int64(byte_buffer_t *b, int argc, VALUE *argv)
|
213
247
|
{
|
214
248
|
int64_t i64;
|
249
|
+
VALUE num;
|
215
250
|
|
216
251
|
ENSURE_BSON_READ(b, 8);
|
217
252
|
memcpy(&i64, READ_PTR(b), 8);
|
218
253
|
b->read_position += 8;
|
219
|
-
|
254
|
+
num = LL2NUM(BSON_UINT64_FROM_LE(i64));
|
255
|
+
|
256
|
+
if (pvt_get_mode_option(argc, argv) == BSON_MODE_BSON) {
|
257
|
+
VALUE klass = rb_funcall(rb_bson_registry,rb_intern("get"),1, INT2FIX(BSON_TYPE_INT64));
|
258
|
+
VALUE value = rb_funcall(klass, rb_intern("new"), 1, num);
|
259
|
+
RB_GC_GUARD(klass);
|
260
|
+
return value;
|
261
|
+
} else {
|
262
|
+
return num;
|
263
|
+
}
|
264
|
+
|
265
|
+
RB_GC_GUARD(num);
|
220
266
|
}
|
221
267
|
|
222
268
|
/**
|
@@ -255,27 +301,27 @@ VALUE rb_bson_byte_buffer_get_decimal128_bytes(VALUE self)
|
|
255
301
|
return bytes;
|
256
302
|
}
|
257
303
|
|
258
|
-
VALUE rb_bson_byte_buffer_get_hash(VALUE self){
|
304
|
+
VALUE rb_bson_byte_buffer_get_hash(int argc, VALUE *argv, VALUE self){
|
259
305
|
VALUE doc = Qnil;
|
260
306
|
byte_buffer_t *b = NULL;
|
261
307
|
uint8_t type;
|
262
|
-
VALUE cDocument =
|
308
|
+
VALUE cDocument = pvt_const_get_2("BSON", "Document");
|
263
309
|
|
264
310
|
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
265
311
|
|
266
312
|
pvt_validate_length(b);
|
267
313
|
|
268
|
-
doc = rb_funcall(cDocument, rb_intern("allocate"),0);
|
314
|
+
doc = rb_funcall(cDocument, rb_intern("allocate"), 0);
|
269
315
|
|
270
316
|
while((type = pvt_get_type_byte(b)) != 0){
|
271
317
|
VALUE field = rb_bson_byte_buffer_get_cstring(self);
|
318
|
+
rb_hash_aset(doc, field, pvt_read_field(b, self, type, argc, argv));
|
272
319
|
RB_GC_GUARD(field);
|
273
|
-
rb_hash_aset(doc, field, pvt_read_field(b, self, type));
|
274
320
|
}
|
275
321
|
return doc;
|
276
322
|
}
|
277
323
|
|
278
|
-
VALUE rb_bson_byte_buffer_get_array(VALUE self){
|
324
|
+
VALUE rb_bson_byte_buffer_get_array(int argc, VALUE *argv, VALUE self){
|
279
325
|
byte_buffer_t *b;
|
280
326
|
VALUE array = Qnil;
|
281
327
|
uint8_t type;
|
@@ -287,7 +333,7 @@ VALUE rb_bson_byte_buffer_get_array(VALUE self){
|
|
287
333
|
array = rb_ary_new();
|
288
334
|
while((type = pvt_get_type_byte(b)) != 0){
|
289
335
|
pvt_skip_cstring(b);
|
290
|
-
rb_ary_push(array, pvt_read_field(b, self, type));
|
336
|
+
rb_ary_push(array, pvt_read_field(b, self, type, argc, argv));
|
291
337
|
}
|
292
338
|
RB_GC_GUARD(array);
|
293
339
|
return array;
|
data/ext/bson/util.c
CHANGED
@@ -53,3 +53,43 @@ VALUE rb_bson_object_id_generator_next(int argc, VALUE* args, VALUE self)
|
|
53
53
|
rb_bson_object_id_counter++;
|
54
54
|
return rb_str_new(bytes, 12);
|
55
55
|
}
|
56
|
+
|
57
|
+
/**
|
58
|
+
* Returns a Ruby constant nested one level, e.g. BSON::Document.
|
59
|
+
*/
|
60
|
+
VALUE pvt_const_get_2(const char *c1, const char *c2) {
|
61
|
+
return rb_const_get(rb_const_get(rb_cObject, rb_intern(c1)), rb_intern(c2));
|
62
|
+
}
|
63
|
+
|
64
|
+
/**
|
65
|
+
* Returns a Ruby constant nested two levels, e.g. BSON::Regexp::Raw.
|
66
|
+
*/
|
67
|
+
VALUE pvt_const_get_3(const char *c1, const char *c2, const char *c3) {
|
68
|
+
return rb_const_get(pvt_const_get_2(c1, c2), rb_intern(c3));
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
* Returns the value of the :mode option, or the default if the option is not
|
73
|
+
* specified. Raises ArgumentError if the value is not one of nil or :bson.
|
74
|
+
* A future version of bson-ruby is expected to also support :ruby and :ruby!
|
75
|
+
* values. Returns one of the BSON_MODE_* values.
|
76
|
+
*/
|
77
|
+
int pvt_get_mode_option(int argc, VALUE *argv) {
|
78
|
+
VALUE opts;
|
79
|
+
VALUE mode;
|
80
|
+
|
81
|
+
rb_scan_args(argc, argv, ":", &opts);
|
82
|
+
if (NIL_P(opts)) {
|
83
|
+
return BSON_MODE_DEFAULT;
|
84
|
+
} else {
|
85
|
+
mode = rb_hash_lookup(opts, ID2SYM(rb_intern("mode")));
|
86
|
+
if (mode == Qnil) {
|
87
|
+
return BSON_MODE_DEFAULT;
|
88
|
+
} else if (mode == ID2SYM(rb_intern("bson"))) {
|
89
|
+
return BSON_MODE_BSON;
|
90
|
+
} else {
|
91
|
+
rb_raise(rb_eArgError, "Invalid value for :mode option: %s",
|
92
|
+
RSTRING_PTR(rb_funcall(mode, rb_intern("inspect"), 0)));
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
data/ext/bson/write.c
CHANGED
@@ -125,40 +125,44 @@ VALUE rb_bson_byte_buffer_put_bytes(VALUE self, VALUE bytes)
|
|
125
125
|
return self;
|
126
126
|
}
|
127
127
|
|
128
|
-
/* write the byte denoting the BSON type for the passed object*/
|
128
|
+
/* write the byte denoting the BSON type for the passed object */
|
129
129
|
void pvt_put_type_byte(byte_buffer_t *b, VALUE val){
|
130
|
-
|
130
|
+
char type_byte;
|
131
|
+
|
132
|
+
switch (TYPE(val)){
|
131
133
|
case T_BIGNUM:
|
132
134
|
case T_FIXNUM:
|
133
|
-
if(fits_int32(NUM2LL(val))){
|
134
|
-
|
135
|
-
}else{
|
136
|
-
|
135
|
+
if (fits_int32(NUM2LL(val))) {
|
136
|
+
type_byte = BSON_TYPE_INT32;
|
137
|
+
} else {
|
138
|
+
type_byte = BSON_TYPE_INT64;
|
137
139
|
}
|
138
140
|
break;
|
139
141
|
case T_STRING:
|
140
|
-
|
142
|
+
type_byte = BSON_TYPE_STRING;
|
141
143
|
break;
|
142
144
|
case T_ARRAY:
|
143
|
-
|
145
|
+
type_byte = BSON_TYPE_ARRAY;
|
144
146
|
break;
|
145
147
|
case T_TRUE:
|
146
148
|
case T_FALSE:
|
147
|
-
|
149
|
+
type_byte = BSON_TYPE_BOOLEAN;
|
148
150
|
break;
|
149
151
|
case T_HASH:
|
150
|
-
|
152
|
+
type_byte = BSON_TYPE_DOCUMENT;
|
151
153
|
break;
|
152
154
|
case T_FLOAT:
|
153
|
-
|
155
|
+
type_byte = BSON_TYPE_DOUBLE;
|
154
156
|
break;
|
155
157
|
default:{
|
156
|
-
VALUE type = rb_funcall(val, rb_intern("bson_type"),0);
|
158
|
+
VALUE type = rb_funcall(val, rb_intern("bson_type"), 0);
|
159
|
+
type_byte = *RSTRING_PTR(type);
|
157
160
|
RB_GC_GUARD(type);
|
158
|
-
pvt_put_byte(b, *RSTRING_PTR(type));
|
159
161
|
break;
|
160
162
|
}
|
161
163
|
}
|
164
|
+
|
165
|
+
pvt_put_byte(b, type_byte);
|
162
166
|
}
|
163
167
|
|
164
168
|
/**
|
data/lib/bson.rb
CHANGED
@@ -57,6 +57,7 @@ module BSON
|
|
57
57
|
end
|
58
58
|
|
59
59
|
require "bson/config"
|
60
|
+
require "bson/error"
|
60
61
|
require "bson/registry"
|
61
62
|
require "bson/specialized"
|
62
63
|
require "bson/json"
|
@@ -70,8 +71,10 @@ require "bson/code"
|
|
70
71
|
require "bson/code_with_scope"
|
71
72
|
require "bson/date"
|
72
73
|
require "bson/date_time"
|
74
|
+
require "bson/db_pointer"
|
73
75
|
require "bson/decimal128"
|
74
76
|
require "bson/document"
|
77
|
+
require "bson/ext_json"
|
75
78
|
require "bson/false_class"
|
76
79
|
require "bson/float"
|
77
80
|
require "bson/hash"
|
data/lib/bson/array.rb
CHANGED
@@ -85,26 +85,44 @@ module BSON
|
|
85
85
|
map { |value| value.to_bson_normalized_value }
|
86
86
|
end
|
87
87
|
|
88
|
+
# Converts this object to a representation directly serializable to
|
89
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
90
|
+
#
|
91
|
+
# This method recursively invokes +as_extended_json+ with the provided
|
92
|
+
# options on each array element.
|
93
|
+
#
|
94
|
+
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
95
|
+
# (default is canonical extended JSON)
|
96
|
+
#
|
97
|
+
# @return [ Array ] This array converted to extended json representation.
|
98
|
+
def as_extended_json(**options)
|
99
|
+
map do |item|
|
100
|
+
item.as_extended_json(**options)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
88
104
|
module ClassMethods
|
89
105
|
|
90
106
|
# Deserialize the array from BSON.
|
91
107
|
#
|
92
108
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
93
109
|
#
|
110
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
111
|
+
#
|
94
112
|
# @return [ Array ] The decoded array.
|
95
113
|
#
|
96
114
|
# @see http://bsonspec.org/#/specification
|
97
115
|
#
|
98
116
|
# @since 2.0.0
|
99
|
-
def from_bson(buffer)
|
117
|
+
def from_bson(buffer, **options)
|
100
118
|
if buffer.respond_to?(:get_array)
|
101
|
-
buffer.get_array
|
119
|
+
buffer.get_array(**options)
|
102
120
|
else
|
103
121
|
array = new
|
104
122
|
buffer.get_int32 # throw away the length
|
105
123
|
while (type = buffer.get_byte) != NULL_BYTE
|
106
124
|
buffer.get_cstring
|
107
|
-
array << BSON::Registry.get(type).from_bson(buffer)
|
125
|
+
array << BSON::Registry.get(type).from_bson(buffer, **options)
|
108
126
|
end
|
109
127
|
array
|
110
128
|
end
|
data/lib/bson/binary.rb
CHANGED
@@ -31,6 +31,12 @@ module BSON
|
|
31
31
|
|
32
32
|
# The mappings of subtypes to their single byte identifiers.
|
33
33
|
#
|
34
|
+
# @note subtype 6 (ciphertext) is used for the Client-Side Encryption
|
35
|
+
# feature. Data represented by this subtype is often encrypted, but
|
36
|
+
# may also be plaintext. All instances of this subtype necessary for
|
37
|
+
# Client-Side Encryption will be created internally by the Ruby driver.
|
38
|
+
# An application should not create new BSON::Binary objects of this subtype.
|
39
|
+
#
|
34
40
|
# @since 2.0.0
|
35
41
|
SUBTYPES = {
|
36
42
|
:generic => 0.chr,
|
@@ -39,6 +45,7 @@ module BSON
|
|
39
45
|
:uuid_old => 3.chr,
|
40
46
|
:uuid => 4.chr,
|
41
47
|
:md5 => 5.chr,
|
48
|
+
:ciphertext => 6.chr,
|
42
49
|
:user => 128.chr
|
43
50
|
}.freeze
|
44
51
|
|
@@ -94,8 +101,31 @@ module BSON
|
|
94
101
|
# @return [ Hash ] The binary as a JSON hash.
|
95
102
|
#
|
96
103
|
# @since 2.0.0
|
104
|
+
# @deprecated Use as_extended_json instead.
|
97
105
|
def as_json(*args)
|
98
|
-
|
106
|
+
as_extended_json
|
107
|
+
end
|
108
|
+
|
109
|
+
# Converts this object to a representation directly serializable to
|
110
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
111
|
+
#
|
112
|
+
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
113
|
+
# (default is canonical extended JSON)
|
114
|
+
#
|
115
|
+
# @return [ Hash ] The extended json representation.
|
116
|
+
def as_extended_json(**options)
|
117
|
+
subtype = SUBTYPES[type].each_byte.map { |c| c.to_s(16) }.join
|
118
|
+
if subtype.length == 1
|
119
|
+
subtype = "0#{subtype}"
|
120
|
+
end
|
121
|
+
|
122
|
+
value = Base64.encode64(data).strip
|
123
|
+
|
124
|
+
if options[:mode] == :legacy
|
125
|
+
{ "$binary" => value, "$type" => subtype }
|
126
|
+
else
|
127
|
+
{ "$binary" => {'base64' => value, "subType" => subtype }}
|
128
|
+
end
|
99
129
|
end
|
100
130
|
|
101
131
|
# Instantiate the new binary object.
|
@@ -228,14 +258,22 @@ module BSON
|
|
228
258
|
#
|
229
259
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
230
260
|
#
|
261
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
262
|
+
#
|
231
263
|
# @return [ Binary ] The decoded binary data.
|
232
264
|
#
|
233
265
|
# @see http://bsonspec.org/#/specification
|
234
266
|
#
|
235
267
|
# @since 2.0.0
|
236
|
-
def self.from_bson(buffer)
|
268
|
+
def self.from_bson(buffer, **options)
|
237
269
|
length = buffer.get_int32
|
238
|
-
|
270
|
+
type_byte = buffer.get_byte
|
271
|
+
type = TYPES[type_byte]
|
272
|
+
if type.nil?
|
273
|
+
raise Error::UnsupportedBinarySubtype,
|
274
|
+
"BSON data contains unsupported binary subtype #{'0x%02x' % type_byte.ord}"
|
275
|
+
end
|
276
|
+
|
239
277
|
length = buffer.get_int32 if type == :old
|
240
278
|
data = buffer.get_bytes(length)
|
241
279
|
new(data, type)
|