bson 4.2.2 → 4.12.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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +25 -7
- data/Rakefile +16 -9
- data/ext/bson/{native-endian.h → bson-endian.h} +5 -99
- data/ext/bson/bson-native.h +125 -0
- data/ext/bson/bytebuf.c +133 -0
- data/ext/bson/endian.c +117 -0
- data/ext/bson/init.c +355 -0
- data/ext/bson/libbson-utf8.c +230 -0
- data/ext/bson/read.c +411 -0
- data/ext/bson/util.c +95 -0
- data/ext/bson/write.c +680 -0
- data/lib/bson.rb +6 -3
- data/lib/bson/active_support.rb +17 -0
- data/lib/bson/array.rb +57 -17
- data/lib/bson/binary.rb +185 -13
- 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 +12 -2
- data/lib/bson/date_time.rb +2 -2
- data/lib/bson/db_pointer.rb +110 -0
- data/lib/bson/decimal128.rb +17 -3
- data/lib/bson/decimal128/builder.rb +1 -1
- data/lib/bson/document.rb +152 -5
- data/lib/bson/environment.rb +2 -1
- data/lib/bson/error.rb +27 -0
- data/lib/bson/ext_json.rb +383 -0
- data/lib/bson/false_class.rb +1 -1
- data/lib/bson/float.rb +48 -2
- data/lib/bson/hash.rb +68 -17
- data/lib/bson/int32.rb +52 -13
- data/lib/bson/int64.rb +59 -15
- data/lib/bson/integer.rb +36 -2
- 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 +27 -4
- data/lib/bson/registry.rb +3 -3
- data/lib/bson/specialized.rb +4 -2
- data/lib/bson/string.rb +5 -3
- data/lib/bson/symbol.rb +99 -7
- data/lib/bson/time.rb +63 -4
- data/lib/bson/time_with_zone.rb +54 -0
- data/lib/bson/timestamp.rb +44 -6
- 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 +18 -1
- data/spec/bson/binary_spec.rb +100 -3
- data/spec/bson/binary_uuid_spec.rb +189 -0
- data/spec/bson/boolean_spec.rb +1 -1
- data/spec/bson/byte_buffer_read_spec.rb +197 -0
- data/spec/bson/byte_buffer_spec.rb +121 -381
- data/spec/bson/byte_buffer_write_spec.rb +854 -0
- 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 +54 -1
- data/spec/bson/decimal128_spec.rb +35 -35
- data/spec/bson/document_as_spec.rb +46 -0
- data/spec/bson/document_spec.rb +197 -30
- 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_as_spec.rb +57 -0
- data/spec/bson/hash_spec.rb +209 -1
- data/spec/bson/int32_spec.rb +180 -6
- data/spec/bson/int64_spec.rb +199 -6
- data/spec/bson/integer_spec.rb +29 -3
- 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 +34 -2
- data/spec/bson/regexp_spec.rb +1 -1
- data/spec/bson/registry_spec.rb +1 -1
- data/spec/bson/string_spec.rb +19 -1
- data/spec/bson/symbol_raw_spec.rb +45 -0
- data/spec/bson/symbol_spec.rb +63 -3
- data/spec/bson/time_spec.rb +205 -2
- data/spec/bson/time_with_zone_spec.rb +68 -0
- data/spec/bson/timestamp_spec.rb +56 -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 +40 -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} +10 -7
- 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 +113 -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 +34 -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 +8 -2
- 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 +3 -5
- data/spec/support/spec_config.rb +16 -0
- data/spec/support/utils.rb +10 -0
- metadata +227 -124
- metadata.gz.sig +0 -0
- data/ext/bson/bson_native.c +0 -762
data/lib/bson.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
1
|
+
# Copyright (C) 2009-2020 MongoDB Inc.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -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"
|
@@ -101,7 +104,7 @@ begin
|
|
101
104
|
else
|
102
105
|
require "bson_native"
|
103
106
|
end
|
104
|
-
rescue LoadError
|
105
|
-
$stderr.puts("Failed to load the necessary extensions.")
|
107
|
+
rescue LoadError => e
|
108
|
+
$stderr.puts("Failed to load the necessary extensions: #{e.class}: #{e}")
|
106
109
|
raise
|
107
110
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Copyright (C) 2018-2020 MongoDB Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
# Require this file if using BSON with ActiveSupport.
|
16
|
+
|
17
|
+
require "bson/time_with_zone"
|
data/lib/bson/array.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
1
|
+
# Copyright (C) 2009-2020 MongoDB Inc.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -41,15 +41,22 @@ module BSON
|
|
41
41
|
#
|
42
42
|
# @since 2.0.0
|
43
43
|
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
buffer.
|
48
|
-
buffer.
|
49
|
-
value
|
44
|
+
if buffer.respond_to?(:put_array)
|
45
|
+
buffer.put_array(self, validating_keys)
|
46
|
+
else
|
47
|
+
position = buffer.length
|
48
|
+
buffer.put_int32(0)
|
49
|
+
each_with_index do |value, index|
|
50
|
+
unless value.respond_to?(:bson_type)
|
51
|
+
raise Error::UnserializableClass, "Array element at position #{index} does not define its BSON serialized type: #{value}"
|
52
|
+
end
|
53
|
+
buffer.put_byte(value.bson_type)
|
54
|
+
buffer.put_cstring(index.to_s)
|
55
|
+
value.to_bson(buffer, validating_keys)
|
56
|
+
end
|
57
|
+
buffer.put_byte(NULL_BYTE)
|
58
|
+
buffer.replace_int32(position, buffer.length - position)
|
50
59
|
end
|
51
|
-
buffer.put_byte(NULL_BYTE)
|
52
|
-
buffer.replace_int32(position, buffer.length - position)
|
53
60
|
end
|
54
61
|
|
55
62
|
# Convert the array to an object id. This will only work for arrays of size
|
@@ -60,7 +67,7 @@ module BSON
|
|
60
67
|
#
|
61
68
|
# @note This is used for repairing legacy bson data.
|
62
69
|
#
|
63
|
-
# @raise [
|
70
|
+
# @raise [ BSON::ObjectId::Invalid ] If the array is not 12 elements.
|
64
71
|
#
|
65
72
|
# @return [ String ] The raw object id bytes.
|
66
73
|
#
|
@@ -81,25 +88,58 @@ module BSON
|
|
81
88
|
map { |value| value.to_bson_normalized_value }
|
82
89
|
end
|
83
90
|
|
91
|
+
# Converts this object to a representation directly serializable to
|
92
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
93
|
+
#
|
94
|
+
# This method recursively invokes +as_extended_json+ with the provided
|
95
|
+
# options on each array element.
|
96
|
+
#
|
97
|
+
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
98
|
+
# (default is canonical extended JSON)
|
99
|
+
#
|
100
|
+
# @return [ Array ] This array converted to extended json representation.
|
101
|
+
def as_extended_json(**options)
|
102
|
+
map do |item|
|
103
|
+
item.as_extended_json(**options)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
84
107
|
module ClassMethods
|
85
108
|
|
86
109
|
# Deserialize the array from BSON.
|
87
110
|
#
|
88
111
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
89
112
|
#
|
113
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
114
|
+
#
|
90
115
|
# @return [ Array ] The decoded array.
|
91
116
|
#
|
92
117
|
# @see http://bsonspec.org/#/specification
|
93
118
|
#
|
94
119
|
# @since 2.0.0
|
95
|
-
def from_bson(buffer)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
120
|
+
def from_bson(buffer, **options)
|
121
|
+
if buffer.respond_to?(:get_array)
|
122
|
+
buffer.get_array(**options)
|
123
|
+
else
|
124
|
+
array = new
|
125
|
+
start_position = buffer.read_position
|
126
|
+
expected_byte_size = buffer.get_int32
|
127
|
+
while (type = buffer.get_byte) != NULL_BYTE
|
128
|
+
buffer.get_cstring
|
129
|
+
cls = BSON::Registry.get(type)
|
130
|
+
value = if options.empty?
|
131
|
+
cls.from_bson(buffer)
|
132
|
+
else
|
133
|
+
cls.from_bson(buffer, **options)
|
134
|
+
end
|
135
|
+
array << value
|
136
|
+
end
|
137
|
+
actual_byte_size = buffer.read_position - start_position
|
138
|
+
if actual_byte_size != expected_byte_size
|
139
|
+
raise Error::BSONDecodeError, "Expected array to take #{expected_byte_size} bytes but it took #{actual_byte_size} bytes"
|
140
|
+
end
|
141
|
+
array
|
101
142
|
end
|
102
|
-
array
|
103
143
|
end
|
104
144
|
end
|
105
145
|
|
data/lib/bson/binary.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
1
|
+
# Copyright (C) 2009-2020 MongoDB Inc.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -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
|
|
@@ -47,13 +54,17 @@ module BSON
|
|
47
54
|
# @since 2.0.0
|
48
55
|
TYPES = SUBTYPES.invert.freeze
|
49
56
|
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
|
56
|
-
|
57
|
+
# @return [ String ] The raw binary data.
|
58
|
+
#
|
59
|
+
# The string is always stored in BINARY encoding.
|
60
|
+
#
|
61
|
+
# @since 2.0.0
|
62
|
+
attr_reader :data
|
63
|
+
|
64
|
+
# @return [ Symbol ] The binary type.
|
65
|
+
#
|
66
|
+
# @since 2.0.0
|
67
|
+
attr_reader :type
|
57
68
|
|
58
69
|
# Determine if this binary object is equal to another object.
|
59
70
|
#
|
@@ -90,21 +101,61 @@ module BSON
|
|
90
101
|
# @return [ Hash ] The binary as a JSON hash.
|
91
102
|
#
|
92
103
|
# @since 2.0.0
|
104
|
+
# @deprecated Use as_extended_json instead.
|
93
105
|
def as_json(*args)
|
94
|
-
|
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
|
95
129
|
end
|
96
130
|
|
97
131
|
# Instantiate the new binary object.
|
98
132
|
#
|
133
|
+
# This method accepts a string in any encoding; however, if a string is
|
134
|
+
# of a non-BINARY encoding, the encoding is set to BINARY. This does not
|
135
|
+
# change the bytes of the string but it means that applications referencing
|
136
|
+
# the data of a Binary instance cannot assume it is in a non-binary
|
137
|
+
# encoding, even if the string given to the constructor was in such an
|
138
|
+
# encoding.
|
139
|
+
#
|
99
140
|
# @example Instantiate a binary.
|
100
141
|
# BSON::Binary.new(data, :md5)
|
101
142
|
#
|
102
|
-
# @param [
|
143
|
+
# @param [ String ] data The raw binary data.
|
103
144
|
# @param [ Symbol ] type The binary type.
|
104
145
|
#
|
105
146
|
# @since 2.0.0
|
106
147
|
def initialize(data = "", type = :generic)
|
107
148
|
validate_type!(type)
|
149
|
+
|
150
|
+
# The Binary class used to force encoding to BINARY when serializing to
|
151
|
+
# BSON. Instead of doing that during serialization, perform this
|
152
|
+
# operation during Binary construction to make it clear that once
|
153
|
+
# the string is given to the Binary, the data is treated as a binary
|
154
|
+
# string and not a text string in any encoding.
|
155
|
+
unless data.encoding == Encoding.find('BINARY')
|
156
|
+
data = data.dup.force_encoding('BINARY')
|
157
|
+
end
|
158
|
+
|
108
159
|
@data = data
|
109
160
|
@type = type
|
110
161
|
end
|
@@ -121,6 +172,70 @@ module BSON
|
|
121
172
|
"<BSON::Binary:0x#{object_id} type=#{type} data=0x#{data[0, 8].unpack('H*').first}...>"
|
122
173
|
end
|
123
174
|
|
175
|
+
# Returns a string representation of the UUID stored in this Binary.
|
176
|
+
#
|
177
|
+
# If the Binary is of subtype 4 (:uuid), this method returns the UUID
|
178
|
+
# in RFC 4122 format. If the representation parameter is provided, it
|
179
|
+
# must be the value :standard as a symbol or a string.
|
180
|
+
#
|
181
|
+
# If the Binary is of subtype 3 (:uuid_old), this method requires that
|
182
|
+
# the representation parameter is provided and is one of :csharp_legacy,
|
183
|
+
# :java_legacy or :python_legacy or the equivalent strings. In this case
|
184
|
+
# the method assumes the Binary stores the UUID in the specified format,
|
185
|
+
# transforms the stored bytes to the standard RFC 4122 representation
|
186
|
+
# and returns the UUID in RFC 4122 format.
|
187
|
+
#
|
188
|
+
# If the Binary is of another subtype, this method raises TypeError.
|
189
|
+
#
|
190
|
+
# @param [ Symbol ] representation How to interpret the UUID.
|
191
|
+
#
|
192
|
+
# @return [ String ] The string representation of the UUID.
|
193
|
+
#
|
194
|
+
# @raise [ TypeError ] If the subtype of Binary is not :uuid nor :uuid_old.
|
195
|
+
# @raise [ ArgumentError ] If the representation other than :standard
|
196
|
+
# is requested for Binary subtype 4 (:uuid), if :standard representation
|
197
|
+
# is requested for Binary subtype 3 (:uuid_old), or if an invalid
|
198
|
+
# representation is requested.
|
199
|
+
#
|
200
|
+
# @api experimental
|
201
|
+
def to_uuid(representation = nil)
|
202
|
+
if representation.is_a?(String)
|
203
|
+
raise ArgumentError, "Representation must be given as a symbol: #{representation}"
|
204
|
+
end
|
205
|
+
case type
|
206
|
+
when :uuid
|
207
|
+
if representation && representation != :standard
|
208
|
+
raise ArgumentError, "Binary of type :uuid can only be stringified to :standard representation, requested: #{representation.inspect}"
|
209
|
+
end
|
210
|
+
|
211
|
+
data.split('').map { |n| '%02x' % n.ord }.join.sub(/\A(.{8})(.{4})(.{4})(.{4})(.{12})\z/, '\1-\2-\3-\4-\5')
|
212
|
+
when :uuid_old
|
213
|
+
if representation.nil?
|
214
|
+
raise ArgumentError, 'Representation must be specified for BSON::Binary objects of type :uuid_old'
|
215
|
+
end
|
216
|
+
|
217
|
+
hex = data.split('').map { |n| '%02x' % n.ord }.join
|
218
|
+
|
219
|
+
case representation
|
220
|
+
when :standard
|
221
|
+
raise ArgumentError, 'BSON::Binary objects of type :uuid_old cannot be stringified to :standard representation'
|
222
|
+
when :csharp_legacy
|
223
|
+
hex.sub(/\A(..)(..)(..)(..)(..)(..)(..)(..)(.{16})\z/, '\4\3\2\1\6\5\8\7\9')
|
224
|
+
when :java_legacy
|
225
|
+
hex.sub(/\A(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)\z/) do |m|
|
226
|
+
"#{$8}#{$7}#{$6}#{$5}#{$4}#{$3}#{$2}#{$1}" +
|
227
|
+
"#{$16}#{$15}#{$14}#{$13}#{$12}#{$11}#{$10}#{$9}"
|
228
|
+
end
|
229
|
+
when :python_legacy
|
230
|
+
hex
|
231
|
+
else
|
232
|
+
raise ArgumentError, "Invalid representation: #{representation}"
|
233
|
+
end.sub(/\A(.{8})(.{4})(.{4})(.{4})(.{12})\z/, '\1-\2-\3-\4-\5')
|
234
|
+
else
|
235
|
+
raise TypeError, "The type of Binary must be :uuid or :uuid_old, this object is: #{type.inspect}"
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
124
239
|
# Encode the binary type
|
125
240
|
#
|
126
241
|
# @example Encode the binary.
|
@@ -136,7 +251,7 @@ module BSON
|
|
136
251
|
buffer.put_int32(0)
|
137
252
|
buffer.put_byte(SUBTYPES[type])
|
138
253
|
buffer.put_int32(data.bytesize) if type == :old
|
139
|
-
buffer.put_bytes(data
|
254
|
+
buffer.put_bytes(data)
|
140
255
|
buffer.replace_int32(position, buffer.length - position - 5)
|
141
256
|
end
|
142
257
|
|
@@ -144,19 +259,76 @@ module BSON
|
|
144
259
|
#
|
145
260
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
146
261
|
#
|
262
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
263
|
+
#
|
147
264
|
# @return [ Binary ] The decoded binary data.
|
148
265
|
#
|
149
266
|
# @see http://bsonspec.org/#/specification
|
150
267
|
#
|
151
268
|
# @since 2.0.0
|
152
|
-
def self.from_bson(buffer)
|
269
|
+
def self.from_bson(buffer, **options)
|
153
270
|
length = buffer.get_int32
|
154
|
-
|
271
|
+
type_byte = buffer.get_byte
|
272
|
+
type = TYPES[type_byte]
|
273
|
+
if type.nil?
|
274
|
+
raise Error::UnsupportedBinarySubtype,
|
275
|
+
"BSON data contains unsupported binary subtype #{'0x%02x' % type_byte.ord}"
|
276
|
+
end
|
277
|
+
|
155
278
|
length = buffer.get_int32 if type == :old
|
156
279
|
data = buffer.get_bytes(length)
|
157
280
|
new(data, type)
|
158
281
|
end
|
159
282
|
|
283
|
+
# Creates a BSON::Binary from a string representation of a UUID.
|
284
|
+
#
|
285
|
+
# The UUID may be given in either 00112233-4455-6677-8899-aabbccddeeff or
|
286
|
+
# 00112233445566778899AABBCCDDEEFF format - specifically, any dashes in
|
287
|
+
# the UUID are removed and both upper and lower case letters are acceptable.
|
288
|
+
#
|
289
|
+
# The input UUID string is always interpreted to be in the RFC 4122 format.
|
290
|
+
#
|
291
|
+
# If representation is not provided, this method creates a BSON::Binary
|
292
|
+
# of subtype 4 (:uuid). If representation is provided, it must be one of
|
293
|
+
# :standard, :csharp_legacy, :java_legacy or :python_legacy. If
|
294
|
+
# representation is :standard, this method creates a subtype 4 (:uuid)
|
295
|
+
# binary which is the same behavior as if representation was not provided.
|
296
|
+
# For other representations, this method creates a Binary of subtype 3
|
297
|
+
# (:uuid_old) with the UUID converted to the appropriate legacy MongoDB
|
298
|
+
# UUID storage format.
|
299
|
+
#
|
300
|
+
# @param [ String ] uuid The string representation of the UUID.
|
301
|
+
# @param [ Symbol ] representation How to interpret the UUID.
|
302
|
+
#
|
303
|
+
# @return [ Binary ] The binary.
|
304
|
+
#
|
305
|
+
# @raise [ ArgumentError ] If invalid representation is requested.
|
306
|
+
#
|
307
|
+
# @api experimental
|
308
|
+
def self.from_uuid(uuid, representation = nil)
|
309
|
+
if representation.is_a?(String)
|
310
|
+
raise ArgumentError, "Representation must be given as a symbol: #{representation}"
|
311
|
+
end
|
312
|
+
uuid_binary = uuid.gsub('-', '').scan(/../).map(&:hex).map(&:chr).join
|
313
|
+
case representation && representation
|
314
|
+
when nil, :standard
|
315
|
+
new(uuid_binary, :uuid)
|
316
|
+
when :csharp_legacy
|
317
|
+
uuid_binary.sub!(/\A(.)(.)(.)(.)(.)(.)(.)(.)(.{8})\z/, '\4\3\2\1\6\5\8\7\9')
|
318
|
+
new(uuid_binary, :uuid_old)
|
319
|
+
when :java_legacy
|
320
|
+
uuid_binary.sub!(/\A(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)\z/) do |m|
|
321
|
+
"#{$8}#{$7}#{$6}#{$5}#{$4}#{$3}#{$2}#{$1}" +
|
322
|
+
"#{$16}#{$15}#{$14}#{$13}#{$12}#{$11}#{$10}#{$9}"
|
323
|
+
end
|
324
|
+
new(uuid_binary, :uuid_old)
|
325
|
+
when :python_legacy
|
326
|
+
new(uuid_binary, :uuid_old)
|
327
|
+
else
|
328
|
+
raise ArgumentError, "Invalid representation: #{representation}"
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
160
332
|
# Raised when providing an invalid type to the Binary.
|
161
333
|
#
|
162
334
|
# @since 2.0.0
|
data/lib/bson/boolean.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
1
|
+
# Copyright (C) 2009-2020 MongoDB Inc.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -31,13 +31,22 @@ module BSON
|
|
31
31
|
#
|
32
32
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
33
33
|
#
|
34
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
35
|
+
#
|
34
36
|
# @return [ TrueClass, FalseClass ] The decoded boolean.
|
35
37
|
#
|
36
38
|
# @see http://bsonspec.org/#/specification
|
37
39
|
#
|
38
40
|
# @since 2.0.0
|
39
|
-
def self.from_bson(buffer)
|
40
|
-
buffer.get_byte
|
41
|
+
def self.from_bson(buffer, **options)
|
42
|
+
case v = buffer.get_byte
|
43
|
+
when TrueClass::TRUE_BYTE
|
44
|
+
true
|
45
|
+
when FalseClass::FALSE_BYTE
|
46
|
+
false
|
47
|
+
else
|
48
|
+
raise Error::BSONDecodeError, "Invalid boolean byte value: #{v}"
|
49
|
+
end
|
41
50
|
end
|
42
51
|
|
43
52
|
# Register this type when the module is loaded.
|