bson 4.7.1 → 4.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://secure.travis-ci.org/mongodb/bson-ruby.
|
1
|
+
BSON [![Build Status](https://secure.travis-ci.org/mongodb/bson-ruby.svg?branch=master)](http://travis-ci.org/mongodb/bson-ruby)
|
2
|
+
[![Build status Windows](https://ci.appveyor.com/api/projects/status/p5aqko7umsx351nm?svg=true)](https://ci.appveyor.com/project/p-mongo/bson-ruby/branch/master)
|
3
|
+
[![Code Climate](https://codeclimate.com/github/mongodb/bson-ruby.svg)](https://codeclimate.com/github/mongodb/bson-ruby)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/mongodb/bson-ruby/badge.svg?branch=master)](https://coveralls.io/r/mongodb/bson-ruby?branch=master)
|
5
|
+
[![Inline docs](http://inch-ci.org/github/mongodb/bson-ruby.svg?branch=master)](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)
|