bson 4.1.1 → 4.2.0.rc0
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 +0 -0
- data/Rakefile +18 -3
- data/ext/bson/{native.c → bson_native.c} +48 -8
- data/ext/bson/extconf.rb +1 -1
- data/ext/bson/native-endian.h +1 -1
- data/lib/bson.rb +3 -1
- data/lib/bson/config.rb +1 -1
- data/lib/bson/decimal128.rb +318 -0
- data/lib/bson/decimal128/builder.rb +448 -0
- data/lib/bson/document.rb +2 -2
- data/lib/bson/environment.rb +13 -1
- data/lib/bson/int32.rb +46 -0
- data/lib/bson/int64.rb +46 -0
- data/lib/bson/max_key.rb +1 -1
- data/lib/bson/min_key.rb +1 -1
- data/lib/bson/object_id.rb +2 -1
- data/lib/bson/open_struct.rb +57 -0
- data/lib/bson/regexp.rb +1 -1
- data/lib/bson/registry.rb +1 -1
- data/lib/bson/version.rb +2 -2
- data/spec/bson/decimal128_spec.rb +1583 -0
- data/spec/bson/document_spec.rb +1 -1
- data/spec/bson/driver_bson_spec.rb +77 -0
- data/spec/bson/int32_spec.rb +58 -0
- data/spec/bson/int64_spec.rb +58 -0
- data/spec/bson/open_struct_spec.rb +144 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/common_driver.rb +347 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-1.json +363 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-2.json +793 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-3.json +1771 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-4.json +165 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-5.json +402 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-6.json +131 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-7.json +327 -0
- metadata +29 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d09affc4bd194e0800ec1b21bc130b760ce0a34
|
4
|
+
data.tar.gz: d084710b111c72364781cfebb6492b51abd22f91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6db9a4decef8b08a8d16dcbbd16c299027209ae4e25c43edc67e8a629da779df2df144f875775ed9ffd7974d081d744d61926168207e3275fdb2dde25922f65e
|
7
|
+
data.tar.gz: 425e006755d2ea79ec961717e736f6cdac44b230364874815bafd056deef5dcbe4e7adc13e8fc2861ce95ae299292cb4fbff577612b3130018c7e8cbb83ba58f
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Rakefile
CHANGED
@@ -35,7 +35,7 @@ if jruby?
|
|
35
35
|
else
|
36
36
|
require "rake/extensiontask"
|
37
37
|
Rake::ExtensionTask.new do |ext|
|
38
|
-
ext.name = "
|
38
|
+
ext.name = "bson_native"
|
39
39
|
ext.ext_dir = "ext/bson"
|
40
40
|
ext.lib_dir = "lib"
|
41
41
|
end
|
@@ -64,8 +64,8 @@ end
|
|
64
64
|
task :clean_all => :clean do
|
65
65
|
begin
|
66
66
|
Dir.chdir(Pathname(__FILE__).dirname + "lib") do
|
67
|
-
`rm
|
68
|
-
`rm
|
67
|
+
`rm bson_native.#{extension}`
|
68
|
+
`rm bson_native.o`
|
69
69
|
`rm bson-ruby.jar`
|
70
70
|
end
|
71
71
|
rescue Exception => e
|
@@ -108,6 +108,21 @@ namespace :benchmark do
|
|
108
108
|
require "bson"
|
109
109
|
benchmark!
|
110
110
|
end
|
111
|
+
|
112
|
+
namespace :decimal128 do
|
113
|
+
|
114
|
+
task :from_string do
|
115
|
+
puts "Benchmarking creating Decimal128 objects from a string"
|
116
|
+
require 'bson'
|
117
|
+
benchmark_decimal128_from_string!
|
118
|
+
end
|
119
|
+
|
120
|
+
task :to_string do
|
121
|
+
puts "Benchmarking getting a string representation of a Decimal128"
|
122
|
+
require 'bson'
|
123
|
+
benchmark_decimal128_to_string!
|
124
|
+
end
|
125
|
+
end
|
111
126
|
end
|
112
127
|
|
113
128
|
task :default => [ :clean_all, :spec ]
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (C) 2009-
|
2
|
+
* Copyright (C) 2009-2016 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.
|
@@ -56,6 +56,7 @@ static VALUE rb_bson_byte_buffer_length(VALUE self);
|
|
56
56
|
static VALUE rb_bson_byte_buffer_get_byte(VALUE self);
|
57
57
|
static VALUE rb_bson_byte_buffer_get_bytes(VALUE self, VALUE i);
|
58
58
|
static VALUE rb_bson_byte_buffer_get_cstring(VALUE self);
|
59
|
+
static VALUE rb_bson_byte_buffer_get_decimal128_bytes(VALUE self);
|
59
60
|
static VALUE rb_bson_byte_buffer_get_double(VALUE self);
|
60
61
|
static VALUE rb_bson_byte_buffer_get_int32(VALUE self);
|
61
62
|
static VALUE rb_bson_byte_buffer_get_int64(VALUE self);
|
@@ -63,6 +64,7 @@ static VALUE rb_bson_byte_buffer_get_string(VALUE self);
|
|
63
64
|
static VALUE rb_bson_byte_buffer_put_byte(VALUE self, VALUE byte);
|
64
65
|
static VALUE rb_bson_byte_buffer_put_bytes(VALUE self, VALUE bytes);
|
65
66
|
static VALUE rb_bson_byte_buffer_put_cstring(VALUE self, VALUE string);
|
67
|
+
static VALUE rb_bson_byte_buffer_put_decimal128(VALUE self, VALUE low, VALUE high);
|
66
68
|
static VALUE rb_bson_byte_buffer_put_double(VALUE self, VALUE f);
|
67
69
|
static VALUE rb_bson_byte_buffer_put_int32(VALUE self, VALUE i);
|
68
70
|
static VALUE rb_bson_byte_buffer_put_int64(VALUE self, VALUE i);
|
@@ -96,9 +98,9 @@ static char rb_bson_machine_id_hash[HOST_NAME_HASH_MAX];
|
|
96
98
|
static uint32_t rb_bson_object_id_counter;
|
97
99
|
|
98
100
|
/**
|
99
|
-
* Initialize the
|
101
|
+
* Initialize the bson_native extension.
|
100
102
|
*/
|
101
|
-
void
|
103
|
+
void Init_bson_native()
|
102
104
|
{
|
103
105
|
char rb_bson_machine_id[256];
|
104
106
|
|
@@ -115,6 +117,7 @@ void Init_native()
|
|
115
117
|
rb_define_method(rb_byte_buffer_class, "get_byte", rb_bson_byte_buffer_get_byte, 0);
|
116
118
|
rb_define_method(rb_byte_buffer_class, "get_bytes", rb_bson_byte_buffer_get_bytes, 1);
|
117
119
|
rb_define_method(rb_byte_buffer_class, "get_cstring", rb_bson_byte_buffer_get_cstring, 0);
|
120
|
+
rb_define_method(rb_byte_buffer_class, "get_decimal128_bytes", rb_bson_byte_buffer_get_decimal128_bytes, 0);
|
118
121
|
rb_define_method(rb_byte_buffer_class, "get_double", rb_bson_byte_buffer_get_double, 0);
|
119
122
|
rb_define_method(rb_byte_buffer_class, "get_int32", rb_bson_byte_buffer_get_int32, 0);
|
120
123
|
rb_define_method(rb_byte_buffer_class, "get_int64", rb_bson_byte_buffer_get_int64, 0);
|
@@ -122,6 +125,7 @@ void Init_native()
|
|
122
125
|
rb_define_method(rb_byte_buffer_class, "put_byte", rb_bson_byte_buffer_put_byte, 1);
|
123
126
|
rb_define_method(rb_byte_buffer_class, "put_bytes", rb_bson_byte_buffer_put_bytes, 1);
|
124
127
|
rb_define_method(rb_byte_buffer_class, "put_cstring", rb_bson_byte_buffer_put_cstring, 1);
|
128
|
+
rb_define_method(rb_byte_buffer_class, "put_decimal128", rb_bson_byte_buffer_put_decimal128, 2);
|
125
129
|
rb_define_method(rb_byte_buffer_class, "put_double", rb_bson_byte_buffer_put_double, 1);
|
126
130
|
rb_define_method(rb_byte_buffer_class, "put_int32", rb_bson_byte_buffer_put_int32, 1);
|
127
131
|
rb_define_method(rb_byte_buffer_class, "put_int64", rb_bson_byte_buffer_put_int64, 1);
|
@@ -234,6 +238,21 @@ VALUE rb_bson_byte_buffer_get_cstring(VALUE self)
|
|
234
238
|
return string;
|
235
239
|
}
|
236
240
|
|
241
|
+
/**
|
242
|
+
* Get the 16 bytes representing the decimal128 from the buffer.
|
243
|
+
*/
|
244
|
+
VALUE rb_bson_byte_buffer_get_decimal128_bytes(VALUE self)
|
245
|
+
{
|
246
|
+
byte_buffer_t *b;
|
247
|
+
VALUE bytes;
|
248
|
+
|
249
|
+
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
250
|
+
ENSURE_BSON_READ(b, 16);
|
251
|
+
bytes = rb_str_new(READ_PTR(b), 16);
|
252
|
+
b->read_position += 16;
|
253
|
+
return bytes;
|
254
|
+
}
|
255
|
+
|
237
256
|
/**
|
238
257
|
* Get a double from the buffer.
|
239
258
|
*/
|
@@ -352,6 +371,27 @@ VALUE rb_bson_byte_buffer_put_cstring(VALUE self, VALUE string)
|
|
352
371
|
return self;
|
353
372
|
}
|
354
373
|
|
374
|
+
/**
|
375
|
+
* Writes a 128 bit decimal to the byte buffer.
|
376
|
+
*/
|
377
|
+
VALUE rb_bson_byte_buffer_put_decimal128(VALUE self, VALUE low, VALUE high)
|
378
|
+
{
|
379
|
+
byte_buffer_t *b;
|
380
|
+
const int64_t low64 = BSON_UINT64_TO_LE(NUM2ULL(low));
|
381
|
+
const int64_t high64 = BSON_UINT64_TO_LE(NUM2ULL(high));
|
382
|
+
|
383
|
+
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
384
|
+
ENSURE_BSON_WRITE(b, 8);
|
385
|
+
memcpy(WRITE_PTR(b), &low64, 8);
|
386
|
+
b->write_position += 8;
|
387
|
+
|
388
|
+
ENSURE_BSON_WRITE(b, 8);
|
389
|
+
memcpy(WRITE_PTR(b), &high64, 8);
|
390
|
+
b->write_position += 8;
|
391
|
+
|
392
|
+
return self;
|
393
|
+
}
|
394
|
+
|
355
395
|
/**
|
356
396
|
* Writes a 64 bit double to the buffer.
|
357
397
|
*/
|
@@ -361,7 +401,7 @@ VALUE rb_bson_byte_buffer_put_double(VALUE self, VALUE f)
|
|
361
401
|
const double d = BSON_DOUBLE_TO_LE(NUM2DBL(f));
|
362
402
|
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
363
403
|
ENSURE_BSON_WRITE(b, 8);
|
364
|
-
memcpy(WRITE_PTR(b),
|
404
|
+
memcpy(WRITE_PTR(b), &d, 8);
|
365
405
|
b->write_position += 8;
|
366
406
|
|
367
407
|
return self;
|
@@ -377,7 +417,7 @@ VALUE rb_bson_byte_buffer_put_int32(VALUE self, VALUE i)
|
|
377
417
|
|
378
418
|
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
379
419
|
ENSURE_BSON_WRITE(b, 4);
|
380
|
-
memcpy(WRITE_PTR(b),
|
420
|
+
memcpy(WRITE_PTR(b), &i32, 4);
|
381
421
|
b->write_position += 4;
|
382
422
|
|
383
423
|
return self;
|
@@ -393,7 +433,7 @@ VALUE rb_bson_byte_buffer_put_int64(VALUE self, VALUE i)
|
|
393
433
|
|
394
434
|
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
395
435
|
ENSURE_BSON_WRITE(b, 8);
|
396
|
-
memcpy(WRITE_PTR(b),
|
436
|
+
memcpy(WRITE_PTR(b), &i64, 8);
|
397
437
|
b->write_position += 8;
|
398
438
|
|
399
439
|
return self;
|
@@ -417,7 +457,7 @@ VALUE rb_bson_byte_buffer_put_string(VALUE self, VALUE string)
|
|
417
457
|
|
418
458
|
TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
|
419
459
|
ENSURE_BSON_WRITE(b, length + 4);
|
420
|
-
memcpy(WRITE_PTR(b),
|
460
|
+
memcpy(WRITE_PTR(b), &length_le, 4);
|
421
461
|
b->write_position += 4;
|
422
462
|
memcpy(WRITE_PTR(b), str, length);
|
423
463
|
b->write_position += length;
|
@@ -550,7 +590,7 @@ VALUE rb_bson_object_id_generator_next(int argc, VALUE* args, VALUE self)
|
|
550
590
|
memcpy(&bytes, &t, 4);
|
551
591
|
memcpy(&bytes[4], rb_bson_machine_id_hash, 3);
|
552
592
|
memcpy(&bytes[7], &pid, 2);
|
553
|
-
memcpy(&bytes[9],
|
593
|
+
memcpy(&bytes[9], &c, 3);
|
554
594
|
rb_bson_object_id_counter++;
|
555
595
|
return rb_str_new(bytes, 12);
|
556
596
|
}
|
data/ext/bson/extconf.rb
CHANGED
data/ext/bson/native-endian.h
CHANGED
data/lib/bson.rb
CHANGED
@@ -70,10 +70,12 @@ require "bson/code"
|
|
70
70
|
require "bson/code_with_scope"
|
71
71
|
require "bson/date"
|
72
72
|
require "bson/date_time"
|
73
|
+
require "bson/decimal128"
|
73
74
|
require "bson/document"
|
74
75
|
require "bson/false_class"
|
75
76
|
require "bson/float"
|
76
77
|
require "bson/hash"
|
78
|
+
require "bson/open_struct"
|
77
79
|
require "bson/max_key"
|
78
80
|
require "bson/min_key"
|
79
81
|
require "bson/nil_class"
|
@@ -98,7 +100,7 @@ begin
|
|
98
100
|
require "bson-ruby.jar"
|
99
101
|
org.bson.NativeService.new.basicLoad(JRuby.runtime)
|
100
102
|
else
|
101
|
-
require "
|
103
|
+
require "bson_native"
|
102
104
|
end
|
103
105
|
rescue LoadError
|
104
106
|
$stderr.puts("BSON is using the pure Ruby implementation.")
|
data/lib/bson/config.rb
CHANGED
@@ -0,0 +1,318 @@
|
|
1
|
+
# Copyright (C) 2016 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 'bigdecimal'
|
16
|
+
require 'bson/decimal128/builder'
|
17
|
+
|
18
|
+
module BSON
|
19
|
+
|
20
|
+
class Decimal128
|
21
|
+
|
22
|
+
# A Decimal128 is type 0x13 in the BSON spec.
|
23
|
+
#
|
24
|
+
# @since 4.2.0
|
25
|
+
BSON_TYPE = 19.chr.force_encoding(BINARY).freeze
|
26
|
+
|
27
|
+
# Exponent offset.
|
28
|
+
#
|
29
|
+
# @since 4.2.0
|
30
|
+
EXPONENT_OFFSET = 6176.freeze
|
31
|
+
|
32
|
+
# Minimum exponent.
|
33
|
+
#
|
34
|
+
# @since 4.2.0
|
35
|
+
MIN_EXPONENT = -6176.freeze
|
36
|
+
|
37
|
+
# Maximum exponent.
|
38
|
+
#
|
39
|
+
# @since 4.2.0
|
40
|
+
MAX_EXPONENT = 6111.freeze
|
41
|
+
|
42
|
+
# Maximum digits of precision.
|
43
|
+
#
|
44
|
+
# @since 4.2.0
|
45
|
+
MAX_DIGITS_OF_PRECISION = 34.freeze
|
46
|
+
|
47
|
+
# Key for this type when converted to extended json.
|
48
|
+
#
|
49
|
+
# @since 4.2.0
|
50
|
+
EXTENDED_JSON_KEY = "$numberDecimal".freeze
|
51
|
+
|
52
|
+
# The native type to which this object can be converted.
|
53
|
+
#
|
54
|
+
# @since 4.2.0
|
55
|
+
NATIVE_TYPE = BigDecimal.freeze
|
56
|
+
|
57
|
+
# Get the Decimal128 as JSON hash data.
|
58
|
+
#
|
59
|
+
# @example Get the Decimal128 as a JSON hash.
|
60
|
+
# decimal.as_json
|
61
|
+
#
|
62
|
+
# @return [ Hash ] The number as a JSON hash.
|
63
|
+
#
|
64
|
+
# @since 4.2.0
|
65
|
+
def as_json(*args)
|
66
|
+
{ EXTENDED_JSON_KEY => to_s }
|
67
|
+
end
|
68
|
+
|
69
|
+
# Check equality of the decimal128 object with another object.
|
70
|
+
#
|
71
|
+
# @example Check if the decimal128 object is equal to the other.
|
72
|
+
# decimal == other
|
73
|
+
#
|
74
|
+
# @param [ Object ] other The object to check against.
|
75
|
+
#
|
76
|
+
# @return [ true, false ] If the objects are equal.
|
77
|
+
#
|
78
|
+
# @since 4.2.0
|
79
|
+
def ==(other)
|
80
|
+
return false unless other.is_a?(Decimal128)
|
81
|
+
@high == other.instance_variable_get(:@high) &&
|
82
|
+
@low == other.instance_variable_get(:@low)
|
83
|
+
end
|
84
|
+
alias :eql? :==
|
85
|
+
|
86
|
+
# Create a new Decimal128 from a BigDecimal.
|
87
|
+
#
|
88
|
+
# @example Create a Decimal128 from a BigDecimal.
|
89
|
+
# Decimal128.new(big_decimal)
|
90
|
+
#
|
91
|
+
# @param [ String, BigDecimal ] object The BigDecimal or String to use for
|
92
|
+
# instantiating a Decimal128.
|
93
|
+
#
|
94
|
+
# @raise [ InvalidBigDecimal ] Raise error unless object argument is a BigDecimal.
|
95
|
+
#
|
96
|
+
# @since 4.2.0
|
97
|
+
def initialize(object)
|
98
|
+
if object.is_a?(String)
|
99
|
+
set_bits(*Builder::FromString.new(object).bits)
|
100
|
+
elsif object.is_a?(BigDecimal)
|
101
|
+
set_bits(*Builder::FromBigDecimal.new(object).bits)
|
102
|
+
else
|
103
|
+
raise InvalidArgument.new
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Get the decimal128 as its raw BSON data.
|
108
|
+
#
|
109
|
+
# @example Get the raw bson bytes in a buffer.
|
110
|
+
# decimal.to_bson
|
111
|
+
#
|
112
|
+
# @return [ BSON::ByteBuffer ] The raw bytes in a buffer.
|
113
|
+
#
|
114
|
+
# @see http://bsonspec.org/#/specification
|
115
|
+
#
|
116
|
+
# @since 4.2.0
|
117
|
+
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
118
|
+
buffer.put_decimal128(@low, @high)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Get the hash value for the decimal128.
|
122
|
+
#
|
123
|
+
# @example Get the hash value.
|
124
|
+
# decimal.hash
|
125
|
+
#
|
126
|
+
# @return [ Integer ] The hash value.
|
127
|
+
#
|
128
|
+
# @since 4.2.0
|
129
|
+
def hash
|
130
|
+
num = @high << 64
|
131
|
+
num |= @low
|
132
|
+
num.hash
|
133
|
+
end
|
134
|
+
|
135
|
+
# Get a nice string for use with object inspection.
|
136
|
+
#
|
137
|
+
# @example Inspect the decimal128 object.
|
138
|
+
# decimal128.inspect
|
139
|
+
#
|
140
|
+
# @return [ String ] The decimal as a string.
|
141
|
+
#
|
142
|
+
# @since 4.2.0
|
143
|
+
def inspect
|
144
|
+
"BSON::Decimal128('#{to_s}')"
|
145
|
+
end
|
146
|
+
|
147
|
+
# Get the string representation of the decimal128.
|
148
|
+
#
|
149
|
+
# @example Get the decimal128 as a string.
|
150
|
+
# decimal128.to_s
|
151
|
+
#
|
152
|
+
# @return [ String ] The decimal128 as a string.
|
153
|
+
#
|
154
|
+
# @since 4.2.0
|
155
|
+
def to_s
|
156
|
+
@string ||= Builder::ToString.new(self).string
|
157
|
+
end
|
158
|
+
alias :to_str :to_s
|
159
|
+
|
160
|
+
# Get a Ruby BigDecimal object corresponding to this Decimal128.
|
161
|
+
# Note that, when converting to a Ruby BigDecimal, non-zero significant digits
|
162
|
+
# are preserved but trailing zeroes may be lost.
|
163
|
+
# See the following example:
|
164
|
+
#
|
165
|
+
# @example
|
166
|
+
# decimal128 = BSON::Decimal128.new("0.200")
|
167
|
+
# => BSON::Decimal128('0.200')
|
168
|
+
# big_decimal = decimal128.to_big_decimal
|
169
|
+
# => #<BigDecimal:7fc619c95388,'0.2E0',9(18)>
|
170
|
+
# big_decimal.to_s
|
171
|
+
# => "0.2E0"
|
172
|
+
#
|
173
|
+
# Note that the the BSON::Decimal128 object can represent -NaN, sNaN,
|
174
|
+
# and -sNaN while Ruby's BigDecimal cannot.
|
175
|
+
#
|
176
|
+
# @return [ BigDecimal ] The decimal as a BigDecimal.
|
177
|
+
#
|
178
|
+
# @since 4.2.0
|
179
|
+
def to_big_decimal
|
180
|
+
@big_decimal ||= BigDecimal.new(to_s)
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
def set_bits(low, high)
|
186
|
+
@low = low
|
187
|
+
@high = high
|
188
|
+
end
|
189
|
+
|
190
|
+
class << self
|
191
|
+
|
192
|
+
# Deserialize the decimal128 from raw BSON bytes.
|
193
|
+
#
|
194
|
+
# @example Get the decimal128 from BSON.
|
195
|
+
# Decimal128.from_bson(bson)
|
196
|
+
#
|
197
|
+
# @param [ ByteBuffer ] buffer The byte buffer.
|
198
|
+
#
|
199
|
+
# @return [ BSON::Decimal128 ] The decimal object.
|
200
|
+
#
|
201
|
+
# @since 4.2.0
|
202
|
+
def from_bson(buffer)
|
203
|
+
from_bits(*buffer.get_decimal128_bytes.unpack('Q*'))
|
204
|
+
end
|
205
|
+
|
206
|
+
# Instantiate a Decimal128 from a string.
|
207
|
+
#
|
208
|
+
# @example Create a Decimal128 from a string.
|
209
|
+
# BSON::Decimal128.from_string("1.05E+3")
|
210
|
+
#
|
211
|
+
# @param [ String ] string The string to parse.
|
212
|
+
#
|
213
|
+
# @raise [ BSON::Decimal128::InvalidString ] If the provided string is invalid.
|
214
|
+
#
|
215
|
+
# @return [ BSON::Decimal128 ] The new decimal128.
|
216
|
+
#
|
217
|
+
# @since 4.2.0
|
218
|
+
def from_string(string)
|
219
|
+
from_bits(*Builder::FromString.new(string).bits)
|
220
|
+
end
|
221
|
+
|
222
|
+
# Instantiate a Decimal128 from high and low bits.
|
223
|
+
#
|
224
|
+
# @example Create a Decimal128 from high and low bits.
|
225
|
+
# BSON::Decimal128.from_bits(high, low)
|
226
|
+
#
|
227
|
+
# @param [ Integer ] high The high order bits.
|
228
|
+
# @param [ Integer ] low The low order bits.
|
229
|
+
#
|
230
|
+
# @return [ BSON::Decimal128 ] The new decimal128.
|
231
|
+
#
|
232
|
+
# @since 4.2.0
|
233
|
+
def from_bits(low, high)
|
234
|
+
decimal = allocate
|
235
|
+
decimal.send(:set_bits, low, high)
|
236
|
+
decimal
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# Raised when trying to create a Decimal128 from an object that is neither a String nor a BigDecimal.
|
241
|
+
#
|
242
|
+
# @api private
|
243
|
+
#
|
244
|
+
# @since 4.2.0
|
245
|
+
class InvalidArgument < ArgumentError
|
246
|
+
|
247
|
+
# The custom error message for this error.
|
248
|
+
#
|
249
|
+
# @since 4.2.0
|
250
|
+
MESSAGE = 'A Decimal128 can only be created from a String or BigDecimal.'.freeze
|
251
|
+
|
252
|
+
# Get the custom error message for the exception.
|
253
|
+
#
|
254
|
+
# @example Get the message.
|
255
|
+
# error.message
|
256
|
+
#
|
257
|
+
# @return [ String ] The error message.
|
258
|
+
#
|
259
|
+
# @since 4.2.0
|
260
|
+
def message
|
261
|
+
MESSAGE
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# Raised when trying to create a Decimal128 from a string with
|
266
|
+
# an invalid format.
|
267
|
+
#
|
268
|
+
# @api private
|
269
|
+
#
|
270
|
+
# @since 4.2.0
|
271
|
+
class InvalidString < RuntimeError
|
272
|
+
|
273
|
+
# The custom error message for this error.
|
274
|
+
#
|
275
|
+
# @since 4.2.0
|
276
|
+
MESSAGE = 'Invalid string format for creating a Decimal128 object.'.freeze
|
277
|
+
|
278
|
+
# Get the custom error message for the exception.
|
279
|
+
#
|
280
|
+
# @example Get the message.
|
281
|
+
# error.message
|
282
|
+
#
|
283
|
+
# @return [ String ] The error message.
|
284
|
+
#
|
285
|
+
# @since 4.2.0
|
286
|
+
def message
|
287
|
+
MESSAGE
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
# Raised when the exponent or significand provided is outside the valid range.
|
292
|
+
#
|
293
|
+
# @api private
|
294
|
+
#
|
295
|
+
# @since 4.2.0
|
296
|
+
class InvalidRange < RuntimeError
|
297
|
+
|
298
|
+
# The custom error message for this error.
|
299
|
+
#
|
300
|
+
# @since 4.2.0
|
301
|
+
MESSAGE = 'Value out of range for Decimal128 representation.'.freeze
|
302
|
+
|
303
|
+
# Get the custom error message for the exception.
|
304
|
+
#
|
305
|
+
# @example Get the message.
|
306
|
+
# error.message
|
307
|
+
#
|
308
|
+
# @return [ String ] The error message.
|
309
|
+
#
|
310
|
+
# @since 4.2.0
|
311
|
+
def message
|
312
|
+
MESSAGE
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
Registry.register(BSON_TYPE, self)
|
317
|
+
end
|
318
|
+
end
|