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.
Files changed (226) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +106 -7
  3. data/Rakefile +86 -43
  4. data/ext/bson/{native-endian.h → bson-endian.h} +14 -107
  5. data/ext/bson/bson-native.h +135 -0
  6. data/ext/bson/bytebuf.c +133 -0
  7. data/ext/bson/endian.c +117 -0
  8. data/ext/bson/extconf.rb +8 -3
  9. data/ext/bson/init.c +364 -0
  10. data/ext/bson/libbson-utf8.c +230 -0
  11. data/ext/bson/read.c +470 -0
  12. data/ext/bson/util.c +250 -0
  13. data/ext/bson/write.c +675 -0
  14. data/lib/bson/active_support.rb +19 -0
  15. data/lib/bson/array.rb +97 -30
  16. data/lib/bson/big_decimal.rb +77 -0
  17. data/lib/bson/binary.rb +510 -70
  18. data/lib/bson/boolean.rb +15 -4
  19. data/lib/bson/code.rb +25 -12
  20. data/lib/bson/code_with_scope.rb +41 -15
  21. data/lib/bson/config.rb +3 -28
  22. data/lib/bson/date.rb +16 -4
  23. data/lib/bson/date_time.rb +6 -4
  24. data/lib/bson/db_pointer.rb +110 -0
  25. data/lib/bson/dbref.rb +154 -0
  26. data/lib/bson/decimal128/builder.rb +456 -0
  27. data/lib/bson/decimal128.rb +272 -0
  28. data/lib/bson/document.rb +177 -7
  29. data/lib/bson/environment.rb +17 -2
  30. data/lib/bson/error/bson_decode_error.rb +11 -0
  31. data/lib/bson/error/ext_json_parse_error.rb +11 -0
  32. data/lib/bson/error/illegal_key.rb +23 -0
  33. data/lib/bson/error/invalid_binary_type.rb +37 -0
  34. data/lib/bson/error/invalid_dbref_argument.rb +12 -0
  35. data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
  36. data/lib/bson/error/invalid_decimal128_range.rb +27 -0
  37. data/lib/bson/error/invalid_decimal128_string.rb +26 -0
  38. data/lib/bson/error/invalid_key.rb +24 -0
  39. data/lib/bson/error/invalid_object_id.rb +11 -0
  40. data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
  41. data/lib/bson/error/unrepresentable_precision.rb +19 -0
  42. data/lib/bson/error/unserializable_class.rb +13 -0
  43. data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
  44. data/lib/bson/error/unsupported_type.rb +11 -0
  45. data/lib/bson/error.rb +22 -0
  46. data/lib/bson/ext_json.rb +389 -0
  47. data/lib/bson/false_class.rb +6 -4
  48. data/lib/bson/float.rb +43 -7
  49. data/lib/bson/hash.rb +152 -37
  50. data/lib/bson/int32.rb +104 -6
  51. data/lib/bson/int64.rb +111 -8
  52. data/lib/bson/integer.rb +43 -9
  53. data/lib/bson/json.rb +3 -1
  54. data/lib/bson/max_key.rb +21 -10
  55. data/lib/bson/min_key.rb +21 -10
  56. data/lib/bson/nil_class.rb +7 -3
  57. data/lib/bson/object.rb +25 -17
  58. data/lib/bson/object_id.rb +98 -113
  59. data/lib/bson/open_struct.rb +59 -0
  60. data/lib/bson/regexp.rb +129 -56
  61. data/lib/bson/registry.rb +7 -10
  62. data/lib/bson/specialized.rb +8 -4
  63. data/lib/bson/string.rb +12 -32
  64. data/lib/bson/symbol.rb +107 -11
  65. data/lib/bson/time.rb +68 -7
  66. data/lib/bson/time_with_zone.rb +67 -0
  67. data/lib/bson/timestamp.rb +50 -10
  68. data/lib/bson/true_class.rb +6 -4
  69. data/lib/bson/undefined.rb +28 -2
  70. data/lib/bson/vector.rb +44 -0
  71. data/lib/bson/version.rb +6 -14
  72. data/lib/bson.rb +22 -12
  73. data/spec/README.md +14 -0
  74. data/spec/bson/array_spec.rb +38 -62
  75. data/spec/bson/big_decimal_spec.rb +328 -0
  76. data/spec/bson/binary_spec.rb +199 -53
  77. data/spec/bson/binary_uuid_spec.rb +190 -0
  78. data/spec/bson/boolean_spec.rb +2 -1
  79. data/spec/bson/byte_buffer_read_spec.rb +198 -0
  80. data/spec/bson/byte_buffer_spec.rb +122 -381
  81. data/spec/bson/byte_buffer_write_spec.rb +855 -0
  82. data/spec/bson/code_spec.rb +6 -4
  83. data/spec/bson/code_with_scope_spec.rb +6 -4
  84. data/spec/bson/config_spec.rb +1 -35
  85. data/spec/bson/date_spec.rb +2 -1
  86. data/spec/bson/date_time_spec.rb +55 -1
  87. data/spec/bson/dbref_legacy_spec.rb +186 -0
  88. data/spec/bson/dbref_spec.rb +487 -0
  89. data/spec/bson/decimal128_spec.rb +1840 -0
  90. data/spec/bson/document_as_spec.rb +61 -0
  91. data/spec/bson/document_spec.rb +205 -32
  92. data/spec/bson/ext_json_parse_spec.rb +346 -0
  93. data/spec/bson/false_class_spec.rb +9 -1
  94. data/spec/bson/float_spec.rb +42 -1
  95. data/spec/bson/hash_as_spec.rb +58 -0
  96. data/spec/bson/hash_spec.rb +318 -66
  97. data/spec/bson/int32_spec.rb +248 -1
  98. data/spec/bson/int64_spec.rb +308 -1
  99. data/spec/bson/integer_spec.rb +61 -3
  100. data/spec/bson/json_spec.rb +2 -1
  101. data/spec/bson/max_key_spec.rb +6 -4
  102. data/spec/bson/min_key_spec.rb +6 -4
  103. data/spec/bson/nil_class_spec.rb +2 -1
  104. data/spec/bson/object_id_spec.rb +95 -5
  105. data/spec/bson/object_spec.rb +3 -2
  106. data/spec/bson/open_struct_spec.rb +87 -0
  107. data/spec/bson/raw_spec.rb +594 -0
  108. data/spec/bson/regexp_spec.rb +61 -8
  109. data/spec/bson/registry_spec.rb +3 -2
  110. data/spec/bson/string_spec.rb +26 -33
  111. data/spec/bson/symbol_raw_spec.rb +70 -0
  112. data/spec/bson/symbol_spec.rb +77 -20
  113. data/spec/bson/time_spec.rb +206 -2
  114. data/spec/bson/time_with_zone_spec.rb +69 -0
  115. data/spec/bson/timestamp_spec.rb +58 -2
  116. data/spec/bson/true_class_spec.rb +9 -1
  117. data/spec/bson/undefined_spec.rb +28 -1
  118. data/spec/bson/vector_spec.rb +33 -0
  119. data/spec/bson_spec.rb +2 -1
  120. data/spec/runners/binary_vector.rb +78 -0
  121. data/spec/runners/common_driver.rb +348 -0
  122. data/spec/runners/corpus.rb +191 -0
  123. data/spec/runners/corpus_legacy.rb +248 -0
  124. data/spec/shared/LICENSE +20 -0
  125. data/spec/shared/bin/get-mongodb-download-url +17 -0
  126. data/spec/shared/bin/s3-copy +45 -0
  127. data/spec/shared/bin/s3-upload +69 -0
  128. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  129. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  130. data/spec/shared/lib/mrss/constraints.rb +378 -0
  131. data/spec/shared/lib/mrss/docker_runner.rb +298 -0
  132. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  133. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  134. data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
  135. data/spec/shared/lib/mrss/release/candidate.rb +281 -0
  136. data/spec/shared/lib/mrss/release/product_data.rb +144 -0
  137. data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
  138. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  139. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  140. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  141. data/spec/shared/lib/mrss/utils.rb +37 -0
  142. data/spec/shared/lib/tasks/candidate.rake +64 -0
  143. data/spec/shared/share/Dockerfile.erb +251 -0
  144. data/spec/shared/share/haproxy-1.conf +16 -0
  145. data/spec/shared/share/haproxy-2.conf +17 -0
  146. data/spec/shared/shlib/config.sh +27 -0
  147. data/spec/shared/shlib/distro.sh +84 -0
  148. data/spec/shared/shlib/server.sh +423 -0
  149. data/spec/shared/shlib/set_env.sh +110 -0
  150. data/spec/spec_helper.rb +61 -1
  151. data/spec/spec_tests/binary_vector_spec.rb +82 -0
  152. data/spec/spec_tests/common_driver_spec.rb +84 -0
  153. data/spec/spec_tests/corpus_legacy_spec.rb +72 -0
  154. data/spec/spec_tests/corpus_spec.rb +134 -0
  155. data/spec/spec_tests/data/binary_vector/README.md +61 -0
  156. data/spec/spec_tests/data/binary_vector/float32.json +65 -0
  157. data/spec/spec_tests/data/binary_vector/int8.json +57 -0
  158. data/spec/spec_tests/data/binary_vector/packed_bit.json +83 -0
  159. data/spec/spec_tests/data/corpus/README.md +15 -0
  160. data/spec/spec_tests/data/corpus/array.json +49 -0
  161. data/spec/spec_tests/data/corpus/binary.json +153 -0
  162. data/spec/spec_tests/data/corpus/boolean.json +27 -0
  163. data/spec/spec_tests/data/corpus/code.json +67 -0
  164. data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
  165. data/spec/spec_tests/data/corpus/datetime.json +42 -0
  166. data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
  167. data/spec/spec_tests/data/corpus/dbref.json +51 -0
  168. data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
  169. data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
  170. data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
  171. data/spec/spec_tests/data/corpus/decimal128-4.json +165 -0
  172. data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
  173. data/spec/spec_tests/data/corpus/decimal128-6.json +131 -0
  174. data/spec/spec_tests/data/corpus/decimal128-7.json +327 -0
  175. data/spec/spec_tests/data/corpus/document.json +60 -0
  176. data/spec/spec_tests/data/corpus/double.json +87 -0
  177. data/spec/spec_tests/data/corpus/int32.json +43 -0
  178. data/spec/spec_tests/data/corpus/int64.json +43 -0
  179. data/spec/spec_tests/data/corpus/maxkey.json +12 -0
  180. data/spec/spec_tests/data/corpus/minkey.json +12 -0
  181. data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
  182. data/spec/spec_tests/data/corpus/multi-type.json +11 -0
  183. data/spec/spec_tests/data/corpus/null.json +12 -0
  184. data/spec/spec_tests/data/corpus/oid.json +28 -0
  185. data/spec/spec_tests/data/corpus/regex.json +65 -0
  186. data/spec/spec_tests/data/corpus/string.json +72 -0
  187. data/spec/spec_tests/data/corpus/symbol.json +80 -0
  188. data/spec/spec_tests/data/corpus/timestamp.json +34 -0
  189. data/spec/spec_tests/data/corpus/top.json +262 -0
  190. data/spec/spec_tests/data/corpus/undefined.json +15 -0
  191. data/spec/spec_tests/data/corpus_legacy/array.json +49 -0
  192. data/spec/spec_tests/data/corpus_legacy/binary.json +69 -0
  193. data/spec/spec_tests/data/corpus_legacy/boolean.json +27 -0
  194. data/spec/spec_tests/data/corpus_legacy/code.json +67 -0
  195. data/spec/spec_tests/data/corpus_legacy/code_w_scope.json +78 -0
  196. data/spec/spec_tests/data/corpus_legacy/document.json +36 -0
  197. data/spec/spec_tests/data/corpus_legacy/double.json +69 -0
  198. data/spec/spec_tests/data/corpus_legacy/failures/datetime.json +31 -0
  199. data/spec/spec_tests/data/corpus_legacy/failures/dbpointer.json +42 -0
  200. data/spec/spec_tests/data/corpus_legacy/failures/int64.json +38 -0
  201. data/spec/spec_tests/data/corpus_legacy/failures/symbol.json +62 -0
  202. data/spec/spec_tests/data/corpus_legacy/int32.json +38 -0
  203. data/spec/spec_tests/data/corpus_legacy/maxkey.json +12 -0
  204. data/spec/spec_tests/data/corpus_legacy/minkey.json +12 -0
  205. data/spec/spec_tests/data/corpus_legacy/null.json +12 -0
  206. data/spec/spec_tests/data/corpus_legacy/oid.json +28 -0
  207. data/spec/spec_tests/data/corpus_legacy/regex.json +37 -0
  208. data/spec/spec_tests/data/corpus_legacy/string.json +67 -0
  209. data/spec/spec_tests/data/corpus_legacy/timestamp.json +18 -0
  210. data/spec/spec_tests/data/corpus_legacy/top.json +62 -0
  211. data/spec/spec_tests/data/corpus_legacy/undefined.json +13 -0
  212. data/spec/spec_tests/data/decimal128/decimal128-1.json +363 -0
  213. data/spec/spec_tests/data/decimal128/decimal128-2.json +793 -0
  214. data/spec/spec_tests/data/decimal128/decimal128-3.json +1771 -0
  215. data/spec/spec_tests/data/decimal128/decimal128-4.json +165 -0
  216. data/spec/spec_tests/data/decimal128/decimal128-5.json +402 -0
  217. data/spec/spec_tests/data/decimal128/decimal128-6.json +131 -0
  218. data/spec/spec_tests/data/decimal128/decimal128-7.json +327 -0
  219. data/spec/support/shared_examples.rb +32 -11
  220. data/spec/support/spec_config.rb +17 -0
  221. data/spec/support/utils.rb +58 -0
  222. metadata +284 -45
  223. checksums.yaml.gz.sig +0 -3
  224. data/ext/bson/native.c +0 -722
  225. data.tar.gz.sig +0 -0
  226. metadata.gz.sig +0 -0
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:todo all
3
+ # Copyright (C) 2018-2020 MongoDB Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # Require this file if using BSON with ActiveSupport.
18
+
19
+ require "bson/time_with_zone"
data/lib/bson/array.rb CHANGED
@@ -1,4 +1,6 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # frozen_string_literal: true
2
+
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,8 @@
12
14
  # See the License for the specific language governing permissions and
13
15
  # limitations under the License.
14
16
 
17
+ # The top-level BSON module.
15
18
  module BSON
16
-
17
19
  # Injects behaviour for encoding and decoding arrays to
18
20
  # and from raw bytes as specified by the BSON spec.
19
21
  #
@@ -21,11 +23,10 @@ module BSON
21
23
  #
22
24
  # @since 2.0.0
23
25
  module Array
24
-
25
26
  # An array is type 0x04 in the BSON spec.
26
27
  #
27
28
  # @since 2.0.0
28
- BSON_TYPE = 4.chr.force_encoding(BINARY).freeze
29
+ BSON_TYPE = ::String.new(4.chr, encoding: BINARY).freeze
29
30
 
30
31
  # Get the array as encoded BSON.
31
32
  #
@@ -35,21 +36,30 @@ module BSON
35
36
  # @note Arrays are encoded as documents, where the index of the value in
36
37
  # the array is the actual key.
37
38
  #
38
- # @return [ String ] The encoded string.
39
+ # @return [ BSON::ByteBuffer ] The buffer with the encoded object.
39
40
  #
40
41
  # @see http://bsonspec.org/#/specification
41
42
  #
42
43
  # @since 2.0.0
43
- def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
44
- position = buffer.length
45
- buffer.put_int32(0)
46
- each_with_index do |value, index|
47
- buffer.put_byte(value.bson_type)
48
- buffer.put_cstring(index.to_s)
49
- value.to_bson(buffer, validating_keys)
44
+ def to_bson(buffer = ByteBuffer.new)
45
+ if buffer.respond_to?(:put_array)
46
+ buffer.put_array(self)
47
+ else
48
+ position = buffer.length
49
+ buffer.put_int32(0)
50
+ each_with_index do |value, index|
51
+ unless value.respond_to?(:bson_type)
52
+ raise Error::UnserializableClass,
53
+ "Array element at position #{index} does not define its BSON serialized type: #{value}"
54
+ end
55
+
56
+ buffer.put_byte(value.bson_type)
57
+ buffer.put_cstring(index.to_s)
58
+ value.to_bson(buffer)
59
+ end
60
+ buffer.put_byte(NULL_BYTE)
61
+ buffer.replace_int32(position, buffer.length - position)
50
62
  end
51
- buffer.put_byte(NULL_BYTE)
52
- buffer.replace_int32(position, buffer.length - position)
53
63
  end
54
64
 
55
65
  # Convert the array to an object id. This will only work for arrays of size
@@ -60,13 +70,13 @@ module BSON
60
70
  #
61
71
  # @note This is used for repairing legacy bson data.
62
72
  #
63
- # @raise [ InvalidObjectId ] If the array is not 12 elements.
73
+ # @raise [ BSON::Error::InvalidObjectId ] If the array is not 12 elements.
64
74
  #
65
75
  # @return [ String ] The raw object id bytes.
66
76
  #
67
77
  # @since 2.0.0
68
78
  def to_bson_object_id
69
- ObjectId.repair(self) { pack("C*") }
79
+ ObjectId.repair(self) { pack('C*') }
70
80
  end
71
81
 
72
82
  # Converts the array to a normalized value in a BSON document.
@@ -78,40 +88,97 @@ module BSON
78
88
  #
79
89
  # @since 3.0.0
80
90
  def to_bson_normalized_value
81
- map { |value| value.to_bson_normalized_value }
91
+ map(&:to_bson_normalized_value)
82
92
  end
83
93
 
84
- module ClassMethods
94
+ # Converts this object to a representation directly serializable to
95
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
96
+ #
97
+ # This method recursively invokes +as_extended_json+ with the provided
98
+ # options on each array element.
99
+ #
100
+ # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
101
+ # (default is canonical extended JSON)
102
+ #
103
+ # @return [ Array ] This array converted to extended json representation.
104
+ def as_extended_json(**options)
105
+ map do |item|
106
+ item.as_extended_json(**options)
107
+ end
108
+ end
85
109
 
110
+ # Class-level methods to be added to the Array class.
111
+ module ClassMethods
86
112
  # Deserialize the array from BSON.
87
113
  #
114
+ # @note If the argument cannot be parsed, an exception will be raised
115
+ # and the argument will be left in an undefined state. The caller
116
+ # must explicitly call `rewind` on the buffer before trying to parse
117
+ # it again.
118
+ #
88
119
  # @param [ ByteBuffer ] buffer The byte buffer.
89
120
  #
121
+ # @option options [ nil | :bson ] :mode Decoding mode to use.
122
+ #
90
123
  # @return [ Array ] The decoded array.
91
124
  #
92
125
  # @see http://bsonspec.org/#/specification
126
+ def from_bson(buffer, **options)
127
+ if buffer.respond_to?(:get_array)
128
+ buffer.get_array(**options)
129
+ else
130
+ parse_array_from_buffer(buffer, **options)
131
+ end
132
+ end
133
+
134
+ private
135
+
136
+ # Parse an array from the buffer.
137
+ #
138
+ # @param [ ByteBuf ] buffer the buffer to read from
139
+ # @param [ Hash ] options the optional keyword arguments
140
+ #
141
+ # @return [ Array ] the array that was parsed
142
+ #
143
+ # @raise [ BSON::Error::BSONDecodeError ] if the expected number of
144
+ # bytes were not read from the buffer
145
+ def parse_array_from_buffer(buffer, **options)
146
+ new.tap do |array|
147
+ start_position = buffer.read_position
148
+ expected_byte_size = buffer.get_int32
149
+ parse_array_elements_from_buffer(array, buffer, **options)
150
+ actual_byte_size = buffer.read_position - start_position
151
+ if actual_byte_size != expected_byte_size
152
+ raise Error::BSONDecodeError,
153
+ "Expected array to take #{expected_byte_size} bytes but it took #{actual_byte_size} bytes"
154
+ end
155
+ end
156
+ end
157
+
158
+ # Parse a sequence of array elements from the buffer.
93
159
  #
94
- # @since 2.0.0
95
- def from_bson(buffer)
96
- array = new
97
- buffer.get_int32 # throw away the length
160
+ # @param [ Array ] array the array to populate
161
+ # @param [ ByteBuf ] buffer the buffer to read from
162
+ # @param [ Hash ] options the optional keyword arguments
163
+ def parse_array_elements_from_buffer(array, buffer, **options)
98
164
  while (type = buffer.get_byte) != NULL_BYTE
99
165
  buffer.get_cstring
100
- array << BSON::Registry.get(type).from_bson(buffer)
166
+ cls = BSON::Registry.get(type)
167
+ value = if options.empty?
168
+ cls.from_bson(buffer)
169
+ else
170
+ cls.from_bson(buffer, **options)
171
+ end
172
+ array << value
101
173
  end
102
- array
103
174
  end
104
175
  end
105
176
 
106
177
  # Register this type when the module is loaded.
107
- #
108
- # @since 2.0.0
109
178
  Registry.register(BSON_TYPE, ::Array)
110
179
  end
111
180
 
112
181
  # Enrich the core Array class with this module.
113
- #
114
- # @since 2.0.0
115
- ::Array.send(:include, Array)
116
- ::Array.send(:extend, Array::ClassMethods)
182
+ ::Array.include Array
183
+ ::Array.extend Array::ClassMethods
117
184
  end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:todo all
3
+ # Copyright (C) 2009-2021 MongoDB Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module BSON
18
+
19
+ # Injects behaviour for encoding and decoding BigDecimals
20
+ # to and from raw bytes as specified by the BSON spec.
21
+ #
22
+ # @see http://bsonspec.org/#/specification
23
+ module BigDecimal
24
+
25
+ # BigDecimals are serialized as Decimal128s under the hood. A Decimal128
26
+ # is type 0x13 in the BSON spec.
27
+ BSON_TYPE = ::String.new(19.chr, encoding: BINARY).freeze
28
+
29
+ # Get the BigDecimal as encoded BSON.
30
+ #
31
+ # @example Get the BigDecimal as encoded BSON.
32
+ # BigDecimal("1").to_bson
33
+ #
34
+ # @return [ BSON::ByteBuffer ] The buffer with the encoded object.
35
+ #
36
+ # @see http://bsonspec.org/#/specification
37
+ def to_bson(buffer = ByteBuffer.new)
38
+ BSON::Decimal128.new(to_s).to_bson(buffer)
39
+ end
40
+
41
+ # Get the BSON type for BigDecimal. This is the same BSON type as
42
+ # BSON::Decimal128.
43
+ def bson_type
44
+ BSON_TYPE
45
+ end
46
+
47
+ module ClassMethods
48
+
49
+ # Deserialize the BigDecimal from raw BSON bytes. If the :mode option
50
+ # is set to BSON, this will return a BSON::Decimal128
51
+ #
52
+ # @example Get the BigDecimal from BSON.
53
+ # BigDecimal.from_bson(bson)
54
+ #
55
+ # @param [ ByteBuffer ] buffer The byte buffer.
56
+ #
57
+ # @option options [ nil | :bson ] :mode Decoding mode to use.
58
+ #
59
+ # @return [ BigDecimal | BSON::Decimal128 ] The decimal object.
60
+ def from_bson(buffer, **options)
61
+ dec128 = Decimal128.from_bson(buffer, **options)
62
+ if options[:mode] == :bson
63
+ dec128
64
+ else
65
+ dec128.to_d
66
+ end
67
+ end
68
+ end
69
+
70
+ # Register this type when the module is loaded.
71
+ Registry.register(BSON_TYPE, ::BigDecimal)
72
+ end
73
+
74
+ # Enrich the core BigDecimal class with this module.
75
+ ::BigDecimal.send(:include, BigDecimal)
76
+ ::BigDecimal.send(:extend, BigDecimal::ClassMethods)
77
+ end