bson 1.12.5 → 2.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bson might be problematic. Click here for more details.

Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -0
  3. data/CONTRIBUTING.md +0 -0
  4. data/LICENSE.md +13 -0
  5. data/README.md +185 -0
  6. data/Rakefile +83 -0
  7. data/ext/bson/extconf.rb +3 -0
  8. data/lib/bson.rb +105 -94
  9. data/lib/bson/array.rb +74 -0
  10. data/lib/bson/binary.rb +125 -0
  11. data/lib/bson/boolean.rb +35 -0
  12. data/lib/bson/code.rb +96 -0
  13. data/lib/bson/code_with_scope.rb +105 -0
  14. data/lib/bson/document.rb +536 -0
  15. data/lib/bson/encodable.rb +73 -0
  16. data/lib/bson/false_class.rb +48 -0
  17. data/lib/bson/float.rb +69 -0
  18. data/lib/bson/hash.rb +71 -0
  19. data/lib/bson/int32.rb +46 -0
  20. data/lib/bson/int64.rb +46 -0
  21. data/lib/bson/integer.rb +172 -0
  22. data/lib/bson/json.rb +26 -0
  23. data/lib/bson/max_key.rb +57 -0
  24. data/lib/bson/min_key.rb +57 -0
  25. data/lib/bson/nil_class.rb +57 -0
  26. data/lib/bson/object_id.rb +309 -0
  27. data/lib/bson/regexp.rb +111 -0
  28. data/lib/bson/registry.rb +57 -0
  29. data/lib/bson/specialized.rb +61 -0
  30. data/lib/bson/string.rb +173 -0
  31. data/lib/bson/symbol.rb +74 -0
  32. data/lib/bson/time.rb +59 -0
  33. data/lib/bson/timestamp.rb +100 -0
  34. data/lib/bson/true_class.rb +48 -0
  35. data/lib/bson/undefined.rb +61 -0
  36. data/lib/bson/version.rb +4 -0
  37. metadata +52 -40
  38. data/LICENSE +0 -190
  39. data/VERSION +0 -1
  40. data/bin/b2json +0 -63
  41. data/bin/j2bson +0 -64
  42. data/bson.gemspec +0 -34
  43. data/lib/bson/bson_c.rb +0 -37
  44. data/lib/bson/bson_java.rb +0 -49
  45. data/lib/bson/bson_ruby.rb +0 -645
  46. data/lib/bson/byte_buffer.rb +0 -241
  47. data/lib/bson/exceptions.rb +0 -37
  48. data/lib/bson/grow.rb +0 -173
  49. data/lib/bson/ordered_hash.rb +0 -197
  50. data/lib/bson/support/hash_with_indifferent_access.rb +0 -174
  51. data/lib/bson/types/binary.rb +0 -52
  52. data/lib/bson/types/code.rb +0 -55
  53. data/lib/bson/types/dbref.rb +0 -40
  54. data/lib/bson/types/min_max_keys.rb +0 -56
  55. data/lib/bson/types/object_id.rb +0 -226
  56. data/lib/bson/types/regex.rb +0 -116
  57. data/lib/bson/types/timestamp.rb +0 -72
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+ module BSON
3
+
4
+ # Defines behaviour around objects that can be encoded.
5
+ #
6
+ # @since 2.0.0
7
+ module Encodable
8
+
9
+ # A 4 byte placeholder that would be replaced by a length at a later point.
10
+ #
11
+ # @since 2.0.0
12
+ PLACEHOLDER = 0.to_bson.freeze
13
+
14
+ # Adjustment value for total number of document bytes.
15
+ #
16
+ # @since 2.0.0
17
+ BSON_ADJUST = 0.freeze
18
+
19
+ # Adjustment value for total number of string bytes.
20
+ #
21
+ # @since 2.0.0
22
+ STRING_ADJUST = -4.freeze
23
+
24
+ # Encodes BSON to raw bytes, for types that require the length of the
25
+ # entire bytes to be present as the first word of the encoded string. This
26
+ # includes Hash, CodeWithScope.
27
+ #
28
+ # @example Encode the BSON with placeholder bytes.
29
+ # hash.encode_with_placeholder_and_null(BSON_ADJUST, encoded) do |encoded|
30
+ # each do |field, value|
31
+ # value.to_bson(encoded)
32
+ # end
33
+ # end
34
+ #
35
+ # @param [ Integer ] adjust The number of bytes to adjust with.
36
+ # @param [ String ] encoded The string to encode.
37
+ #
38
+ # @return [ String ] The encoded string.
39
+ #
40
+ # @since 2.0.0
41
+ def encode_with_placeholder_and_null(adjust, encoded = ''.force_encoding(BINARY))
42
+ pos = encoded.bytesize
43
+ encoded << PLACEHOLDER
44
+ yield(encoded)
45
+ encoded << NULL_BYTE
46
+ encoded.set_int32(pos, encoded.bytesize - pos + adjust)
47
+ encoded
48
+ end
49
+
50
+ # Encodes binary data with a generic placeholder value to be written later
51
+ # once all bytes have been written.
52
+ #
53
+ # @example Encode the BSON with placeholder bytes.
54
+ # string.encode_binary_data_with_placeholder(encoded) do |encoded|
55
+ # each do |field, value|
56
+ # value.to_bson(encoded)
57
+ # end
58
+ # end
59
+ #
60
+ # @param [ String ] encoded The string to encode.
61
+ #
62
+ # @return [ String ] The encoded string.
63
+ #
64
+ # @since 2.0.0
65
+ def encode_binary_data_with_placeholder(encoded = ''.force_encoding(BINARY))
66
+ pos = encoded.bytesize
67
+ encoded << PLACEHOLDER
68
+ yield(encoded)
69
+ encoded.set_int32(pos, encoded.bytesize - pos - 5)
70
+ encoded
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ module BSON
3
+
4
+ # Injects behaviour for encoding and decoding false values to and from
5
+ # raw bytes as specified by the BSON spec.
6
+ #
7
+ # @see http://bsonspec.org/#/specification
8
+ #
9
+ # @since 2.0.0
10
+ module FalseClass
11
+
12
+ # A false value in the BSON spec is 0x00.
13
+ #
14
+ # @since 2.0.0
15
+ FALSE_BYTE = 0.chr.force_encoding(BINARY).freeze
16
+
17
+ # The BSON type for false values is the general boolean type of 0x08.
18
+ #
19
+ # @example Get the bson type.
20
+ # false.bson_type
21
+ #
22
+ # @return [ String ] The character 0x08.
23
+ #
24
+ # @since 2.0.0
25
+ def bson_type
26
+ Boolean::BSON_TYPE
27
+ end
28
+
29
+ # Get the false boolean as encoded BSON.
30
+ #
31
+ # @example Get the false boolean as encoded BSON.
32
+ # false.to_bson
33
+ #
34
+ # @return [ String ] The encoded string.
35
+ #
36
+ # @see http://bsonspec.org/#/specification
37
+ #
38
+ # @since 2.0.0
39
+ def to_bson(encoded = ''.force_encoding(BINARY))
40
+ encoded << FALSE_BYTE
41
+ end
42
+ end
43
+
44
+ # Enrich the core FalseClass class with this module.
45
+ #
46
+ # @since 2.0.0
47
+ ::FalseClass.send(:include, FalseClass)
48
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+ module BSON
3
+
4
+ # Injects behaviour for encoding and decoding floating point values
5
+ # to and from # raw bytes as specified by the BSON spec.
6
+ #
7
+ # @see http://bsonspec.org/#/specification
8
+ #
9
+ # @since 2.0.0
10
+ module Float
11
+
12
+ # A floating point is type 0x01 in the BSON spec.
13
+ #
14
+ # @since 2.0.0
15
+ BSON_TYPE = 1.chr.force_encoding(BINARY).freeze
16
+
17
+ # The pack directive is for 8 byte floating points.
18
+ #
19
+ # @since 2.0.0
20
+ PACK = "E".freeze
21
+
22
+ # Get the floating point as encoded BSON.
23
+ #
24
+ # @example Get the floating point as encoded BSON.
25
+ # 1.221311.to_bson
26
+ #
27
+ # @return [ String ] The encoded string.
28
+ #
29
+ # @see http://bsonspec.org/#/specification
30
+ #
31
+ # @since 2.0.0
32
+ def to_bson(encoded = ''.force_encoding(BINARY))
33
+ encoded << [ self ].pack(PACK)
34
+ end
35
+
36
+ module ClassMethods
37
+
38
+ # Deserialize an instance of a Float from a BSON double.
39
+ #
40
+ # @param [ BSON ] bson The encoded double.
41
+ #
42
+ # @return [ Float ] The decoded Float.
43
+ #
44
+ # @see http://bsonspec.org/#/specification
45
+ #
46
+ # @since 2.0.0
47
+ def from_bson(bson)
48
+ from_bson_double(bson.read(8))
49
+ end
50
+
51
+ private
52
+
53
+ def from_bson_double(double)
54
+ double.unpack(PACK).first
55
+ end
56
+ end
57
+
58
+ # Register this type when the module is loaded.
59
+ #
60
+ # @since 2.0.0
61
+ Registry.register(BSON_TYPE, ::Float)
62
+ end
63
+
64
+ # Enrich the core Float class with this module.
65
+ #
66
+ # @since 2.0.0
67
+ ::Float.send(:include, Float)
68
+ ::Float.send(:extend, Float::ClassMethods)
69
+ end
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+ module BSON
3
+
4
+ # Injects behaviour for encoding and decoding hashes to
5
+ # and from raw bytes as specified by the BSON spec.
6
+ #
7
+ # @see http://bsonspec.org/#/specification
8
+ #
9
+ # @since 2.0.0
10
+ module Hash
11
+ include Encodable
12
+
13
+ # An hash (embedded document) is type 0x03 in the BSON spec.
14
+ #
15
+ # @since 2.0.0
16
+ BSON_TYPE = 3.chr.force_encoding(BINARY).freeze
17
+
18
+ # Get the hash as encoded BSON.
19
+ #
20
+ # @example Get the hash as encoded BSON.
21
+ # { field: "value" }.to_bson
22
+ #
23
+ # @return [ String ] The encoded string.
24
+ #
25
+ # @see http://bsonspec.org/#/specification
26
+ #
27
+ # @since 2.0.0
28
+ def to_bson(encoded = ''.force_encoding(BINARY))
29
+ encode_with_placeholder_and_null(BSON_ADJUST, encoded) do |encoded|
30
+ each do |field, value|
31
+ encoded << value.bson_type
32
+ field.to_bson_key(encoded)
33
+ value.to_bson(encoded)
34
+ end
35
+ end
36
+ end
37
+
38
+ module ClassMethods
39
+
40
+ # Deserialize the hash from BSON.
41
+ #
42
+ # @param [ String ] bson The bson representing a hash.
43
+ #
44
+ # @return [ Array ] The decoded hash.
45
+ #
46
+ # @see http://bsonspec.org/#/specification
47
+ #
48
+ # @since 2.0.0
49
+ def from_bson(bson)
50
+ hash = new
51
+ bson.read(4) # Swallow the first four bytes.
52
+ while (type = bson.readbyte.chr) != NULL_BYTE
53
+ field = bson.gets(NULL_BYTE).from_bson_string.chop!
54
+ hash[field] = BSON::Registry.get(type).from_bson(bson)
55
+ end
56
+ hash
57
+ end
58
+ end
59
+
60
+ # Register this type when the module is loaded.
61
+ #
62
+ # @since 2.0.0
63
+ Registry.register(BSON_TYPE, ::Hash)
64
+ end
65
+
66
+ # Enrich the core Hash class with this module.
67
+ #
68
+ # @since 2.0.0
69
+ ::Hash.send(:include, Hash)
70
+ ::Hash.send(:extend, Hash::ClassMethods)
71
+ end
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+ module BSON
3
+
4
+ # Represents a $maxKey type, which compares less than any other value in the
5
+ # specification.
6
+ #
7
+ # @see http://bsonspec.org/#/specification
8
+ #
9
+ # @since 2.0.0
10
+ class Int32
11
+
12
+ # A boolean is type 0x08 in the BSON spec.
13
+ #
14
+ # @since 2.0.0
15
+ BSON_TYPE = 16.chr.force_encoding(BINARY).freeze
16
+
17
+ # Constant for the int 32 pack directive.
18
+ #
19
+ # @since 2.0.0
20
+ PACK = ruby_18? ? "l".freeze : "l<".freeze
21
+
22
+ # Deserialize an Integer from BSON.
23
+ #
24
+ # @param [ BSON ] bson The encoded int32.
25
+ #
26
+ # @return [ Integer ] The decoded Integer.
27
+ #
28
+ # @see http://bsonspec.org/#/specification
29
+ #
30
+ # @since 2.0.0
31
+ def self.from_bson(bson)
32
+ from_bson_int32(bson.read(4))
33
+ end
34
+
35
+ private
36
+
37
+ def self.from_bson_int32(bytes)
38
+ bytes.unpack(PACK).first
39
+ end
40
+
41
+ # Register this type when the module is loaded.
42
+ #
43
+ # @since 2.0.0
44
+ Registry.register(BSON_TYPE, self)
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+ module BSON
3
+
4
+ # Represents a $maxKey type, which compares less than any other value in the
5
+ # specification.
6
+ #
7
+ # @see http://bsonspec.org/#/specification
8
+ #
9
+ # @since 2.0.0
10
+ class Int64
11
+
12
+ # A boolean is type 0x08 in the BSON spec.
13
+ #
14
+ # @since 2.0.0
15
+ BSON_TYPE = 18.chr.force_encoding(BINARY).freeze
16
+
17
+ # Constant for the int 64 pack directive.
18
+ #
19
+ # @since 2.0.0
20
+ PACK = ruby_18? ? "q".freeze : "q<".freeze
21
+
22
+ # Deserialize an Integer from BSON.
23
+ #
24
+ # @param [ BSON ] bson The encoded int64.
25
+ #
26
+ # @return [ Integer ] The decoded Integer.
27
+ #
28
+ # @see http://bsonspec.org/#/specification
29
+ #
30
+ # @since 2.0.0
31
+ def self.from_bson(bson)
32
+ from_bson_int64(bson.read(8))
33
+ end
34
+
35
+ private
36
+
37
+ def self.from_bson_int64(bytes)
38
+ bytes.unpack(PACK).first
39
+ end
40
+
41
+ # Register this type when the module is loaded.
42
+ #
43
+ # @since 2.0.0
44
+ Registry.register(BSON_TYPE, self)
45
+ end
46
+ end
@@ -0,0 +1,172 @@
1
+ # encoding: utf-8
2
+ module BSON
3
+
4
+ # Injects behaviour for encoding and decoding integer values to and from
5
+ # raw bytes as specified by the BSON spec.
6
+ #
7
+ # @see http://bsonspec.org/#/specification
8
+ #
9
+ # @since 2.0.0
10
+ module Integer
11
+
12
+ # A 32bit integer is type 0x10 in the BSON spec.
13
+ #
14
+ # @since 2.0.0
15
+ INT32_TYPE = 16.chr.force_encoding(BINARY).freeze
16
+
17
+ # A 64bit integer is type 0x12 in the BSON spec.
18
+ #
19
+ # @since 2.0.0
20
+ INT64_TYPE = 18.chr.force_encoding(BINARY).freeze
21
+
22
+ # The maximum 32 bit integer value.
23
+ #
24
+ # @since 2.0.0
25
+ MAX_32BIT = (1 << 31) - 1
26
+
27
+ # The maximum 64 bit integer value.
28
+ #
29
+ # @since 2.0.0
30
+ MAX_64BIT = (1 << 63) - 1
31
+
32
+ # The minimum 32 bit integer value.
33
+ #
34
+ # @since 2.0.0
35
+ MIN_32BIT = -(1 << 31)
36
+
37
+ # The minimum 64 bit integer value.
38
+ #
39
+ # @since 2.0.0
40
+ MIN_64BIT = -(1 << 63)
41
+
42
+ # The BSON index size.
43
+ #
44
+ # @since 2.0.0
45
+ BSON_INDEX_SIZE = 1024.freeze
46
+
47
+ # A hash of index values for array optimization.
48
+ #
49
+ # @since 2.0.0
50
+ BSON_ARRAY_INDEXES = ::Array.new(BSON_INDEX_SIZE) do |i|
51
+ (i.to_s.force_encoding(BINARY) << NULL_BYTE).freeze
52
+ end.freeze
53
+
54
+ # Is this integer a valid BSON 32 bit value?
55
+ #
56
+ # @example Is the integer a valid 32 bit value?
57
+ # 1024.bson_int32?
58
+ #
59
+ # @return [ true, false ] If the integer is 32 bit.
60
+ #
61
+ # @since 2.0.0
62
+ def bson_int32?
63
+ (MIN_32BIT <= self) && (self <= MAX_32BIT)
64
+ end
65
+
66
+ # Is this integer a valid BSON 64 bit value?
67
+ #
68
+ # @example Is the integer a valid 64 bit value?
69
+ # 1024.bson_int64?
70
+ #
71
+ # @return [ true, false ] If the integer is 64 bit.
72
+ #
73
+ # @since 2.0.0
74
+ def bson_int64?
75
+ (MIN_64BIT <= self) && (self <= MAX_64BIT)
76
+ end
77
+
78
+ # Get the BSON type for this integer. Will depend on whether the integer
79
+ # is 32 bit or 64 bit.
80
+ #
81
+ # @example Get the BSON type for the integer.
82
+ # 1024.bson_type
83
+ #
84
+ # @return [ String ] The single byte BSON type.
85
+ #
86
+ # @see http://bsonspec.org/#/specification
87
+ #
88
+ # @since 2.0.0
89
+ def bson_type
90
+ bson_int32? ? INT32_TYPE : (bson_int64? ? INT64_TYPE : out_of_range!)
91
+ end
92
+
93
+ # Get the integer as encoded BSON.
94
+ #
95
+ # @example Get the integer as encoded BSON.
96
+ # 1024.to_bson
97
+ #
98
+ # @return [ String ] The encoded string.
99
+ #
100
+ # @see http://bsonspec.org/#/specification
101
+ #
102
+ # @since 2.0.0
103
+ def to_bson(encoded = ''.force_encoding(BINARY))
104
+ if bson_int32?
105
+ to_bson_int32(encoded)
106
+ elsif bson_int64?
107
+ to_bson_int64(encoded)
108
+ else
109
+ out_of_range!
110
+ end
111
+ end
112
+
113
+ # Convert the integer to a 32 bit (4 bytes) raw bytes string.
114
+ #
115
+ # @example Convert the integer to it's 32 bit bytes.
116
+ # 1024.to_bson_int32
117
+ #
118
+ # @param [ String ] encoded The string to encode to.
119
+ #
120
+ # @return [ String ] The encoded string.
121
+ #
122
+ # @since 2.0.0
123
+ def to_bson_int32(encoded)
124
+ append_bson_int32(encoded)
125
+ end
126
+
127
+ # Convert the integer to a 64 bit (8 bytes) raw bytes string.
128
+ #
129
+ # @example Convert the integer to it's 64 bit bytes.
130
+ # 1024.to_bson_int64
131
+ #
132
+ # @param [ String ] encoded The string to encode to.
133
+ #
134
+ # @return [ String ] The encoded string.
135
+ #
136
+ # @since 2.0.0
137
+ def to_bson_int64(encoded)
138
+ append_bson_int32(encoded)
139
+ encoded << ((self >> 32) & 255)
140
+ encoded << ((self >> 40) & 255)
141
+ encoded << ((self >> 48) & 255)
142
+ encoded << ((self >> 56) & 255)
143
+ end
144
+
145
+ def to_bson_key(encoded = ''.force_encoding(BINARY))
146
+ if self < BSON_INDEX_SIZE
147
+ encoded << BSON_ARRAY_INDEXES[self]
148
+ else
149
+ self.to_s.to_bson_cstring(encoded)
150
+ end
151
+ end
152
+
153
+ private
154
+
155
+ def append_bson_int32(encoded)
156
+ encoded << (self & 255)
157
+ encoded << ((self >> 8) & 255)
158
+ encoded << ((self >> 16) & 255)
159
+ encoded << ((self >> 24) & 255)
160
+ end
161
+
162
+ def out_of_range!
163
+ raise RangeError.new("#{self} is not a valid 8 byte integer value.")
164
+ end
165
+
166
+ end
167
+
168
+ # Enrich the core Integer class with this module.
169
+ #
170
+ # @since 2.0.0
171
+ ::Integer.send(:include, Integer)
172
+ end