bson 4.9.0 → 4.15.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 +0 -0
- data/README.md +15 -6
- data/ext/bson/bson-native.h +4 -0
- data/ext/bson/init.c +75 -23
- data/ext/bson/read.c +63 -11
- data/ext/bson/write.c +42 -3
- data/lib/bson/active_support.rb +1 -0
- data/lib/bson/array.rb +5 -1
- data/lib/bson/big_decimal.rb +67 -0
- data/lib/bson/binary.rb +8 -5
- data/lib/bson/boolean.rb +2 -1
- data/lib/bson/code.rb +2 -1
- data/lib/bson/code_with_scope.rb +2 -1
- data/lib/bson/config.rb +1 -0
- data/lib/bson/date.rb +1 -0
- data/lib/bson/date_time.rb +2 -1
- data/lib/bson/db_pointer.rb +2 -1
- data/lib/bson/dbref.rb +152 -0
- data/lib/bson/decimal128/builder.rb +27 -20
- data/lib/bson/decimal128.rb +39 -14
- data/lib/bson/document.rb +61 -18
- data/lib/bson/environment.rb +1 -0
- data/lib/bson/error.rb +13 -0
- data/lib/bson/ext_json.rb +24 -11
- data/lib/bson/false_class.rb +2 -1
- data/lib/bson/float.rb +21 -32
- data/lib/bson/hash.rb +18 -6
- data/lib/bson/int32.rb +3 -2
- data/lib/bson/int64.rb +3 -2
- data/lib/bson/integer.rb +3 -2
- data/lib/bson/json.rb +1 -0
- data/lib/bson/max_key.rb +3 -2
- data/lib/bson/min_key.rb +3 -2
- data/lib/bson/nil_class.rb +2 -1
- data/lib/bson/object.rb +1 -0
- data/lib/bson/object_id.rb +4 -3
- data/lib/bson/open_struct.rb +1 -0
- data/lib/bson/regexp.rb +24 -7
- data/lib/bson/registry.rb +1 -0
- data/lib/bson/specialized.rb +1 -0
- data/lib/bson/string.rb +3 -2
- data/lib/bson/symbol.rb +2 -1
- data/lib/bson/time.rb +4 -3
- data/lib/bson/time_with_zone.rb +1 -0
- data/lib/bson/timestamp.rb +7 -6
- data/lib/bson/true_class.rb +2 -1
- data/lib/bson/undefined.rb +2 -1
- data/lib/bson/version.rb +2 -1
- data/lib/bson.rb +8 -5
- data/spec/README.md +14 -0
- data/spec/bson/array_spec.rb +17 -0
- data/spec/bson/big_decimal_spec.rb +316 -0
- data/spec/bson/binary_spec.rb +1 -1
- data/spec/bson/binary_uuid_spec.rb +12 -0
- data/spec/bson/byte_buffer_read_spec.rb +59 -3
- data/spec/bson/byte_buffer_spec.rb +129 -6
- data/spec/bson/byte_buffer_write_spec.rb +96 -0
- data/spec/bson/date_time_spec.rb +53 -0
- data/spec/bson/dbref_legacy_spec.rb +169 -0
- data/spec/bson/dbref_spec.rb +487 -0
- data/spec/bson/decimal128_spec.rb +231 -0
- data/spec/bson/document_as_spec.rb +46 -0
- data/spec/bson/document_spec.rb +43 -1
- data/spec/bson/ext_json_parse_spec.rb +37 -0
- data/spec/bson/hash_as_spec.rb +57 -0
- data/spec/bson/hash_spec.rb +105 -0
- data/spec/bson/int64_spec.rb +4 -24
- data/spec/bson/raw_spec.rb +18 -1
- data/spec/bson/regexp_spec.rb +52 -0
- data/spec/runners/common_driver.rb +1 -1
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/cluster_config.rb +231 -0
- data/spec/shared/lib/mrss/constraints.rb +386 -0
- data/spec/shared/lib/mrss/docker_runner.rb +271 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +191 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +120 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
- data/spec/shared/lib/mrss/utils.rb +15 -0
- data/spec/shared/share/Dockerfile.erb +338 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/distro.sh +74 -0
- data/spec/shared/shlib/server.sh +367 -0
- data/spec/shared/shlib/set_env.sh +131 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/spec_tests/common_driver_spec.rb +2 -1
- data/spec/spec_tests/data/corpus/binary.json +33 -0
- data/spec/spec_tests/data/corpus/dbref.json +21 -1
- data/spec/spec_tests/data/corpus/document.json +4 -0
- data/spec/spec_tests/data/corpus/regex.json +2 -2
- data/spec/spec_tests/data/corpus/timestamp.json +10 -0
- data/spec/spec_tests/data/corpus/top.json +23 -12
- data/spec/support/spec_config.rb +8 -1
- data.tar.gz.sig +0 -0
- metadata +168 -93
- metadata.gz.sig +1 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d0c420e8204cb354acfc6adadb5097b71f4a8346620a5461153c6461aece1e2
|
4
|
+
data.tar.gz: ce5e7172180e7e9f5c60d2af3207b50e0ead96283d36828e75a118cc53cdd7fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 990f1be935132660ad51dab98c9233e12f9af5d03eac5f52a5bef82a78af2d258c12721564bfaf042977766c65d9adc7dbc7d88241283207213fe9ac15c9a024
|
7
|
+
data.tar.gz: 8004b3cd0e51a769df76fd9027058f403efe6b5a565eff39aca3e43f700f0b77a7a670793dfb043d0cf963537eda0426e8a885dd4044adc2800934beaeb59286
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
BSON
|
2
|
-
[![
|
3
|
-
[![
|
4
|
-
[![Coverage Status]
|
5
|
-
[![Inline docs]
|
1
|
+
BSON
|
2
|
+
[![Gem Version][rubygems-img]][rubygems-url]
|
3
|
+
[![Build Status][ghactions-img]][ghactions-url]
|
4
|
+
[![Coverage Status][coveralls-img]][coveralls-url]
|
5
|
+
[![Inline docs][inch-img]][inch-url]
|
6
6
|
====
|
7
7
|
|
8
8
|
An implementation of the BSON specification in Ruby.
|
@@ -10,7 +10,7 @@ An implementation of the BSON specification in Ruby.
|
|
10
10
|
Compatibility
|
11
11
|
-------------
|
12
12
|
|
13
|
-
BSON is tested against MRI (2.
|
13
|
+
BSON is tested against MRI (2.5) and JRuby (9.2+).
|
14
14
|
|
15
15
|
Documentation
|
16
16
|
-------------
|
@@ -51,3 +51,12 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
|
51
51
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
52
52
|
See the License for the specific language governing permissions and
|
53
53
|
limitations under the License.
|
54
|
+
|
55
|
+
[rubygems-img]: https://badge.fury.io/rb/bson.svg
|
56
|
+
[rubygems-url]: http://badge.fury.io/rb/bson
|
57
|
+
[ghactions-img]: https://github.com/mongodb/bson-ruby/actions/workflows/bson-ruby.yml/badge.svg?query=branch%3Amaster
|
58
|
+
[ghactions-url]: https://github.com/mongodb/bson-ruby/actions/workflows/bson-ruby.yml?query=branch%3Amaster
|
59
|
+
[coveralls-img]: https://coveralls.io/repos/mongodb/bson-ruby/badge.svg?branch=master
|
60
|
+
[coveralls-url]: https://coveralls.io/r/mongodb/bson-ruby?branch=master
|
61
|
+
[inch-img]: http://inch-ci.org/github/mongodb/bson-ruby.svg?branch=master
|
62
|
+
[inch-url]: http://inch-ci.org/github/mongodb/bson-ruby
|
data/ext/bson/bson-native.h
CHANGED
@@ -76,6 +76,7 @@ VALUE rb_bson_byte_buffer_get_cstring(VALUE self);
|
|
76
76
|
VALUE rb_bson_byte_buffer_get_decimal128_bytes(VALUE self);
|
77
77
|
VALUE rb_bson_byte_buffer_get_double(VALUE self);
|
78
78
|
VALUE rb_bson_byte_buffer_get_int32(VALUE self);
|
79
|
+
VALUE rb_bson_byte_buffer_get_uint32(VALUE self);
|
79
80
|
VALUE rb_bson_byte_buffer_get_int64(VALUE self);
|
80
81
|
VALUE rb_bson_byte_buffer_get_string(VALUE self);
|
81
82
|
VALUE rb_bson_byte_buffer_get_hash(int argc, VALUE *argv, VALUE self);
|
@@ -86,6 +87,7 @@ VALUE rb_bson_byte_buffer_put_cstring(VALUE self, VALUE string);
|
|
86
87
|
VALUE rb_bson_byte_buffer_put_decimal128(VALUE self, VALUE low, VALUE high);
|
87
88
|
VALUE rb_bson_byte_buffer_put_double(VALUE self, VALUE f);
|
88
89
|
VALUE rb_bson_byte_buffer_put_int32(VALUE self, VALUE i);
|
90
|
+
VALUE rb_bson_byte_buffer_put_uint32(VALUE self, VALUE i);
|
89
91
|
VALUE rb_bson_byte_buffer_put_int64(VALUE self, VALUE i);
|
90
92
|
VALUE rb_bson_byte_buffer_put_string(VALUE self, VALUE string);
|
91
93
|
VALUE rb_bson_byte_buffer_put_symbol(VALUE self, VALUE symbol);
|
@@ -121,3 +123,5 @@ extern VALUE rb_bson_registry;
|
|
121
123
|
extern VALUE rb_bson_illegal_key;
|
122
124
|
|
123
125
|
extern const rb_data_type_t rb_byte_buffer_data_type;
|
126
|
+
|
127
|
+
extern VALUE _ref_str, _id_str, _db_str;
|
data/ext/bson/init.c
CHANGED
@@ -30,6 +30,8 @@ const rb_data_type_t rb_byte_buffer_data_type = {
|
|
30
30
|
{ NULL, rb_bson_byte_buffer_free, rb_bson_byte_buffer_memsize }
|
31
31
|
};
|
32
32
|
|
33
|
+
VALUE _ref_str, _id_str, _db_str;
|
34
|
+
|
33
35
|
/**
|
34
36
|
* Initialize the bson_native extension.
|
35
37
|
*/
|
@@ -37,26 +39,44 @@ void Init_bson_native()
|
|
37
39
|
{
|
38
40
|
char rb_bson_machine_id[256];
|
39
41
|
|
42
|
+
_ref_str = rb_str_new_cstr("$ref");
|
43
|
+
rb_gc_register_mark_object(_ref_str);
|
44
|
+
_id_str = rb_str_new_cstr("$id");
|
45
|
+
rb_gc_register_mark_object(_id_str);
|
46
|
+
_db_str = rb_str_new_cstr("$db");
|
47
|
+
rb_gc_register_mark_object(_db_str);
|
48
|
+
|
40
49
|
VALUE rb_bson_module = rb_define_module("BSON");
|
41
|
-
|
50
|
+
|
42
51
|
/* Document-class: BSON::ByteBuffer
|
43
52
|
*
|
44
53
|
* Stores BSON-serialized data and provides efficient serialization and
|
45
54
|
* deserialization of common Ruby classes using native code.
|
46
55
|
*/
|
47
56
|
VALUE rb_byte_buffer_class = rb_define_class_under(rb_bson_module, "ByteBuffer", rb_cObject);
|
48
|
-
|
57
|
+
|
49
58
|
VALUE rb_bson_object_id_class = rb_const_get(rb_bson_module, rb_intern("ObjectId"));
|
50
59
|
VALUE rb_bson_object_id_generator_class = rb_const_get(rb_bson_object_id_class, rb_intern("Generator"));
|
51
60
|
VALUE rb_digest_class = rb_const_get(rb_cObject, rb_intern("Digest"));
|
52
61
|
VALUE rb_md5_class = rb_const_get(rb_digest_class, rb_intern("MD5"));
|
53
62
|
|
54
63
|
rb_bson_illegal_key = rb_const_get(rb_const_get(rb_bson_module, rb_intern("String")),rb_intern("IllegalKey"));
|
64
|
+
rb_gc_register_mark_object(rb_bson_illegal_key);
|
55
65
|
|
56
66
|
rb_define_alloc_func(rb_byte_buffer_class, rb_bson_byte_buffer_allocate);
|
57
67
|
rb_define_method(rb_byte_buffer_class, "initialize", rb_bson_byte_buffer_initialize, -1);
|
68
|
+
|
69
|
+
/*
|
70
|
+
* call-seq:
|
71
|
+
* buffer.length -> Fixnum
|
72
|
+
*
|
73
|
+
* Returns the number of bytes available to be read in the buffer.
|
74
|
+
*
|
75
|
+
* When a buffer is being written to, each added byte increases its length.
|
76
|
+
* When a buffer is being read from, each read byte decreases its length.
|
77
|
+
*/
|
58
78
|
rb_define_method(rb_byte_buffer_class, "length", rb_bson_byte_buffer_length, 0);
|
59
|
-
|
79
|
+
|
60
80
|
/*
|
61
81
|
* call-seq:
|
62
82
|
* buffer.read_position -> Fixnum
|
@@ -64,13 +84,13 @@ void Init_bson_native()
|
|
64
84
|
* Returns the read position in the buffer.
|
65
85
|
*/
|
66
86
|
rb_define_method(rb_byte_buffer_class, "read_position", rb_bson_byte_buffer_read_position, 0);
|
67
|
-
|
87
|
+
|
68
88
|
rb_define_method(rb_byte_buffer_class, "get_byte", rb_bson_byte_buffer_get_byte, 0);
|
69
89
|
rb_define_method(rb_byte_buffer_class, "get_bytes", rb_bson_byte_buffer_get_bytes, 1);
|
70
90
|
rb_define_method(rb_byte_buffer_class, "get_cstring", rb_bson_byte_buffer_get_cstring, 0);
|
71
91
|
rb_define_method(rb_byte_buffer_class, "get_decimal128_bytes", rb_bson_byte_buffer_get_decimal128_bytes, 0);
|
72
92
|
rb_define_method(rb_byte_buffer_class, "get_double", rb_bson_byte_buffer_get_double, 0);
|
73
|
-
|
93
|
+
|
74
94
|
/*
|
75
95
|
* call-seq:
|
76
96
|
* buffer.get_hash(**options) -> Hash
|
@@ -82,23 +102,35 @@ void Init_bson_native()
|
|
82
102
|
* @return [ BSON::Document ] The decoded document.
|
83
103
|
*/
|
84
104
|
rb_define_method(rb_byte_buffer_class, "get_hash", rb_bson_byte_buffer_get_hash, -1);
|
85
|
-
|
105
|
+
|
86
106
|
/*
|
87
107
|
* call-seq:
|
88
108
|
* buffer.get_array(**options) -> Array
|
89
109
|
*
|
90
|
-
* Reads an array from the byte buffer
|
110
|
+
* Reads an array from the byte buffer.
|
91
111
|
*
|
92
112
|
* @option options [ nil | :bson ] :mode Decoding mode to use.
|
93
113
|
*
|
94
114
|
* @return [ Array ] The decoded array.
|
95
115
|
*/
|
96
116
|
rb_define_method(rb_byte_buffer_class, "get_array", rb_bson_byte_buffer_get_array, -1);
|
97
|
-
|
117
|
+
|
98
118
|
rb_define_method(rb_byte_buffer_class, "get_int32", rb_bson_byte_buffer_get_int32, 0);
|
119
|
+
|
120
|
+
/*
|
121
|
+
* call-seq:
|
122
|
+
* buffer.get_uint32(buffer) -> Fixnum
|
123
|
+
*
|
124
|
+
* Reads an unsigned 32 bit number from the byte buffer.
|
125
|
+
*
|
126
|
+
* @return [ Fixnum ] The unsigned 32 bits integer from the buffer
|
127
|
+
*
|
128
|
+
* @api private
|
129
|
+
*/
|
130
|
+
rb_define_method(rb_byte_buffer_class, "get_uint32", rb_bson_byte_buffer_get_uint32, 0);
|
99
131
|
rb_define_method(rb_byte_buffer_class, "get_int64", rb_bson_byte_buffer_get_int64, 0);
|
100
132
|
rb_define_method(rb_byte_buffer_class, "get_string", rb_bson_byte_buffer_get_string, 0);
|
101
|
-
|
133
|
+
|
102
134
|
/*
|
103
135
|
* call-seq:
|
104
136
|
* buffer.write_position -> Fixnum
|
@@ -106,7 +138,7 @@ void Init_bson_native()
|
|
106
138
|
* Returns the write position in the buffer.
|
107
139
|
*/
|
108
140
|
rb_define_method(rb_byte_buffer_class, "write_position", rb_bson_byte_buffer_write_position, 0);
|
109
|
-
|
141
|
+
|
110
142
|
/*
|
111
143
|
* call-seq:
|
112
144
|
* buffer.put_byte(binary_str) -> ByteBuffer
|
@@ -117,7 +149,7 @@ void Init_bson_native()
|
|
117
149
|
* Returns the modified +self+.
|
118
150
|
*/
|
119
151
|
rb_define_method(rb_byte_buffer_class, "put_byte", rb_bson_byte_buffer_put_byte, 1);
|
120
|
-
|
152
|
+
|
121
153
|
/*
|
122
154
|
* call-seq:
|
123
155
|
* buffer.put_bytes(binary_str) -> ByteBuffer
|
@@ -170,7 +202,7 @@ void Init_bson_native()
|
|
170
202
|
* instead on the null terminator), unlike the BSON string serialization.
|
171
203
|
*/
|
172
204
|
rb_define_method(rb_byte_buffer_class, "put_cstring", rb_bson_byte_buffer_put_cstring, 1);
|
173
|
-
|
205
|
+
|
174
206
|
/**
|
175
207
|
* call-seq:
|
176
208
|
* buffer.put_symbol(sym) -> ByteBuffer
|
@@ -188,7 +220,7 @@ void Init_bson_native()
|
|
188
220
|
* indistinguishable from a string with the same value written to the buffer.
|
189
221
|
*/
|
190
222
|
rb_define_method(rb_byte_buffer_class, "put_symbol", rb_bson_byte_buffer_put_symbol, 1);
|
191
|
-
|
223
|
+
|
192
224
|
/*
|
193
225
|
* call-seq:
|
194
226
|
* buffer.put_int32(fixnum) -> ByteBuffer
|
@@ -200,7 +232,22 @@ void Init_bson_native()
|
|
200
232
|
* Returns the modified +self+.
|
201
233
|
*/
|
202
234
|
rb_define_method(rb_byte_buffer_class, "put_int32", rb_bson_byte_buffer_put_int32, 1);
|
203
|
-
|
235
|
+
|
236
|
+
/*
|
237
|
+
* call-seq:
|
238
|
+
* buffer.put_uint32(fixnum) -> ByteBuffer
|
239
|
+
*
|
240
|
+
* Writes an unsigned 32-bit integer value to the buffer.
|
241
|
+
*
|
242
|
+
* If the argument cannot be represented in 32 bits, raises RangeError.
|
243
|
+
*
|
244
|
+
* Returns the modified +self+.
|
245
|
+
*
|
246
|
+
* @api private
|
247
|
+
*
|
248
|
+
*/
|
249
|
+
rb_define_method(rb_byte_buffer_class, "put_uint32", rb_bson_byte_buffer_put_uint32, 1);
|
250
|
+
|
204
251
|
/*
|
205
252
|
* call-seq:
|
206
253
|
* buffer.put_int64(fixnum) -> ByteBuffer
|
@@ -212,7 +259,7 @@ void Init_bson_native()
|
|
212
259
|
* Returns the modified +self+.
|
213
260
|
*/
|
214
261
|
rb_define_method(rb_byte_buffer_class, "put_int64", rb_bson_byte_buffer_put_int64, 1);
|
215
|
-
|
262
|
+
|
216
263
|
/*
|
217
264
|
* call-seq:
|
218
265
|
* buffer.put_double(double) -> ByteBuffer
|
@@ -222,7 +269,7 @@ void Init_bson_native()
|
|
222
269
|
* Returns the modified +self+.
|
223
270
|
*/
|
224
271
|
rb_define_method(rb_byte_buffer_class, "put_double", rb_bson_byte_buffer_put_double, 1);
|
225
|
-
|
272
|
+
|
226
273
|
/*
|
227
274
|
* call-seq:
|
228
275
|
* buffer.put_decimal128(low_64bit, high_64bit) -> ByteBuffer
|
@@ -235,17 +282,17 @@ void Init_bson_native()
|
|
235
282
|
* Returns the modified +self+.
|
236
283
|
*/
|
237
284
|
rb_define_method(rb_byte_buffer_class, "put_decimal128", rb_bson_byte_buffer_put_decimal128, 2);
|
238
|
-
|
285
|
+
|
239
286
|
/*
|
240
287
|
* call-seq:
|
241
|
-
* buffer.put_hash(hash) -> ByteBuffer
|
288
|
+
* buffer.put_hash(hash, validating_keys) -> ByteBuffer
|
242
289
|
*
|
243
290
|
* Writes a Hash into the byte buffer.
|
244
291
|
*
|
245
292
|
* Returns the modified +self+.
|
246
293
|
*/
|
247
294
|
rb_define_method(rb_byte_buffer_class, "put_hash", rb_bson_byte_buffer_put_hash, 2);
|
248
|
-
|
295
|
+
|
249
296
|
/*
|
250
297
|
* call-seq:
|
251
298
|
* buffer.put_array(array) -> ByteBuffer
|
@@ -255,7 +302,7 @@ void Init_bson_native()
|
|
255
302
|
* Returns the modified +self+.
|
256
303
|
*/
|
257
304
|
rb_define_method(rb_byte_buffer_class, "put_array", rb_bson_byte_buffer_put_array, 2);
|
258
|
-
|
305
|
+
|
259
306
|
/*
|
260
307
|
* call-seq:
|
261
308
|
* buffer.replace_int32(position, fixnum) -> ByteBuffer
|
@@ -272,7 +319,7 @@ void Init_bson_native()
|
|
272
319
|
* Returns the modified +self+.
|
273
320
|
*/
|
274
321
|
rb_define_method(rb_byte_buffer_class, "replace_int32", rb_bson_byte_buffer_replace_int32, 2);
|
275
|
-
|
322
|
+
|
276
323
|
/*
|
277
324
|
* call-seq:
|
278
325
|
* buffer.rewind! -> ByteBuffer
|
@@ -284,19 +331,23 @@ void Init_bson_native()
|
|
284
331
|
* Returns the modified +self+.
|
285
332
|
*/
|
286
333
|
rb_define_method(rb_byte_buffer_class, "rewind!", rb_bson_byte_buffer_rewind, 0);
|
287
|
-
|
334
|
+
|
288
335
|
/*
|
289
336
|
* call-seq:
|
290
337
|
* buffer.to_s -> String
|
291
338
|
*
|
292
339
|
* Returns the contents of the buffer as a binary string.
|
293
340
|
*
|
341
|
+
* If the buffer is used for reading, the returned contents is the data
|
342
|
+
* that was not yet read. If the buffer is used for writing, the returned
|
343
|
+
* contents is the complete data that has been written so far.
|
344
|
+
*
|
294
345
|
* Note: this method copies the buffer's contents into a newly allocated
|
295
346
|
* +String+ instance. It does not return a reference to the data stored in
|
296
347
|
* the buffer itself.
|
297
348
|
*/
|
298
349
|
rb_define_method(rb_byte_buffer_class, "to_s", rb_bson_byte_buffer_to_s, 0);
|
299
|
-
|
350
|
+
|
300
351
|
rb_define_method(rb_bson_object_id_generator_class, "next_object_id", rb_bson_object_id_generator_next, -1);
|
301
352
|
|
302
353
|
// Get the object id machine id and hash it.
|
@@ -309,4 +360,5 @@ void Init_bson_native()
|
|
309
360
|
rb_bson_object_id_counter = FIX2INT(rb_funcall(rb_mKernel, rb_intern("rand"), 1, INT2FIX(0x1000000)));
|
310
361
|
|
311
362
|
rb_bson_registry = rb_const_get(rb_bson_module, rb_intern("Registry"));
|
363
|
+
rb_gc_register_mark_object(rb_bson_registry);
|
312
364
|
}
|
data/ext/bson/read.c
CHANGED
@@ -21,6 +21,7 @@ static void pvt_raise_decode_error(volatile VALUE msg);
|
|
21
21
|
static int32_t pvt_validate_length(byte_buffer_t *b);
|
22
22
|
static uint8_t pvt_get_type_byte(byte_buffer_t *b);
|
23
23
|
static VALUE pvt_get_int32(byte_buffer_t *b);
|
24
|
+
static VALUE pvt_get_uint32(byte_buffer_t *b);
|
24
25
|
static VALUE pvt_get_int64(byte_buffer_t *b, int argc, VALUE *argv);
|
25
26
|
static VALUE pvt_get_double(byte_buffer_t *b);
|
26
27
|
static VALUE pvt_get_string(byte_buffer_t *b, const char *data_type);
|
@@ -41,12 +42,12 @@ void pvt_raise_decode_error(volatile VALUE msg) {
|
|
41
42
|
int32_t pvt_validate_length(byte_buffer_t *b)
|
42
43
|
{
|
43
44
|
int32_t length;
|
44
|
-
|
45
|
+
|
45
46
|
ENSURE_BSON_READ(b, 4);
|
46
47
|
memcpy(&length, READ_PTR(b), 4);
|
47
48
|
length = BSON_UINT32_TO_LE(length);
|
48
49
|
|
49
|
-
/* minimum valid length is 4 (byte count) + 1 (terminating byte) */
|
50
|
+
/* minimum valid length is 4 (byte count) + 1 (terminating byte) */
|
50
51
|
if(length >= 5){
|
51
52
|
ENSURE_BSON_READ(b, length);
|
52
53
|
|
@@ -59,7 +60,7 @@ int32_t pvt_validate_length(byte_buffer_t *b)
|
|
59
60
|
else{
|
60
61
|
rb_raise(rb_eRangeError, "Buffer contained invalid length %d at %zu", length, b->read_position);
|
61
62
|
}
|
62
|
-
|
63
|
+
|
63
64
|
return length;
|
64
65
|
}
|
65
66
|
|
@@ -175,13 +176,13 @@ VALUE pvt_get_string(byte_buffer_t *b, const char *data_type)
|
|
175
176
|
}
|
176
177
|
ENSURE_BSON_READ(b, 4 + length);
|
177
178
|
str_ptr = READ_PTR(b) + 4;
|
178
|
-
last_byte = *(READ_PTR(b) + 4 +
|
179
|
+
last_byte = *(READ_PTR(b) + 4 + length - 1);
|
179
180
|
if (last_byte != 0) {
|
180
181
|
pvt_raise_decode_error(rb_sprintf("Last byte of the string is not null: 0x%x", (int) last_byte));
|
181
182
|
}
|
182
183
|
rb_bson_utf8_validate(str_ptr, length - 1, true, data_type);
|
183
184
|
string = rb_enc_str_new(str_ptr, length - 1, rb_utf8_encoding());
|
184
|
-
b->read_position += 4 +
|
185
|
+
b->read_position += 4 + length;
|
185
186
|
return string;
|
186
187
|
}
|
187
188
|
|
@@ -205,7 +206,7 @@ VALUE pvt_get_symbol(byte_buffer_t *b, VALUE rb_buffer, int argc, VALUE *argv)
|
|
205
206
|
klass = rb_funcall(rb_bson_registry, rb_intern("get"), 1, INT2FIX(BSON_TYPE_SYMBOL));
|
206
207
|
value = rb_funcall(klass, rb_intern("from_bson"), 1, rb_buffer);
|
207
208
|
}
|
208
|
-
|
209
|
+
|
209
210
|
RB_GC_GUARD(klass);
|
210
211
|
return value;
|
211
212
|
}
|
@@ -259,6 +260,28 @@ VALUE pvt_get_int32(byte_buffer_t *b)
|
|
259
260
|
return INT2NUM(BSON_UINT32_FROM_LE(i32));
|
260
261
|
}
|
261
262
|
|
263
|
+
/**
|
264
|
+
* Get an unsigned int32 from the buffer.
|
265
|
+
*/
|
266
|
+
VALUE rb_bson_byte_buffer_get_uint32(VALUE self)
|
267
|
+
{
|
268
|
+
byte_buffer_t *b;
|
269
|
+
|
270
|
+
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
271
|
+
return pvt_get_uint32(b);
|
272
|
+
}
|
273
|
+
|
274
|
+
VALUE pvt_get_uint32(byte_buffer_t *b)
|
275
|
+
{
|
276
|
+
uint32_t i32;
|
277
|
+
|
278
|
+
ENSURE_BSON_READ(b, 4);
|
279
|
+
memcpy(&i32, READ_PTR(b), 4);
|
280
|
+
b->read_position += 4;
|
281
|
+
return UINT2NUM(BSON_UINT32_FROM_LE(i32));
|
282
|
+
}
|
283
|
+
|
284
|
+
|
262
285
|
/**
|
263
286
|
* Get a int64 from the buffer.
|
264
287
|
*/
|
@@ -284,7 +307,7 @@ VALUE pvt_get_int64(byte_buffer_t *b, int argc, VALUE *argv)
|
|
284
307
|
memcpy(&i64, READ_PTR(b), 8);
|
285
308
|
b->read_position += 8;
|
286
309
|
num = LL2NUM(BSON_UINT64_FROM_LE(i64));
|
287
|
-
|
310
|
+
|
288
311
|
if (pvt_get_mode_option(argc, argv) == BSON_MODE_BSON) {
|
289
312
|
VALUE klass = rb_funcall(rb_bson_registry,rb_intern("get"),1, INT2FIX(BSON_TYPE_INT64));
|
290
313
|
VALUE value = rb_funcall(klass, rb_intern("new"), 1, num);
|
@@ -293,7 +316,7 @@ VALUE pvt_get_int64(byte_buffer_t *b, int argc, VALUE *argv)
|
|
293
316
|
} else {
|
294
317
|
return num;
|
295
318
|
}
|
296
|
-
|
319
|
+
|
297
320
|
RB_GC_GUARD(num);
|
298
321
|
}
|
299
322
|
|
@@ -333,6 +356,30 @@ VALUE rb_bson_byte_buffer_get_decimal128_bytes(VALUE self)
|
|
333
356
|
return bytes;
|
334
357
|
}
|
335
358
|
|
359
|
+
/**
|
360
|
+
* This duplicates the DBRef validation code in DBRef constructor.
|
361
|
+
*/
|
362
|
+
static int pvt_is_dbref(VALUE doc) {
|
363
|
+
VALUE ref, id, db;
|
364
|
+
|
365
|
+
ref = rb_hash_aref(doc, _ref_str);
|
366
|
+
if (NIL_P(ref) || !RB_TYPE_P(ref, T_STRING)) {
|
367
|
+
return 0;
|
368
|
+
}
|
369
|
+
|
370
|
+
id = rb_hash_aref(doc, _id_str);
|
371
|
+
if (NIL_P(id)) {
|
372
|
+
return 0;
|
373
|
+
}
|
374
|
+
|
375
|
+
db = rb_hash_aref(doc, _db_str);
|
376
|
+
if (!NIL_P(db) && !RB_TYPE_P(db, T_STRING)) {
|
377
|
+
return 0;
|
378
|
+
}
|
379
|
+
|
380
|
+
return 1;
|
381
|
+
}
|
382
|
+
|
336
383
|
VALUE rb_bson_byte_buffer_get_hash(int argc, VALUE *argv, VALUE self){
|
337
384
|
VALUE doc = Qnil;
|
338
385
|
byte_buffer_t *b = NULL;
|
@@ -353,11 +400,16 @@ VALUE rb_bson_byte_buffer_get_hash(int argc, VALUE *argv, VALUE self){
|
|
353
400
|
rb_hash_aset(doc, field, pvt_read_field(b, self, type, argc, argv));
|
354
401
|
RB_GC_GUARD(field);
|
355
402
|
}
|
356
|
-
|
403
|
+
|
357
404
|
if (READ_PTR(b) - start_ptr != length) {
|
358
405
|
pvt_raise_decode_error(rb_sprintf("Expected to read %d bytes for the hash but read %ld bytes", length, READ_PTR(b) - start_ptr));
|
359
406
|
}
|
360
407
|
|
408
|
+
if (pvt_is_dbref(doc)) {
|
409
|
+
VALUE cDBRef = pvt_const_get_2("BSON", "DBRef");
|
410
|
+
doc = rb_funcall(cDBRef, rb_intern("new"), 1, doc);
|
411
|
+
}
|
412
|
+
|
361
413
|
return doc;
|
362
414
|
}
|
363
415
|
|
@@ -379,10 +431,10 @@ VALUE rb_bson_byte_buffer_get_array(int argc, VALUE *argv, VALUE self){
|
|
379
431
|
rb_ary_push(array, pvt_read_field(b, self, type, argc, argv));
|
380
432
|
}
|
381
433
|
RB_GC_GUARD(array);
|
382
|
-
|
434
|
+
|
383
435
|
if (READ_PTR(b) - start_ptr != length) {
|
384
436
|
pvt_raise_decode_error(rb_sprintf("Expected to read %d bytes for the hash but read %ld bytes", length, READ_PTR(b) - start_ptr));
|
385
437
|
}
|
386
|
-
|
438
|
+
|
387
439
|
return array;
|
388
440
|
}
|
data/ext/bson/write.c
CHANGED
@@ -27,6 +27,7 @@ static void pvt_replace_int32(byte_buffer_t *b, int32_t position, int32_t newval
|
|
27
27
|
static void pvt_put_field(byte_buffer_t *b, VALUE rb_buffer, VALUE val, VALUE validating_keys);
|
28
28
|
static void pvt_put_byte(byte_buffer_t *b, const char byte);
|
29
29
|
static void pvt_put_int32(byte_buffer_t *b, const int32_t i32);
|
30
|
+
static void pvt_put_uint32(byte_buffer_t *b, const uint32_t i32);
|
30
31
|
static void pvt_put_int64(byte_buffer_t *b, const int64_t i);
|
31
32
|
static void pvt_put_double(byte_buffer_t *b, double f);
|
32
33
|
static void pvt_put_cstring(byte_buffer_t *b, const char *str, int32_t length, const char *data_type);
|
@@ -154,8 +155,15 @@ void pvt_put_type_byte(byte_buffer_t *b, VALUE val){
|
|
154
155
|
case T_FLOAT:
|
155
156
|
type_byte = BSON_TYPE_DOUBLE;
|
156
157
|
break;
|
157
|
-
default:{
|
158
|
-
VALUE type
|
158
|
+
default: {
|
159
|
+
VALUE type;
|
160
|
+
VALUE responds = rb_funcall(val, rb_intern("respond_to?"), 1, ID2SYM(rb_intern("bson_type")));
|
161
|
+
if (!RTEST(responds)) {
|
162
|
+
VALUE klass = pvt_const_get_3("BSON", "Error", "UnserializableClass");
|
163
|
+
VALUE val_str = rb_funcall(val, rb_intern("to_s"), 0);
|
164
|
+
rb_raise(klass, "Value does not define its BSON serialized type: %s", RSTRING_PTR(val_str));
|
165
|
+
}
|
166
|
+
type = rb_funcall(val, rb_intern("bson_type"), 0);
|
159
167
|
type_byte = *RSTRING_PTR(type);
|
160
168
|
RB_GC_GUARD(type);
|
161
169
|
break;
|
@@ -383,6 +391,37 @@ void pvt_put_int32(byte_buffer_t *b, const int32_t i)
|
|
383
391
|
b->write_position += 4;
|
384
392
|
}
|
385
393
|
|
394
|
+
/* The docstring is in init.c. */
|
395
|
+
VALUE rb_bson_byte_buffer_put_uint32(VALUE self, VALUE i)
|
396
|
+
{
|
397
|
+
byte_buffer_t *b;
|
398
|
+
int64_t temp;
|
399
|
+
uint32_t i32;
|
400
|
+
|
401
|
+
if (RB_TYPE_P(i, T_FLOAT)) {
|
402
|
+
rb_raise(rb_eArgError, "put_uint32: incorrect type: float, expected: integer");
|
403
|
+
}
|
404
|
+
|
405
|
+
temp = NUM2LL(i);
|
406
|
+
if (temp < 0 || temp > UINT32_MAX) {
|
407
|
+
rb_raise(rb_eRangeError, "Number %lld is out of range [0, 2^32)", (long long)temp);
|
408
|
+
}
|
409
|
+
|
410
|
+
i32 = NUM2UINT(i);
|
411
|
+
|
412
|
+
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
413
|
+
pvt_put_uint32(b, i32);
|
414
|
+
return self;
|
415
|
+
}
|
416
|
+
|
417
|
+
void pvt_put_uint32(byte_buffer_t *b, const uint32_t i)
|
418
|
+
{
|
419
|
+
const uint32_t i32 = BSON_UINT32_TO_LE(i);
|
420
|
+
ENSURE_BSON_WRITE(b, 4);
|
421
|
+
memcpy(WRITE_PTR(b), &i32, 4);
|
422
|
+
b->write_position += 4;
|
423
|
+
}
|
424
|
+
|
386
425
|
/* The docstring is in init.c. */
|
387
426
|
VALUE rb_bson_byte_buffer_put_int64(VALUE self, VALUE i)
|
388
427
|
{
|
@@ -627,7 +666,7 @@ VALUE rb_bson_byte_buffer_put_array(VALUE self, VALUE array, VALUE validating_ke
|
|
627
666
|
|
628
667
|
for(int32_t index=0; index < RARRAY_LEN(array); index++, array_element++){
|
629
668
|
pvt_put_type_byte(b, *array_element);
|
630
|
-
pvt_put_array_index(b,index);
|
669
|
+
pvt_put_array_index(b, index);
|
631
670
|
pvt_put_field(b, self, *array_element, validating_keys);
|
632
671
|
}
|
633
672
|
pvt_put_byte(b, 0);
|
data/lib/bson/active_support.rb
CHANGED
data/lib/bson/array.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (C) 2009-2020 MongoDB Inc.
|
2
3
|
#
|
3
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -25,7 +26,7 @@ module BSON
|
|
25
26
|
# An array is type 0x04 in the BSON spec.
|
26
27
|
#
|
27
28
|
# @since 2.0.0
|
28
|
-
BSON_TYPE = 4.chr
|
29
|
+
BSON_TYPE = ::String.new(4.chr, encoding: BINARY).freeze
|
29
30
|
|
30
31
|
# Get the array as encoded BSON.
|
31
32
|
#
|
@@ -47,6 +48,9 @@ module BSON
|
|
47
48
|
position = buffer.length
|
48
49
|
buffer.put_int32(0)
|
49
50
|
each_with_index do |value, index|
|
51
|
+
unless value.respond_to?(:bson_type)
|
52
|
+
raise Error::UnserializableClass, "Array element at position #{index} does not define its BSON serialized type: #{value}"
|
53
|
+
end
|
50
54
|
buffer.put_byte(value.bson_type)
|
51
55
|
buffer.put_cstring(index.to_s)
|
52
56
|
value.to_bson(buffer, validating_keys)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright (C) 2009-2021 MongoDB Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
module BSON
|
17
|
+
|
18
|
+
# Injects behaviour for encoding and decoding BigDecimals
|
19
|
+
# to and from raw bytes as specified by the BSON spec.
|
20
|
+
#
|
21
|
+
# @see http://bsonspec.org/#/specification
|
22
|
+
module BigDecimal
|
23
|
+
|
24
|
+
# BigDecimals are serialized as Decimal128s under the hood. A Decimal128
|
25
|
+
# is type 0x13 in the BSON spec.
|
26
|
+
BSON_TYPE = ::String.new(19.chr, encoding: BINARY).freeze
|
27
|
+
|
28
|
+
# Get the BigDecimal as encoded BSON.
|
29
|
+
#
|
30
|
+
# @example Get the BigDecimal as encoded BSON.
|
31
|
+
# BigDecimal("1").to_bson
|
32
|
+
#
|
33
|
+
# @return [ BSON::ByteBuffer ] The buffer with the encoded object.
|
34
|
+
#
|
35
|
+
# @see http://bsonspec.org/#/specification
|
36
|
+
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
37
|
+
BSON::Decimal128.new(to_s).to_bson(buffer, validating_keys)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get the BSON type for BigDecimal. This is the same BSON type as
|
41
|
+
# BSON::Decimal128.
|
42
|
+
def bson_type
|
43
|
+
BSON_TYPE
|
44
|
+
end
|
45
|
+
|
46
|
+
module ClassMethods
|
47
|
+
|
48
|
+
# Deserialize the BigDecimal from raw BSON bytes.
|
49
|
+
#
|
50
|
+
# @example Get the BigDecimal from BSON.
|
51
|
+
# BigDecimal.from_bson(bson)
|
52
|
+
#
|
53
|
+
# @param [ ByteBuffer ] buffer The byte buffer.
|
54
|
+
#
|
55
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
56
|
+
#
|
57
|
+
# @return [ BigDecimal ] The decimal object.
|
58
|
+
def from_bson(buffer, **options)
|
59
|
+
Decimal128.from_bson(buffer, **options).to_big_decimal
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Enrich the core BigDecimal class with this module.
|
65
|
+
::BigDecimal.send(:include, BigDecimal)
|
66
|
+
::BigDecimal.send(:extend, BigDecimal::ClassMethods)
|
67
|
+
end
|