bson 4.1.1 → 5.2.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 +5 -5
- data/README.md +106 -7
- data/Rakefile +86 -43
- data/ext/bson/{native-endian.h → bson-endian.h} +14 -107
- data/ext/bson/bson-native.h +135 -0
- data/ext/bson/bytebuf.c +133 -0
- data/ext/bson/endian.c +117 -0
- data/ext/bson/extconf.rb +8 -3
- data/ext/bson/init.c +364 -0
- data/ext/bson/libbson-utf8.c +230 -0
- data/ext/bson/read.c +470 -0
- data/ext/bson/util.c +250 -0
- data/ext/bson/write.c +675 -0
- data/lib/bson/active_support.rb +19 -0
- data/lib/bson/array.rb +97 -30
- data/lib/bson/big_decimal.rb +77 -0
- data/lib/bson/binary.rb +510 -70
- data/lib/bson/boolean.rb +15 -4
- data/lib/bson/code.rb +25 -12
- data/lib/bson/code_with_scope.rb +41 -15
- data/lib/bson/config.rb +3 -28
- data/lib/bson/date.rb +16 -4
- data/lib/bson/date_time.rb +6 -4
- data/lib/bson/db_pointer.rb +110 -0
- data/lib/bson/dbref.rb +154 -0
- data/lib/bson/decimal128/builder.rb +456 -0
- data/lib/bson/decimal128.rb +272 -0
- data/lib/bson/document.rb +177 -7
- data/lib/bson/environment.rb +17 -2
- data/lib/bson/error/bson_decode_error.rb +11 -0
- data/lib/bson/error/ext_json_parse_error.rb +11 -0
- data/lib/bson/error/illegal_key.rb +23 -0
- data/lib/bson/error/invalid_binary_type.rb +37 -0
- data/lib/bson/error/invalid_dbref_argument.rb +12 -0
- data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
- data/lib/bson/error/invalid_decimal128_range.rb +27 -0
- data/lib/bson/error/invalid_decimal128_string.rb +26 -0
- data/lib/bson/error/invalid_key.rb +24 -0
- data/lib/bson/error/invalid_object_id.rb +11 -0
- data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
- data/lib/bson/error/unrepresentable_precision.rb +19 -0
- data/lib/bson/error/unserializable_class.rb +13 -0
- data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
- data/lib/bson/error/unsupported_type.rb +11 -0
- data/lib/bson/error.rb +22 -0
- data/lib/bson/ext_json.rb +389 -0
- data/lib/bson/false_class.rb +6 -4
- data/lib/bson/float.rb +43 -7
- data/lib/bson/hash.rb +152 -37
- data/lib/bson/int32.rb +104 -6
- data/lib/bson/int64.rb +111 -8
- data/lib/bson/integer.rb +43 -9
- data/lib/bson/json.rb +3 -1
- data/lib/bson/max_key.rb +21 -10
- data/lib/bson/min_key.rb +21 -10
- data/lib/bson/nil_class.rb +7 -3
- data/lib/bson/object.rb +25 -17
- data/lib/bson/object_id.rb +98 -113
- data/lib/bson/open_struct.rb +59 -0
- data/lib/bson/regexp.rb +129 -56
- data/lib/bson/registry.rb +7 -10
- data/lib/bson/specialized.rb +8 -4
- data/lib/bson/string.rb +12 -32
- data/lib/bson/symbol.rb +107 -11
- data/lib/bson/time.rb +68 -7
- data/lib/bson/time_with_zone.rb +67 -0
- data/lib/bson/timestamp.rb +50 -10
- data/lib/bson/true_class.rb +6 -4
- data/lib/bson/undefined.rb +28 -2
- data/lib/bson/vector.rb +44 -0
- data/lib/bson/version.rb +6 -14
- data/lib/bson.rb +22 -12
- data/spec/README.md +14 -0
- data/spec/bson/array_spec.rb +38 -62
- data/spec/bson/big_decimal_spec.rb +328 -0
- data/spec/bson/binary_spec.rb +199 -53
- data/spec/bson/binary_uuid_spec.rb +190 -0
- data/spec/bson/boolean_spec.rb +2 -1
- data/spec/bson/byte_buffer_read_spec.rb +198 -0
- data/spec/bson/byte_buffer_spec.rb +122 -381
- data/spec/bson/byte_buffer_write_spec.rb +855 -0
- data/spec/bson/code_spec.rb +6 -4
- data/spec/bson/code_with_scope_spec.rb +6 -4
- data/spec/bson/config_spec.rb +1 -35
- data/spec/bson/date_spec.rb +2 -1
- data/spec/bson/date_time_spec.rb +55 -1
- data/spec/bson/dbref_legacy_spec.rb +186 -0
- data/spec/bson/dbref_spec.rb +487 -0
- data/spec/bson/decimal128_spec.rb +1840 -0
- data/spec/bson/document_as_spec.rb +61 -0
- data/spec/bson/document_spec.rb +205 -32
- data/spec/bson/ext_json_parse_spec.rb +346 -0
- data/spec/bson/false_class_spec.rb +9 -1
- data/spec/bson/float_spec.rb +42 -1
- data/spec/bson/hash_as_spec.rb +58 -0
- data/spec/bson/hash_spec.rb +318 -66
- data/spec/bson/int32_spec.rb +248 -1
- data/spec/bson/int64_spec.rb +308 -1
- data/spec/bson/integer_spec.rb +61 -3
- data/spec/bson/json_spec.rb +2 -1
- data/spec/bson/max_key_spec.rb +6 -4
- data/spec/bson/min_key_spec.rb +6 -4
- data/spec/bson/nil_class_spec.rb +2 -1
- data/spec/bson/object_id_spec.rb +95 -5
- data/spec/bson/object_spec.rb +3 -2
- data/spec/bson/open_struct_spec.rb +87 -0
- data/spec/bson/raw_spec.rb +594 -0
- data/spec/bson/regexp_spec.rb +61 -8
- data/spec/bson/registry_spec.rb +3 -2
- data/spec/bson/string_spec.rb +26 -33
- data/spec/bson/symbol_raw_spec.rb +70 -0
- data/spec/bson/symbol_spec.rb +77 -20
- data/spec/bson/time_spec.rb +206 -2
- data/spec/bson/time_with_zone_spec.rb +69 -0
- data/spec/bson/timestamp_spec.rb +58 -2
- data/spec/bson/true_class_spec.rb +9 -1
- data/spec/bson/undefined_spec.rb +28 -1
- data/spec/bson/vector_spec.rb +33 -0
- data/spec/bson_spec.rb +2 -1
- data/spec/runners/binary_vector.rb +78 -0
- data/spec/runners/common_driver.rb +348 -0
- data/spec/runners/corpus.rb +191 -0
- data/spec/runners/corpus_legacy.rb +248 -0
- 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 +378 -0
- data/spec/shared/lib/mrss/docker_runner.rb +298 -0
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
- data/spec/shared/lib/mrss/release/candidate.rb +281 -0
- data/spec/shared/lib/mrss/release/product_data.rb +144 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
- data/spec/shared/lib/mrss/session_registry.rb +69 -0
- data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
- data/spec/shared/lib/mrss/utils.rb +37 -0
- data/spec/shared/lib/tasks/candidate.rake +64 -0
- data/spec/shared/share/Dockerfile.erb +251 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/distro.sh +84 -0
- data/spec/shared/shlib/server.sh +423 -0
- data/spec/shared/shlib/set_env.sh +110 -0
- data/spec/spec_helper.rb +61 -1
- data/spec/spec_tests/binary_vector_spec.rb +82 -0
- data/spec/spec_tests/common_driver_spec.rb +84 -0
- data/spec/spec_tests/corpus_legacy_spec.rb +72 -0
- data/spec/spec_tests/corpus_spec.rb +134 -0
- data/spec/spec_tests/data/binary_vector/README.md +61 -0
- data/spec/spec_tests/data/binary_vector/float32.json +65 -0
- data/spec/spec_tests/data/binary_vector/int8.json +57 -0
- data/spec/spec_tests/data/binary_vector/packed_bit.json +83 -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 +153 -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 +51 -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 +165 -0
- data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
- data/spec/spec_tests/data/corpus/decimal128-6.json +131 -0
- data/spec/spec_tests/data/corpus/decimal128-7.json +327 -0
- data/spec/spec_tests/data/corpus/document.json +60 -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 +262 -0
- data/spec/spec_tests/data/corpus/undefined.json +15 -0
- data/spec/spec_tests/data/corpus_legacy/array.json +49 -0
- data/spec/spec_tests/data/corpus_legacy/binary.json +69 -0
- data/spec/spec_tests/data/corpus_legacy/boolean.json +27 -0
- data/spec/spec_tests/data/corpus_legacy/code.json +67 -0
- data/spec/spec_tests/data/corpus_legacy/code_w_scope.json +78 -0
- data/spec/spec_tests/data/corpus_legacy/document.json +36 -0
- data/spec/spec_tests/data/corpus_legacy/double.json +69 -0
- data/spec/spec_tests/data/corpus_legacy/failures/datetime.json +31 -0
- data/spec/spec_tests/data/corpus_legacy/failures/dbpointer.json +42 -0
- data/spec/spec_tests/data/corpus_legacy/failures/int64.json +38 -0
- data/spec/spec_tests/data/corpus_legacy/failures/symbol.json +62 -0
- data/spec/spec_tests/data/corpus_legacy/int32.json +38 -0
- data/spec/spec_tests/data/corpus_legacy/maxkey.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/minkey.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/null.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/oid.json +28 -0
- data/spec/spec_tests/data/corpus_legacy/regex.json +37 -0
- data/spec/spec_tests/data/corpus_legacy/string.json +67 -0
- data/spec/spec_tests/data/corpus_legacy/timestamp.json +18 -0
- data/spec/spec_tests/data/corpus_legacy/top.json +62 -0
- data/spec/spec_tests/data/corpus_legacy/undefined.json +13 -0
- data/spec/spec_tests/data/decimal128/decimal128-1.json +363 -0
- data/spec/spec_tests/data/decimal128/decimal128-2.json +793 -0
- data/spec/spec_tests/data/decimal128/decimal128-3.json +1771 -0
- data/spec/spec_tests/data/decimal128/decimal128-4.json +165 -0
- data/spec/spec_tests/data/decimal128/decimal128-5.json +402 -0
- data/spec/spec_tests/data/decimal128/decimal128-6.json +131 -0
- data/spec/spec_tests/data/decimal128/decimal128-7.json +327 -0
- data/spec/support/shared_examples.rb +32 -11
- data/spec/support/spec_config.rb +17 -0
- data/spec/support/utils.rb +58 -0
- metadata +284 -45
- checksums.yaml.gz.sig +0 -3
- data/ext/bson/native.c +0 -722
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
data/lib/bson/binary.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rubocop:todo all
|
|
3
|
+
# Copyright (C) 2009-2020 MongoDB Inc.
|
|
2
4
|
#
|
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
6
|
# you may not use this file except in compliance with the License.
|
|
@@ -12,8 +14,9 @@
|
|
|
12
14
|
# See the License for the specific language governing permissions and
|
|
13
15
|
# limitations under the License.
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
require 'base64'
|
|
16
18
|
|
|
19
|
+
module BSON
|
|
17
20
|
# Represents binary data.
|
|
18
21
|
#
|
|
19
22
|
# @see http://bsonspec.org/#/specification
|
|
@@ -21,37 +24,66 @@ module BSON
|
|
|
21
24
|
# @since 2.0.0
|
|
22
25
|
class Binary
|
|
23
26
|
include JSON
|
|
27
|
+
include Comparable
|
|
24
28
|
|
|
25
29
|
# A binary is type 0x05 in the BSON spec.
|
|
26
30
|
#
|
|
27
31
|
# @since 2.0.0
|
|
28
|
-
BSON_TYPE = 5.chr
|
|
32
|
+
BSON_TYPE = ::String.new(5.chr, encoding: BINARY).freeze
|
|
29
33
|
|
|
30
34
|
# The mappings of subtypes to their single byte identifiers.
|
|
31
35
|
#
|
|
36
|
+
# @note subtype 6 (ciphertext) is used for the Client-Side Encryption
|
|
37
|
+
# feature. Data represented by this subtype is often encrypted, but
|
|
38
|
+
# may also be plaintext. All instances of this subtype necessary for
|
|
39
|
+
# Client-Side Encryption will be created internally by the Ruby driver.
|
|
40
|
+
# An application should not create new BSON::Binary objects of this subtype.
|
|
41
|
+
#
|
|
32
42
|
# @since 2.0.0
|
|
33
43
|
SUBTYPES = {
|
|
34
|
-
:
|
|
35
|
-
:
|
|
36
|
-
:
|
|
37
|
-
:
|
|
38
|
-
:
|
|
39
|
-
:
|
|
40
|
-
:
|
|
44
|
+
generic: 0.chr,
|
|
45
|
+
function: 1.chr,
|
|
46
|
+
old: 2.chr,
|
|
47
|
+
uuid_old: 3.chr,
|
|
48
|
+
uuid: 4.chr,
|
|
49
|
+
md5: 5.chr,
|
|
50
|
+
ciphertext: 6.chr,
|
|
51
|
+
column: 7.chr,
|
|
52
|
+
sensitive: 8.chr,
|
|
53
|
+
vector: 9.chr,
|
|
54
|
+
user: 128.chr,
|
|
41
55
|
}.freeze
|
|
42
56
|
|
|
57
|
+
# The starting point of the user-defined subtype range.
|
|
58
|
+
USER_SUBTYPE = 0x80
|
|
59
|
+
|
|
43
60
|
# The mappings of single byte subtypes to their symbol counterparts.
|
|
44
61
|
#
|
|
45
62
|
# @since 2.0.0
|
|
46
63
|
TYPES = SUBTYPES.invert.freeze
|
|
47
64
|
|
|
48
|
-
#
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
# Types of vector data.
|
|
66
|
+
VECTOR_DATA_TYPES = {
|
|
67
|
+
int8: '0x03'.hex,
|
|
68
|
+
float32: '0x27'.hex,
|
|
69
|
+
packed_bit: '0x10'.hex
|
|
70
|
+
}.freeze
|
|
71
|
+
|
|
72
|
+
# @api private
|
|
73
|
+
VECTOR_DATA_TYPES_INVERSE = VECTOR_DATA_TYPES.invert.freeze
|
|
74
|
+
|
|
75
|
+
# @return [ String ] The raw binary data.
|
|
76
|
+
#
|
|
77
|
+
# The string is always stored in BINARY encoding.
|
|
78
|
+
#
|
|
79
|
+
# @since 2.0.0
|
|
80
|
+
attr_reader :data
|
|
81
|
+
|
|
82
|
+
# @return [ Symbol ] The binary type.
|
|
83
|
+
attr_reader :type
|
|
84
|
+
|
|
85
|
+
# @return [ String ] The raw type value, as an encoded integer.
|
|
86
|
+
attr_reader :raw_type
|
|
55
87
|
|
|
56
88
|
# Determine if this binary object is equal to another object.
|
|
57
89
|
#
|
|
@@ -65,10 +97,26 @@ module BSON
|
|
|
65
97
|
# @since 2.0.0
|
|
66
98
|
def ==(other)
|
|
67
99
|
return false unless other.is_a?(Binary)
|
|
100
|
+
|
|
68
101
|
type == other.type && data == other.data
|
|
69
102
|
end
|
|
103
|
+
|
|
70
104
|
alias eql? ==
|
|
71
105
|
|
|
106
|
+
# Compare this binary object to another object. The two objects must have
|
|
107
|
+
# the same type for any meaningful comparison.
|
|
108
|
+
#
|
|
109
|
+
# @param [ Object ] other The object to compare against.
|
|
110
|
+
#
|
|
111
|
+
# @return [ Integer | nil ] If the objects have the same type, the result
|
|
112
|
+
# is -1 if self < other, 0 if self == other, and 1 if self > other. If
|
|
113
|
+
# other is not a Binary, or is a Binary of a different type, returns nil.
|
|
114
|
+
def <=>(other)
|
|
115
|
+
return nil unless other.is_a?(Binary) && type == other.type
|
|
116
|
+
|
|
117
|
+
data <=> other.data
|
|
118
|
+
end
|
|
119
|
+
|
|
72
120
|
# Generates a Fixnum hash value for this object.
|
|
73
121
|
#
|
|
74
122
|
# Allows using Binary as hash keys.
|
|
@@ -77,34 +125,86 @@ module BSON
|
|
|
77
125
|
#
|
|
78
126
|
# @since 2.3.1
|
|
79
127
|
def hash
|
|
80
|
-
data
|
|
128
|
+
[data, type].hash
|
|
81
129
|
end
|
|
82
130
|
|
|
83
|
-
#
|
|
131
|
+
# Return a representation of the object for use in
|
|
132
|
+
# application-level JSON serialization. Since BSON::Binary
|
|
133
|
+
# is used exclusively in BSON-related contexts, this
|
|
134
|
+
# method returns the canonical Extended JSON representation.
|
|
135
|
+
#
|
|
136
|
+
# @return [ Hash ] The extended json representation.
|
|
137
|
+
def as_json(*_args)
|
|
138
|
+
as_extended_json
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Converts this object to a representation directly serializable to
|
|
142
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
|
|
84
143
|
#
|
|
85
|
-
# @
|
|
86
|
-
#
|
|
144
|
+
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
|
145
|
+
# (default is canonical extended JSON)
|
|
87
146
|
#
|
|
88
|
-
# @return [ Hash ] The
|
|
147
|
+
# @return [ Hash ] The extended json representation.
|
|
148
|
+
def as_extended_json(**options)
|
|
149
|
+
subtype = @raw_type.each_byte.map { |c| c.to_s(16) }.join
|
|
150
|
+
subtype = "0#{subtype}" if subtype.length == 1
|
|
151
|
+
|
|
152
|
+
value = Base64.encode64(data).strip
|
|
153
|
+
|
|
154
|
+
if options[:mode] == :legacy
|
|
155
|
+
{ '$binary' => value, '$type' => subtype }
|
|
156
|
+
else
|
|
157
|
+
{ '$binary' => { 'base64' => value, 'subType' => subtype } }
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Decode the binary data as a vector data type.
|
|
89
162
|
#
|
|
90
|
-
# @
|
|
91
|
-
def
|
|
92
|
-
|
|
163
|
+
# @return [ BSON::Vector ] The decoded vector data.
|
|
164
|
+
def as_vector
|
|
165
|
+
raise BSON::Error, "Cannot decode subtype #{type} as vector" unless type == :vector
|
|
166
|
+
|
|
167
|
+
dtype_value, padding, = data[0..1].unpack('CC')
|
|
168
|
+
dtype = VECTOR_DATA_TYPES_INVERSE[dtype_value]
|
|
169
|
+
raise ArgumentError, "Unsupported vector type: #{dtype_value}" unless dtype
|
|
170
|
+
|
|
171
|
+
format = case dtype
|
|
172
|
+
when :int8 then 'c*'
|
|
173
|
+
when :float32 then 'f*'
|
|
174
|
+
when :packed_bit then 'C*'
|
|
175
|
+
else
|
|
176
|
+
raise ArgumentError, "Unsupported type: #{dtype}"
|
|
177
|
+
end
|
|
178
|
+
BSON::Vector.new(data[2..-1].unpack(format), dtype, padding)
|
|
93
179
|
end
|
|
94
180
|
|
|
95
181
|
# Instantiate the new binary object.
|
|
96
182
|
#
|
|
183
|
+
# This method accepts a string in any encoding; however, if a string is
|
|
184
|
+
# of a non-BINARY encoding, the encoding is set to BINARY. This does not
|
|
185
|
+
# change the bytes of the string but it means that applications referencing
|
|
186
|
+
# the data of a Binary instance cannot assume it is in a non-binary
|
|
187
|
+
# encoding, even if the string given to the constructor was in such an
|
|
188
|
+
# encoding.
|
|
189
|
+
#
|
|
97
190
|
# @example Instantiate a binary.
|
|
98
191
|
# BSON::Binary.new(data, :md5)
|
|
99
192
|
#
|
|
100
|
-
# @param [
|
|
193
|
+
# @param [ String ] data The raw binary data.
|
|
101
194
|
# @param [ Symbol ] type The binary type.
|
|
102
195
|
#
|
|
103
196
|
# @since 2.0.0
|
|
104
|
-
def initialize(data =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
197
|
+
def initialize(data = '', type = :generic)
|
|
198
|
+
initialize_instance(data, type)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# For legacy deserialization support where BSON::Binary objects are
|
|
202
|
+
# expected to have a specific internal representation (with only
|
|
203
|
+
# @type and @data instance variables).
|
|
204
|
+
#
|
|
205
|
+
# @api private
|
|
206
|
+
def init_with(coder)
|
|
207
|
+
initialize_instance(coder['data'], coder['type'])
|
|
108
208
|
end
|
|
109
209
|
|
|
110
210
|
# Get a nice string for use with object inspection.
|
|
@@ -116,7 +216,49 @@ module BSON
|
|
|
116
216
|
#
|
|
117
217
|
# @since 2.3.0
|
|
118
218
|
def inspect
|
|
119
|
-
"<BSON::Binary:0x#{object_id} type=#{type} data=0x#{data[0, 8].
|
|
219
|
+
"<BSON::Binary:0x#{object_id} type=#{type} data=0x#{data[0, 8].unpack1('H*')}...>"
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Returns a string representation of the UUID stored in this Binary.
|
|
223
|
+
#
|
|
224
|
+
# If the Binary is of subtype 4 (:uuid), this method returns the UUID
|
|
225
|
+
# in RFC 4122 format. If the representation parameter is provided, it
|
|
226
|
+
# must be the value :standard as a symbol or a string.
|
|
227
|
+
#
|
|
228
|
+
# If the Binary is of subtype 3 (:uuid_old), this method requires that
|
|
229
|
+
# the representation parameter is provided and is one of :csharp_legacy,
|
|
230
|
+
# :java_legacy or :python_legacy or the equivalent strings. In this case
|
|
231
|
+
# the method assumes the Binary stores the UUID in the specified format,
|
|
232
|
+
# transforms the stored bytes to the standard RFC 4122 representation
|
|
233
|
+
# and returns the UUID in RFC 4122 format.
|
|
234
|
+
#
|
|
235
|
+
# If the Binary is of another subtype, this method raises TypeError.
|
|
236
|
+
#
|
|
237
|
+
# @param [ Symbol ] representation How to interpret the UUID.
|
|
238
|
+
#
|
|
239
|
+
# @return [ String ] The string representation of the UUID.
|
|
240
|
+
#
|
|
241
|
+
# @raise [ TypeError ] If the subtype of Binary is not :uuid nor :uuid_old.
|
|
242
|
+
# @raise [ ArgumentError ] If the representation other than :standard
|
|
243
|
+
# is requested for Binary subtype 4 (:uuid), if :standard representation
|
|
244
|
+
# is requested for Binary subtype 3 (:uuid_old), or if an invalid
|
|
245
|
+
# representation is requested.
|
|
246
|
+
#
|
|
247
|
+
# @api experimental
|
|
248
|
+
def to_uuid(representation = nil)
|
|
249
|
+
if representation.is_a?(String)
|
|
250
|
+
raise ArgumentError,
|
|
251
|
+
"Representation must be given as a symbol: #{representation.inspect}"
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
case type
|
|
255
|
+
when :uuid
|
|
256
|
+
from_uuid_to_uuid(representation || :standard)
|
|
257
|
+
when :uuid_old
|
|
258
|
+
from_uuid_old_to_uuid(representation)
|
|
259
|
+
else
|
|
260
|
+
raise TypeError, "The type of Binary must be :uuid or :uuid_old, this object is: #{type.inspect}"
|
|
261
|
+
end
|
|
120
262
|
end
|
|
121
263
|
|
|
122
264
|
# Encode the binary type
|
|
@@ -124,17 +266,17 @@ module BSON
|
|
|
124
266
|
# @example Encode the binary.
|
|
125
267
|
# binary.to_bson
|
|
126
268
|
#
|
|
127
|
-
# @return [
|
|
269
|
+
# @return [ BSON::ByteBuffer ] The buffer with the encoded object.
|
|
128
270
|
#
|
|
129
271
|
# @see http://bsonspec.org/#/specification
|
|
130
272
|
#
|
|
131
273
|
# @since 2.0.0
|
|
132
|
-
def to_bson(buffer = ByteBuffer.new
|
|
274
|
+
def to_bson(buffer = ByteBuffer.new)
|
|
133
275
|
position = buffer.length
|
|
134
276
|
buffer.put_int32(0)
|
|
135
|
-
buffer.put_byte(
|
|
277
|
+
buffer.put_byte(@raw_type)
|
|
136
278
|
buffer.put_int32(data.bytesize) if type == :old
|
|
137
|
-
buffer.put_bytes(data
|
|
279
|
+
buffer.put_bytes(data)
|
|
138
280
|
buffer.replace_int32(position, buffer.length - position - 5)
|
|
139
281
|
end
|
|
140
282
|
|
|
@@ -142,57 +284,309 @@ module BSON
|
|
|
142
284
|
#
|
|
143
285
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
|
144
286
|
#
|
|
287
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
|
288
|
+
#
|
|
145
289
|
# @return [ Binary ] The decoded binary data.
|
|
146
290
|
#
|
|
147
291
|
# @see http://bsonspec.org/#/specification
|
|
148
292
|
#
|
|
149
293
|
# @since 2.0.0
|
|
150
|
-
def self.from_bson(buffer)
|
|
294
|
+
def self.from_bson(buffer, **_options)
|
|
151
295
|
length = buffer.get_int32
|
|
152
|
-
|
|
296
|
+
type_byte = buffer.get_byte
|
|
297
|
+
|
|
298
|
+
if type_byte.bytes.first < USER_SUBTYPE
|
|
299
|
+
type = TYPES[type_byte]
|
|
300
|
+
|
|
301
|
+
if type.nil?
|
|
302
|
+
raise Error::UnsupportedBinarySubtype,
|
|
303
|
+
"BSON data contains unsupported binary subtype #{'0x%02x' % type_byte.ord}"
|
|
304
|
+
end
|
|
305
|
+
else
|
|
306
|
+
type = type_byte
|
|
307
|
+
end
|
|
308
|
+
|
|
153
309
|
length = buffer.get_int32 if type == :old
|
|
154
310
|
data = buffer.get_bytes(length)
|
|
155
311
|
new(data, type)
|
|
156
312
|
end
|
|
157
313
|
|
|
158
|
-
#
|
|
314
|
+
# Creates a BSON::Binary from a string representation of a UUID.
|
|
159
315
|
#
|
|
160
|
-
#
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
316
|
+
# The UUID may be given in either 00112233-4455-6677-8899-aabbccddeeff or
|
|
317
|
+
# 00112233445566778899AABBCCDDEEFF format - specifically, any dashes in
|
|
318
|
+
# the UUID are removed and both upper and lower case letters are acceptable.
|
|
319
|
+
#
|
|
320
|
+
# The input UUID string is always interpreted to be in the RFC 4122 format.
|
|
321
|
+
#
|
|
322
|
+
# If representation is not provided, this method creates a BSON::Binary
|
|
323
|
+
# of subtype 4 (:uuid). If representation is provided, it must be one of
|
|
324
|
+
# :standard, :csharp_legacy, :java_legacy or :python_legacy. If
|
|
325
|
+
# representation is :standard, this method creates a subtype 4 (:uuid)
|
|
326
|
+
# binary which is the same behavior as if representation was not provided.
|
|
327
|
+
# For other representations, this method creates a Binary of subtype 3
|
|
328
|
+
# (:uuid_old) with the UUID converted to the appropriate legacy MongoDB
|
|
329
|
+
# UUID storage format.
|
|
330
|
+
#
|
|
331
|
+
# @param [ String ] uuid The string representation of the UUID.
|
|
332
|
+
# @param [ Symbol ] representation How to interpret the UUID.
|
|
333
|
+
#
|
|
334
|
+
# @return [ Binary ] The binary.
|
|
335
|
+
#
|
|
336
|
+
# @raise [ ArgumentError ] If invalid representation is requested.
|
|
337
|
+
#
|
|
338
|
+
# @api experimental
|
|
339
|
+
def self.from_uuid(uuid, representation = nil)
|
|
340
|
+
raise ArgumentError, "Representation must be given as a symbol: #{representation}" if representation.is_a?(String)
|
|
341
|
+
|
|
342
|
+
uuid_binary = uuid.delete('-').scan(/../).map(&:hex).map(&:chr).join
|
|
343
|
+
representation ||= :standard
|
|
344
|
+
|
|
345
|
+
handler = :"from_#{representation}_uuid"
|
|
346
|
+
raise ArgumentError, "Invalid representation: #{representation}" unless respond_to?(handler)
|
|
347
|
+
|
|
348
|
+
send(handler, uuid_binary)
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# Constructs a new binary object from a standard-format binary UUID
|
|
352
|
+
# representation.
|
|
353
|
+
#
|
|
354
|
+
# @param [ String ] uuid_binary the UUID data
|
|
355
|
+
#
|
|
356
|
+
# @return [ BSON::Binary ] the Binary object
|
|
357
|
+
#
|
|
358
|
+
# @api private
|
|
359
|
+
def self.from_standard_uuid(uuid_binary)
|
|
360
|
+
new(uuid_binary, :uuid)
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
# Constructs a new binary object from a csharp legacy-format binary UUID
|
|
364
|
+
# representation.
|
|
365
|
+
#
|
|
366
|
+
# @param [ String ] uuid_binary the UUID data
|
|
367
|
+
#
|
|
368
|
+
# @return [ BSON::Binary ] the Binary object
|
|
369
|
+
#
|
|
370
|
+
# @api private
|
|
371
|
+
def self.from_csharp_legacy_uuid(uuid_binary)
|
|
372
|
+
uuid_binary.sub!(/\A(.)(.)(.)(.)(.)(.)(.)(.)(.{8})\z/, '\4\3\2\1\6\5\8\7\9')
|
|
373
|
+
new(uuid_binary, :uuid_old)
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
# Constructs a new binary object from a java legacy-format binary UUID
|
|
377
|
+
# representation.
|
|
378
|
+
#
|
|
379
|
+
# @param [ String ] uuid_binary the UUID data
|
|
380
|
+
#
|
|
381
|
+
# @return [ BSON::Binary ] the Binary object
|
|
382
|
+
#
|
|
383
|
+
# @api private
|
|
384
|
+
def self.from_java_legacy_uuid(uuid_binary)
|
|
385
|
+
uuid_binary.sub!(/\A(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)\z/) do
|
|
386
|
+
(::Regexp.last_match[1..8].reverse + ::Regexp.last_match[9..16].reverse).join
|
|
178
387
|
end
|
|
388
|
+
new(uuid_binary, :uuid_old)
|
|
389
|
+
end
|
|
179
390
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
391
|
+
# Constructs a new binary object from a python legacy-format binary UUID
|
|
392
|
+
# representation.
|
|
393
|
+
#
|
|
394
|
+
# @param [ String ] uuid_binary the UUID data
|
|
395
|
+
#
|
|
396
|
+
# @return [ BSON::Binary ] the Binary object
|
|
397
|
+
#
|
|
398
|
+
# @api private
|
|
399
|
+
def self.from_python_legacy_uuid(uuid_binary)
|
|
400
|
+
new(uuid_binary, :uuid_old)
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
# Constructs a new binary object from a binary vector.
|
|
404
|
+
|
|
405
|
+
# @param [ BSON::Vector | Array ] vector The vector data.
|
|
406
|
+
# @param [ Symbol | nil ] dtype The vector data type, must be nil if vector is a BSON::Vector.
|
|
407
|
+
# @param [ Integer ] padding The number of bits in the final byte that are to
|
|
408
|
+
# be ignored when a vector element's size is less than a byte. Must be 0 if vector is a BSON::Vector.
|
|
409
|
+
# @param [ Boolean ] validate_vector_data Whether to validate the vector data.
|
|
410
|
+
#
|
|
411
|
+
# @return [ BSON::Binary ] The binary object.
|
|
412
|
+
def self.from_vector(vector, dtype = nil, padding = 0, validate_vector_data: false)
|
|
413
|
+
data, dtype, padding = extract_args_for_vector(vector, dtype, padding)
|
|
414
|
+
validate_args_for_vector!(data, dtype, padding)
|
|
415
|
+
|
|
416
|
+
format = case dtype
|
|
417
|
+
when :int8 then 'c*'
|
|
418
|
+
when :float32 then 'f*'
|
|
419
|
+
when :packed_bit then 'C*'
|
|
420
|
+
else raise ArgumentError, "Unsupported type: #{dtype}"
|
|
421
|
+
end
|
|
422
|
+
if validate_vector_data
|
|
423
|
+
validate_vector_data!(data, dtype)
|
|
191
424
|
end
|
|
425
|
+
metadata = [ VECTOR_DATA_TYPES[dtype], padding ].pack('CC')
|
|
426
|
+
data = data.pack(format)
|
|
427
|
+
new(metadata.concat(data), :vector)
|
|
192
428
|
end
|
|
193
429
|
|
|
194
430
|
private
|
|
195
431
|
|
|
432
|
+
# Extracts the arguments for a binary vector.
|
|
433
|
+
#
|
|
434
|
+
# @param [ BSON::Vector | Array ] vector The vector data.
|
|
435
|
+
# @param [ ::Symbol | nil ] dtype The vector data type, must be nil if vector is a BSON::Vector.
|
|
436
|
+
# @param [ Integer ] padding The padding. Must be 0 if vector is a BSON::Vector.
|
|
437
|
+
#
|
|
438
|
+
# @return [ Array ] The extracted data, dtype, and padding.
|
|
439
|
+
def self.extract_args_for_vector(vector, dtype, padding)
|
|
440
|
+
if vector.is_a?(BSON::Vector)
|
|
441
|
+
if dtype || padding != 0
|
|
442
|
+
raise ArgumentError, 'Do not specify dtype and padding if the first argument is BSON::Vector'
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
data = vector.data
|
|
446
|
+
dtype = vector.dtype
|
|
447
|
+
padding = vector.padding
|
|
448
|
+
else
|
|
449
|
+
data = vector
|
|
450
|
+
end
|
|
451
|
+
[ data, dtype, padding ]
|
|
452
|
+
end
|
|
453
|
+
private_class_method :extract_args_for_vector
|
|
454
|
+
|
|
455
|
+
# Validate the arguments for a binary vector.
|
|
456
|
+
# @param [ Array ] data The vector data.
|
|
457
|
+
# @param [ ::Symbol ] dtype The vector data type.
|
|
458
|
+
# @param [ Integer ] padding The padding. Must be 0 if vector is a BSON::Vector.
|
|
459
|
+
# @raise [ ArgumentError ] If the arguments are invalid.
|
|
460
|
+
def self.validate_args_for_vector!(data, dtype, padding)
|
|
461
|
+
raise ArgumentError, "Unknown dtype #{dtype}" unless VECTOR_DATA_TYPES.key?(dtype)
|
|
462
|
+
|
|
463
|
+
if %i[int8 float32].include?(dtype)
|
|
464
|
+
raise ArgumentError, 'Padding applies only to packed_bit' if padding != 0
|
|
465
|
+
elsif padding.positive? && data.empty?
|
|
466
|
+
raise ArgumentError, 'Padding must be zero when the vector is empty for PACKED_BIT'
|
|
467
|
+
elsif padding.negative? || padding > 7
|
|
468
|
+
raise ArgumentError, "Padding must be between 0 and 7, got #{padding}"
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
private_class_method :validate_args_for_vector!
|
|
472
|
+
|
|
473
|
+
# Validate that all the values in the vector data are valid for the given dtype.
|
|
474
|
+
#
|
|
475
|
+
# @param [ Array ] data The vector data.
|
|
476
|
+
# @param [ ::Symbol ] dtype The vector data type.
|
|
477
|
+
def self.validate_vector_data!(data, dtype)
|
|
478
|
+
validator = case dtype
|
|
479
|
+
when :int8
|
|
480
|
+
->(v) { v.is_a?(Integer) && v.between?(-128, 127) }
|
|
481
|
+
when :float32
|
|
482
|
+
->(v) { v.is_a?(Float) }
|
|
483
|
+
when :packed_bit
|
|
484
|
+
->(v) { v.is_a?(Integer) && v.between?(0, 255) }
|
|
485
|
+
else
|
|
486
|
+
raise ArgumentError, "Unsupported type: #{dtype}"
|
|
487
|
+
end
|
|
488
|
+
data.each do |v|
|
|
489
|
+
raise ArgumentError, "Invalid value #{v} for type #{dtype}" unless validator.call(v)
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
private_class_method :validate_vector_data!
|
|
493
|
+
|
|
494
|
+
# initializes an instance of BSON::Binary.
|
|
495
|
+
#
|
|
496
|
+
# @param [ String ] data the data to initialize the object with
|
|
497
|
+
# @param [ Symbol ] type the type to assign the binary object
|
|
498
|
+
def initialize_instance(data, type)
|
|
499
|
+
@type = validate_type!(type)
|
|
500
|
+
|
|
501
|
+
# The Binary class used to force encoding to BINARY when serializing to
|
|
502
|
+
# BSON. Instead of doing that during serialization, perform this
|
|
503
|
+
# operation during Binary construction to make it clear that once
|
|
504
|
+
# the string is given to the Binary, the data is treated as a binary
|
|
505
|
+
# string and not a text string in any encoding.
|
|
506
|
+
data = data.dup.force_encoding('BINARY') unless data.encoding == Encoding.find('BINARY')
|
|
507
|
+
|
|
508
|
+
@data = data
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
# Converts the Binary UUID object to a UUID of the given representation.
|
|
512
|
+
# Currently, only :standard representation is supported.
|
|
513
|
+
#
|
|
514
|
+
# @param [ Symbol ] representation The representation to target (must be
|
|
515
|
+
# :standard)
|
|
516
|
+
#
|
|
517
|
+
# @return [ String ] the UUID as a string
|
|
518
|
+
def from_uuid_to_uuid(representation)
|
|
519
|
+
if representation != :standard
|
|
520
|
+
raise ArgumentError,
|
|
521
|
+
'Binary of type :uuid can only be stringified to :standard representation, ' \
|
|
522
|
+
"requested: #{representation.inspect}"
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
data
|
|
526
|
+
.chars
|
|
527
|
+
.map { |n| '%02x' % n.ord }
|
|
528
|
+
.join
|
|
529
|
+
.sub(/\A(.{8})(.{4})(.{4})(.{4})(.{12})\z/, '\1-\2-\3-\4-\5')
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
# Converts the UUID-old object to a UUID of the given representation.
|
|
533
|
+
#
|
|
534
|
+
# @param [ Symbol ] representation The representation to target
|
|
535
|
+
#
|
|
536
|
+
# @return [ String ] the UUID as a string
|
|
537
|
+
def from_uuid_old_to_uuid(representation)
|
|
538
|
+
if representation.nil?
|
|
539
|
+
raise ArgumentError, 'Representation must be specified for BSON::Binary objects of type :uuid_old'
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
hex = data.chars.map { |n| '%02x' % n.ord }.join
|
|
543
|
+
handler = :"from_uuid_old_to_#{representation}_uuid"
|
|
544
|
+
|
|
545
|
+
raise ArgumentError, "Invalid representation: #{representation}" unless respond_to?(handler, true)
|
|
546
|
+
|
|
547
|
+
send(handler, hex)
|
|
548
|
+
.sub(/\A(.{8})(.{4})(.{4})(.{4})(.{12})\z/, '\1-\2-\3-\4-\5')
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
# Tries to convert a UUID-old object to a standard representation, which is
|
|
552
|
+
# not supported.
|
|
553
|
+
#
|
|
554
|
+
# @param [ String ] hex The hexadecimal string to convert
|
|
555
|
+
#
|
|
556
|
+
# @raise [ ArgumentError ] because standard representation is not supported
|
|
557
|
+
def from_uuid_old_to_standard_uuid(_hex)
|
|
558
|
+
raise ArgumentError, 'BSON::Binary objects of type :uuid_old cannot be stringified to :standard representation'
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
# Converts a UUID-old object to a csharp-legacy representation.
|
|
562
|
+
#
|
|
563
|
+
# @param [ String ] hex The hexadecimal string to convert
|
|
564
|
+
#
|
|
565
|
+
# @return [ String ] the csharp-legacy-formatted UUID
|
|
566
|
+
def from_uuid_old_to_csharp_legacy_uuid(hex)
|
|
567
|
+
hex.sub(/\A(..)(..)(..)(..)(..)(..)(..)(..)(.{16})\z/, '\4\3\2\1\6\5\8\7\9')
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
# Converts a UUID-old object to a java-legacy representation.
|
|
571
|
+
#
|
|
572
|
+
# @param [ String ] hex The hexadecimal string to convert
|
|
573
|
+
#
|
|
574
|
+
# @return [ String ] the java-legacy-formatted UUID
|
|
575
|
+
def from_uuid_old_to_java_legacy_uuid(hex)
|
|
576
|
+
hex.sub(/\A(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)\z/) do
|
|
577
|
+
(::Regexp.last_match[1..8].reverse + ::Regexp.last_match[9..16].reverse).join
|
|
578
|
+
end
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
# Converts a UUID-old object to a python-legacy representation.
|
|
582
|
+
#
|
|
583
|
+
# @param [ String ] hex The hexadecimal string to convert
|
|
584
|
+
#
|
|
585
|
+
# @return [ String ] the python-legacy-formatted UUID
|
|
586
|
+
def from_uuid_old_to_python_legacy_uuid(hex)
|
|
587
|
+
hex
|
|
588
|
+
end
|
|
589
|
+
|
|
196
590
|
# Validate the provided type is a valid type.
|
|
197
591
|
#
|
|
198
592
|
# @api private
|
|
@@ -200,13 +594,59 @@ module BSON
|
|
|
200
594
|
# @example Validate the type.
|
|
201
595
|
# binary.validate_type!(:user)
|
|
202
596
|
#
|
|
203
|
-
# @param [
|
|
597
|
+
# @param [ Symbol | String | Integer ] type The provided type.
|
|
598
|
+
#
|
|
599
|
+
# @return [ Symbol ] the symbolic type corresponding to the argument.
|
|
204
600
|
#
|
|
205
|
-
# @raise [
|
|
601
|
+
# @raise [ BSON::Error::InvalidBinaryType ] The the type is invalid.
|
|
206
602
|
#
|
|
207
603
|
# @since 2.0.0
|
|
208
604
|
def validate_type!(type)
|
|
209
|
-
|
|
605
|
+
case type
|
|
606
|
+
when Integer then validate_integer_type!(type)
|
|
607
|
+
when String
|
|
608
|
+
if type.length > 1
|
|
609
|
+
validate_symbol_type!(type.to_sym)
|
|
610
|
+
else
|
|
611
|
+
validate_integer_type!(type.bytes.first)
|
|
612
|
+
end
|
|
613
|
+
when Symbol then validate_symbol_type!(type)
|
|
614
|
+
else
|
|
615
|
+
raise BSON::Error::InvalidBinaryType, type
|
|
616
|
+
end
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
# Test that the given integer type is valid.
|
|
620
|
+
#
|
|
621
|
+
# @param [ Integer ] type the provided type
|
|
622
|
+
#
|
|
623
|
+
# @return [ Symbol ] the symbolic type corresponding to the argument.
|
|
624
|
+
#
|
|
625
|
+
# @raise [ BSON::Error::InvalidBinaryType] if the type is invalid.
|
|
626
|
+
def validate_integer_type!(type)
|
|
627
|
+
@raw_type = type.chr.force_encoding('BINARY').freeze
|
|
628
|
+
|
|
629
|
+
if type < USER_SUBTYPE
|
|
630
|
+
raise BSON::Error::InvalidBinaryType, type unless TYPES.key?(@raw_type)
|
|
631
|
+
|
|
632
|
+
return TYPES[@raw_type]
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
:user
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
# Test that the given symbol type is valid.
|
|
639
|
+
#
|
|
640
|
+
# @param [ Symbol ] type the provided type
|
|
641
|
+
#
|
|
642
|
+
# @return [ Symbol ] the symbolic type corresponding to the argument.
|
|
643
|
+
#
|
|
644
|
+
# @raise [ BSON::Error::InvalidBinaryType] if the type is invalid.
|
|
645
|
+
def validate_symbol_type!(type)
|
|
646
|
+
raise BSON::Error::InvalidBinaryType, type unless SUBTYPES.key?(type)
|
|
647
|
+
|
|
648
|
+
@raw_type = SUBTYPES[type]
|
|
649
|
+
type
|
|
210
650
|
end
|
|
211
651
|
|
|
212
652
|
# Register this type when the module is loaded.
|