bson 4.9.0 → 4.15.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 +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
|