bson 4.7.1 → 4.9.1
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.tar.gz.sig +2 -1
- data/README.md +6 -2
- data/ext/bson/bson-endian.h +1 -1
- data/ext/bson/bson-native.h +15 -5
- data/ext/bson/bytebuf.c +1 -1
- data/ext/bson/endian.c +1 -1
- data/ext/bson/init.c +26 -3
- data/ext/bson/read.c +127 -33
- data/ext/bson/util.c +41 -1
- data/ext/bson/write.c +18 -14
- data/lib/bson.rb +4 -1
- data/lib/bson/active_support.rb +1 -1
- data/lib/bson/array.rb +34 -5
- data/lib/bson/binary.rb +42 -4
- data/lib/bson/boolean.rb +12 -3
- data/lib/bson/code.rb +16 -2
- data/lib/bson/code_with_scope.rb +32 -5
- data/lib/bson/config.rb +1 -1
- data/lib/bson/date.rb +1 -1
- data/lib/bson/date_time.rb +1 -1
- data/lib/bson/db_pointer.rb +110 -0
- data/lib/bson/decimal128.rb +16 -2
- data/lib/bson/decimal128/builder.rb +1 -1
- data/lib/bson/document.rb +1 -1
- data/lib/bson/environment.rb +2 -1
- data/lib/bson/error.rb +21 -0
- data/lib/bson/ext_json.rb +375 -0
- data/lib/bson/false_class.rb +1 -1
- data/lib/bson/float.rb +48 -2
- data/lib/bson/hash.rb +36 -5
- data/lib/bson/int32.rb +22 -2
- data/lib/bson/int64.rb +29 -4
- data/lib/bson/integer.rb +35 -1
- data/lib/bson/json.rb +1 -1
- data/lib/bson/max_key.rb +13 -1
- data/lib/bson/min_key.rb +13 -1
- data/lib/bson/nil_class.rb +4 -2
- data/lib/bson/object.rb +28 -1
- data/lib/bson/object_id.rb +16 -2
- data/lib/bson/open_struct.rb +1 -1
- data/lib/bson/regexp.rb +20 -3
- data/lib/bson/registry.rb +1 -1
- data/lib/bson/specialized.rb +4 -2
- data/lib/bson/string.rb +4 -2
- data/lib/bson/symbol.rb +93 -4
- data/lib/bson/time.rb +63 -4
- data/lib/bson/time_with_zone.rb +1 -1
- data/lib/bson/timestamp.rb +16 -2
- data/lib/bson/true_class.rb +1 -1
- data/lib/bson/undefined.rb +12 -1
- data/lib/bson/version.rb +2 -2
- data/spec/bson/array_spec.rb +1 -1
- data/spec/bson/binary_spec.rb +34 -4
- data/spec/bson/binary_uuid_spec.rb +1 -1
- data/spec/bson/boolean_spec.rb +1 -1
- data/spec/bson/code_spec.rb +1 -1
- data/spec/bson/code_with_scope_spec.rb +1 -1
- data/spec/bson/date_spec.rb +1 -1
- data/spec/bson/date_time_spec.rb +1 -1
- data/spec/bson/decimal128_spec.rb +1 -1
- data/spec/bson/document_spec.rb +1 -1
- data/spec/bson/ext_json_parse_spec.rb +308 -0
- data/spec/bson/false_class_spec.rb +1 -1
- data/spec/bson/float_spec.rb +37 -1
- data/spec/bson/hash_spec.rb +71 -1
- data/spec/bson/int32_spec.rb +21 -1
- data/spec/bson/int64_spec.rb +39 -1
- data/spec/bson/integer_spec.rb +27 -1
- data/spec/bson/json_spec.rb +1 -1
- data/spec/bson/max_key_spec.rb +1 -1
- data/spec/bson/min_key_spec.rb +1 -1
- data/spec/bson/nil_class_spec.rb +1 -1
- data/spec/bson/object_id_spec.rb +1 -1
- data/spec/bson/object_spec.rb +1 -1
- data/spec/bson/open_struct_spec.rb +1 -1
- data/spec/bson/raw_spec.rb +22 -1
- data/spec/bson/regexp_spec.rb +1 -1
- data/spec/bson/registry_spec.rb +1 -1
- data/spec/bson/string_spec.rb +1 -1
- data/spec/bson/symbol_raw_spec.rb +45 -0
- data/spec/bson/symbol_spec.rb +61 -1
- data/spec/bson/time_spec.rb +205 -2
- data/spec/bson/time_with_zone_spec.rb +1 -1
- data/spec/bson/timestamp_spec.rb +1 -1
- data/spec/bson/true_class_spec.rb +1 -1
- data/spec/bson/undefined_spec.rb +1 -1
- data/spec/bson_spec.rb +1 -1
- data/spec/{support → runners}/common_driver.rb +1 -1
- data/spec/runners/corpus.rb +185 -0
- data/spec/{support/corpus.rb → runners/corpus_legacy.rb} +41 -59
- data/spec/spec_helper.rb +10 -3
- 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 +236 -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
- data/spec/support/shared_examples.rb +1 -1
- metadata +176 -102
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f828ac65b41cef0a3f73a37a22321ece1da8a034d522e275edf8ef1ff3c45116
|
4
|
+
data.tar.gz: '09028f28079bf6a6917972792457b639ef66014f536174e5dc229f768cfbdab6'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1d84a40c313f946bc11ac931fef2db76c5364ee250d01f06e04053aec8d7a79f5f8207eebcd462409f430e6813094544f00f88e83f2609530a67da5dc25449a
|
7
|
+
data.tar.gz: c454d6c47fb86cd9f64e9f59ef6030e16b2de30dd0a441bff3e3dc9487feeb7ec10b997ead6793811bc65f636412f7a1b6d70bb2577847c3920f57182802f7d8
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
,�P���$��l6��F��S����&�m�
|
2
|
+
���û��h���YX�np<������л"�z���]2�k�!)��qc#�8&"���2
|
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.
|
@@ -34,7 +38,7 @@ As of 2.0.0, this project adheres to the
|
|
34
38
|
License
|
35
39
|
-------
|
36
40
|
|
37
|
-
Copyright (C) 2009-
|
41
|
+
Copyright (C) 2009-2020 MongoDB Inc.
|
38
42
|
|
39
43
|
Licensed under the Apache License, Version 2.0 (the "License");
|
40
44
|
you may not use this file except in compliance with the License.
|
data/ext/bson/bson-endian.h
CHANGED
data/ext/bson/bson-native.h
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (C) 2009-
|
2
|
+
* Copyright (C) 2009-2020 MongoDB Inc.
|
3
3
|
*
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
* you may not use this file except in compliance with the License.
|
@@ -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/bytebuf.c
CHANGED
data/ext/bson/endian.c
CHANGED
data/ext/bson/init.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (C) 2009-
|
2
|
+
* Copyright (C) 2009-2020 MongoDB Inc.
|
3
3
|
*
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
* you may not use this file except in compliance with the License.
|
@@ -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
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (C) 2009-
|
2
|
+
* Copyright (C) 2009-2020 MongoDB Inc.
|
3
3
|
*
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
* you may not use this file except in compliance with the License.
|
@@ -17,21 +17,28 @@
|
|
17
17
|
#include "bson-native.h"
|
18
18
|
#include <ruby/encoding.h>
|
19
19
|
|
20
|
-
static void
|
20
|
+
static void pvt_raise_decode_error(volatile VALUE msg);
|
21
|
+
static int32_t pvt_validate_length(byte_buffer_t *b);
|
21
22
|
static uint8_t pvt_get_type_byte(byte_buffer_t *b);
|
22
23
|
static VALUE pvt_get_int32(byte_buffer_t *b);
|
23
|
-
static VALUE pvt_get_int64(byte_buffer_t *b);
|
24
|
+
static VALUE pvt_get_int64(byte_buffer_t *b, int argc, VALUE *argv);
|
24
25
|
static VALUE pvt_get_double(byte_buffer_t *b);
|
25
|
-
static VALUE pvt_get_string(byte_buffer_t *b);
|
26
|
+
static VALUE pvt_get_string(byte_buffer_t *b, const char *data_type);
|
27
|
+
static VALUE pvt_get_symbol(byte_buffer_t *b, VALUE rb_buffer, int argc, VALUE *argv);
|
26
28
|
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);
|
29
|
+
static VALUE pvt_read_field(byte_buffer_t *b, VALUE rb_buffer, uint8_t type, int argc, VALUE *argv);
|
28
30
|
static void pvt_skip_cstring(byte_buffer_t *b);
|
29
31
|
|
32
|
+
void pvt_raise_decode_error(volatile VALUE msg) {
|
33
|
+
VALUE klass = pvt_const_get_3("BSON", "Error", "BSONDecodeError");
|
34
|
+
rb_exc_raise(rb_exc_new_str(klass, msg));
|
35
|
+
}
|
36
|
+
|
30
37
|
/**
|
31
38
|
* validate the buffer contains the amount of bytes the array / hash claimns
|
32
39
|
* and that it is null terminated
|
33
40
|
*/
|
34
|
-
|
41
|
+
int32_t pvt_validate_length(byte_buffer_t *b)
|
35
42
|
{
|
36
43
|
int32_t length;
|
37
44
|
|
@@ -52,19 +59,23 @@ void pvt_validate_length(byte_buffer_t *b)
|
|
52
59
|
else{
|
53
60
|
rb_raise(rb_eRangeError, "Buffer contained invalid length %d at %zu", length, b->read_position);
|
54
61
|
}
|
62
|
+
|
63
|
+
return length;
|
55
64
|
}
|
56
65
|
|
57
66
|
/**
|
58
67
|
* Read a single field from a hash or array
|
59
68
|
*/
|
60
|
-
VALUE pvt_read_field(byte_buffer_t *b, VALUE rb_buffer, uint8_t type)
|
69
|
+
VALUE pvt_read_field(byte_buffer_t *b, VALUE rb_buffer, uint8_t type, int argc, VALUE *argv)
|
70
|
+
{
|
61
71
|
switch(type) {
|
62
72
|
case BSON_TYPE_INT32: return pvt_get_int32(b);
|
63
|
-
case BSON_TYPE_INT64: return pvt_get_int64(b);
|
73
|
+
case BSON_TYPE_INT64: return pvt_get_int64(b, argc, argv);
|
64
74
|
case BSON_TYPE_DOUBLE: return pvt_get_double(b);
|
65
|
-
case BSON_TYPE_STRING: return pvt_get_string(b);
|
66
|
-
case
|
67
|
-
case
|
75
|
+
case BSON_TYPE_STRING: return pvt_get_string(b, "String");
|
76
|
+
case BSON_TYPE_SYMBOL: return pvt_get_symbol(b, rb_buffer, argc, argv);
|
77
|
+
case BSON_TYPE_ARRAY: return rb_bson_byte_buffer_get_array(argc, argv, rb_buffer);
|
78
|
+
case BSON_TYPE_DOCUMENT: return rb_bson_byte_buffer_get_hash(argc, argv, rb_buffer);
|
68
79
|
case BSON_TYPE_BOOLEAN: return pvt_get_boolean(b);
|
69
80
|
default:
|
70
81
|
{
|
@@ -116,9 +127,20 @@ VALUE rb_bson_byte_buffer_get_bytes(VALUE self, VALUE i)
|
|
116
127
|
}
|
117
128
|
|
118
129
|
VALUE pvt_get_boolean(byte_buffer_t *b){
|
119
|
-
VALUE result
|
130
|
+
VALUE result;
|
131
|
+
char byte_value;
|
120
132
|
ENSURE_BSON_READ(b, 1);
|
121
|
-
|
133
|
+
byte_value = *READ_PTR(b);
|
134
|
+
switch (byte_value) {
|
135
|
+
case 1:
|
136
|
+
result = Qtrue;
|
137
|
+
break;
|
138
|
+
case 0:
|
139
|
+
result = Qfalse;
|
140
|
+
break;
|
141
|
+
default:
|
142
|
+
pvt_raise_decode_error(rb_sprintf("Invalid boolean byte value: %d", (int) byte_value));
|
143
|
+
}
|
122
144
|
b->read_position += 1;
|
123
145
|
return result;
|
124
146
|
}
|
@@ -131,25 +153,63 @@ VALUE rb_bson_byte_buffer_get_string(VALUE self)
|
|
131
153
|
byte_buffer_t *b;
|
132
154
|
|
133
155
|
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
134
|
-
return pvt_get_string(b);
|
156
|
+
return pvt_get_string(b, "String");
|
135
157
|
}
|
136
158
|
|
137
|
-
VALUE pvt_get_string(byte_buffer_t *b)
|
159
|
+
VALUE pvt_get_string(byte_buffer_t *b, const char *data_type)
|
138
160
|
{
|
139
|
-
int32_t length;
|
140
161
|
int32_t length_le;
|
162
|
+
int32_t length;
|
163
|
+
char *str_ptr;
|
141
164
|
VALUE string;
|
165
|
+
unsigned char last_byte;
|
142
166
|
|
143
167
|
ENSURE_BSON_READ(b, 4);
|
144
|
-
memcpy(&
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
168
|
+
memcpy(&length_le, READ_PTR(b), 4);
|
169
|
+
length = BSON_UINT32_FROM_LE(length_le);
|
170
|
+
if (length < 0) {
|
171
|
+
pvt_raise_decode_error(rb_sprintf("String length is negative: %d", length));
|
172
|
+
}
|
173
|
+
if (length == 0) {
|
174
|
+
pvt_raise_decode_error(rb_str_new_cstr("String length is zero but string must be null-terminated"));
|
175
|
+
}
|
176
|
+
ENSURE_BSON_READ(b, 4 + length);
|
177
|
+
str_ptr = READ_PTR(b) + 4;
|
178
|
+
last_byte = *(READ_PTR(b) + 4 + length_le - 1);
|
179
|
+
if (last_byte != 0) {
|
180
|
+
pvt_raise_decode_error(rb_sprintf("Last byte of the string is not null: 0x%x", (int) last_byte));
|
181
|
+
}
|
182
|
+
rb_bson_utf8_validate(str_ptr, length - 1, true, data_type);
|
183
|
+
string = rb_enc_str_new(str_ptr, length - 1, rb_utf8_encoding());
|
184
|
+
b->read_position += 4 + length_le;
|
150
185
|
return string;
|
151
186
|
}
|
152
187
|
|
188
|
+
/**
|
189
|
+
* Reads a UTF-8 string out of the byte buffer. If the argc/argv arguments
|
190
|
+
* have a :mode option with the value of :bson, wraps the string in a
|
191
|
+
* BSON::Symbol::Raw. Otherwise consults the BSON registry to determine
|
192
|
+
* which class to instantiate (String in bson-ruby, overridden to Symbol by
|
193
|
+
* the Ruby driver). Returns either a BSON::Symbol::Raw, Symbol or String
|
194
|
+
* value.
|
195
|
+
*/
|
196
|
+
VALUE pvt_get_symbol(byte_buffer_t *b, VALUE rb_buffer, int argc, VALUE *argv)
|
197
|
+
{
|
198
|
+
VALUE value, klass;
|
199
|
+
|
200
|
+
if (pvt_get_mode_option(argc, argv) == BSON_MODE_BSON) {
|
201
|
+
value = pvt_get_string(b, "Symbol");
|
202
|
+
klass = pvt_const_get_3("BSON", "Symbol", "Raw");
|
203
|
+
value = rb_funcall(klass, rb_intern("new"), 1, value);
|
204
|
+
} else {
|
205
|
+
klass = rb_funcall(rb_bson_registry, rb_intern("get"), 1, INT2FIX(BSON_TYPE_SYMBOL));
|
206
|
+
value = rb_funcall(klass, rb_intern("from_bson"), 1, rb_buffer);
|
207
|
+
}
|
208
|
+
|
209
|
+
RB_GC_GUARD(klass);
|
210
|
+
return value;
|
211
|
+
}
|
212
|
+
|
153
213
|
/**
|
154
214
|
* Get a cstring from the buffer.
|
155
215
|
*/
|
@@ -206,17 +266,35 @@ VALUE rb_bson_byte_buffer_get_int64(VALUE self)
|
|
206
266
|
{
|
207
267
|
byte_buffer_t *b;
|
208
268
|
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
209
|
-
return pvt_get_int64(b);
|
269
|
+
return pvt_get_int64(b, 0, NULL);
|
210
270
|
}
|
211
271
|
|
212
|
-
|
272
|
+
/**
|
273
|
+
* Reads a 64-bit integer out of the byte buffer into a Ruby Integer instance.
|
274
|
+
* If the argc/argv arguments have a :mode option with the value of :bson,
|
275
|
+
* wraps the integer in a BSON::Int64. Returns either the Integer or the
|
276
|
+
* BSON::Int64 instance.
|
277
|
+
*/
|
278
|
+
VALUE pvt_get_int64(byte_buffer_t *b, int argc, VALUE *argv)
|
213
279
|
{
|
214
280
|
int64_t i64;
|
281
|
+
VALUE num;
|
215
282
|
|
216
283
|
ENSURE_BSON_READ(b, 8);
|
217
284
|
memcpy(&i64, READ_PTR(b), 8);
|
218
285
|
b->read_position += 8;
|
219
|
-
|
286
|
+
num = LL2NUM(BSON_UINT64_FROM_LE(i64));
|
287
|
+
|
288
|
+
if (pvt_get_mode_option(argc, argv) == BSON_MODE_BSON) {
|
289
|
+
VALUE klass = rb_funcall(rb_bson_registry,rb_intern("get"),1, INT2FIX(BSON_TYPE_INT64));
|
290
|
+
VALUE value = rb_funcall(klass, rb_intern("new"), 1, num);
|
291
|
+
RB_GC_GUARD(klass);
|
292
|
+
return value;
|
293
|
+
} else {
|
294
|
+
return num;
|
295
|
+
}
|
296
|
+
|
297
|
+
RB_GC_GUARD(num);
|
220
298
|
}
|
221
299
|
|
222
300
|
/**
|
@@ -255,40 +333,56 @@ VALUE rb_bson_byte_buffer_get_decimal128_bytes(VALUE self)
|
|
255
333
|
return bytes;
|
256
334
|
}
|
257
335
|
|
258
|
-
VALUE rb_bson_byte_buffer_get_hash(VALUE self){
|
336
|
+
VALUE rb_bson_byte_buffer_get_hash(int argc, VALUE *argv, VALUE self){
|
259
337
|
VALUE doc = Qnil;
|
260
338
|
byte_buffer_t *b = NULL;
|
261
339
|
uint8_t type;
|
262
|
-
VALUE cDocument =
|
340
|
+
VALUE cDocument = pvt_const_get_2("BSON", "Document");
|
341
|
+
int32_t length;
|
342
|
+
char *start_ptr;
|
263
343
|
|
264
344
|
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
265
345
|
|
266
|
-
|
346
|
+
start_ptr = READ_PTR(b);
|
347
|
+
length = pvt_validate_length(b);
|
267
348
|
|
268
|
-
doc = rb_funcall(cDocument, rb_intern("allocate"),0);
|
349
|
+
doc = rb_funcall(cDocument, rb_intern("allocate"), 0);
|
269
350
|
|
270
351
|
while((type = pvt_get_type_byte(b)) != 0){
|
271
352
|
VALUE field = rb_bson_byte_buffer_get_cstring(self);
|
353
|
+
rb_hash_aset(doc, field, pvt_read_field(b, self, type, argc, argv));
|
272
354
|
RB_GC_GUARD(field);
|
273
|
-
rb_hash_aset(doc, field, pvt_read_field(b, self, type));
|
274
355
|
}
|
356
|
+
|
357
|
+
if (READ_PTR(b) - start_ptr != length) {
|
358
|
+
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
|
+
}
|
360
|
+
|
275
361
|
return doc;
|
276
362
|
}
|
277
363
|
|
278
|
-
VALUE rb_bson_byte_buffer_get_array(VALUE self){
|
364
|
+
VALUE rb_bson_byte_buffer_get_array(int argc, VALUE *argv, VALUE self){
|
279
365
|
byte_buffer_t *b;
|
280
366
|
VALUE array = Qnil;
|
281
367
|
uint8_t type;
|
368
|
+
int32_t length;
|
369
|
+
char *start_ptr;
|
282
370
|
|
283
371
|
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
284
372
|
|
285
|
-
|
373
|
+
start_ptr = READ_PTR(b);
|
374
|
+
length = pvt_validate_length(b);
|
286
375
|
|
287
376
|
array = rb_ary_new();
|
288
377
|
while((type = pvt_get_type_byte(b)) != 0){
|
289
378
|
pvt_skip_cstring(b);
|
290
|
-
rb_ary_push(array, pvt_read_field(b, self, type));
|
379
|
+
rb_ary_push(array, pvt_read_field(b, self, type, argc, argv));
|
291
380
|
}
|
292
381
|
RB_GC_GUARD(array);
|
382
|
+
|
383
|
+
if (READ_PTR(b) - start_ptr != length) {
|
384
|
+
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
|
+
}
|
386
|
+
|
293
387
|
return array;
|
294
388
|
}
|
data/ext/bson/util.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (C) 2009-
|
2
|
+
* Copyright (C) 2009-2020 MongoDB Inc.
|
3
3
|
*
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
* you may not use this file except in compliance with the License.
|
@@ -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
|
+
}
|