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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +0 -0
- data/CONTRIBUTING.md +0 -0
- data/LICENSE.md +13 -0
- data/README.md +185 -0
- data/Rakefile +83 -0
- data/ext/bson/extconf.rb +3 -0
- data/lib/bson.rb +105 -94
- data/lib/bson/array.rb +74 -0
- data/lib/bson/binary.rb +125 -0
- data/lib/bson/boolean.rb +35 -0
- data/lib/bson/code.rb +96 -0
- data/lib/bson/code_with_scope.rb +105 -0
- data/lib/bson/document.rb +536 -0
- data/lib/bson/encodable.rb +73 -0
- data/lib/bson/false_class.rb +48 -0
- data/lib/bson/float.rb +69 -0
- data/lib/bson/hash.rb +71 -0
- data/lib/bson/int32.rb +46 -0
- data/lib/bson/int64.rb +46 -0
- data/lib/bson/integer.rb +172 -0
- data/lib/bson/json.rb +26 -0
- data/lib/bson/max_key.rb +57 -0
- data/lib/bson/min_key.rb +57 -0
- data/lib/bson/nil_class.rb +57 -0
- data/lib/bson/object_id.rb +309 -0
- data/lib/bson/regexp.rb +111 -0
- data/lib/bson/registry.rb +57 -0
- data/lib/bson/specialized.rb +61 -0
- data/lib/bson/string.rb +173 -0
- data/lib/bson/symbol.rb +74 -0
- data/lib/bson/time.rb +59 -0
- data/lib/bson/timestamp.rb +100 -0
- data/lib/bson/true_class.rb +48 -0
- data/lib/bson/undefined.rb +61 -0
- data/lib/bson/version.rb +4 -0
- metadata +52 -40
- data/LICENSE +0 -190
- data/VERSION +0 -1
- data/bin/b2json +0 -63
- data/bin/j2bson +0 -64
- data/bson.gemspec +0 -34
- data/lib/bson/bson_c.rb +0 -37
- data/lib/bson/bson_java.rb +0 -49
- data/lib/bson/bson_ruby.rb +0 -645
- data/lib/bson/byte_buffer.rb +0 -241
- data/lib/bson/exceptions.rb +0 -37
- data/lib/bson/grow.rb +0 -173
- data/lib/bson/ordered_hash.rb +0 -197
- data/lib/bson/support/hash_with_indifferent_access.rb +0 -174
- data/lib/bson/types/binary.rb +0 -52
- data/lib/bson/types/code.rb +0 -55
- data/lib/bson/types/dbref.rb +0 -40
- data/lib/bson/types/min_max_keys.rb +0 -56
- data/lib/bson/types/object_id.rb +0 -226
- data/lib/bson/types/regex.rb +0 -116
- data/lib/bson/types/timestamp.rb +0 -72
data/lib/bson/regexp.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module BSON
|
3
|
+
|
4
|
+
# Injects behaviour for encoding and decoding regular expression values 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 Regexp
|
11
|
+
include JSON
|
12
|
+
|
13
|
+
# A regular expression is type 0x0B in the BSON spec.
|
14
|
+
#
|
15
|
+
# @since 2.0.0
|
16
|
+
BSON_TYPE = 11.chr.force_encoding(BINARY).freeze
|
17
|
+
|
18
|
+
# Get the regexp as JSON hash data.
|
19
|
+
#
|
20
|
+
# @example Get the regexp as a JSON hash.
|
21
|
+
# regexp.as_json
|
22
|
+
#
|
23
|
+
# @return [ Hash ] The regexp as a JSON hash.
|
24
|
+
#
|
25
|
+
# @since 2.0.0
|
26
|
+
def as_json(*args)
|
27
|
+
{ "$regex" => source, "$options" => bson_options }
|
28
|
+
end
|
29
|
+
|
30
|
+
# Get the regular expression as encoded BSON.
|
31
|
+
#
|
32
|
+
# @example Get the regular expression as encoded BSON.
|
33
|
+
# %r{\d+}.to_bson
|
34
|
+
#
|
35
|
+
# @note From the BSON spec: The first cstring is the regex pattern,
|
36
|
+
# the second is the regex options string. Options are identified
|
37
|
+
# by characters, which must be stored in alphabetical order.
|
38
|
+
# Valid options are 'i' for case insensitive matching,
|
39
|
+
# 'm' for multiline matching, 'x' for verbose mode,
|
40
|
+
# 'l' to make \w, \W, etc. locale dependent,
|
41
|
+
# 's' for dotall mode ('.' matches everything),
|
42
|
+
# and 'u' to make \w, \W, etc. match unicode.
|
43
|
+
#
|
44
|
+
# @return [ String ] The encoded string.
|
45
|
+
#
|
46
|
+
# @see http://bsonspec.org/#/specification
|
47
|
+
#
|
48
|
+
# @since 2.0.0
|
49
|
+
def to_bson(encoded = ''.force_encoding(BINARY))
|
50
|
+
source.to_bson_cstring(encoded)
|
51
|
+
bson_options.to_bson_cstring(encoded)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def bson_options
|
57
|
+
bson_ignorecase + bson_multiline + bson_extended
|
58
|
+
end
|
59
|
+
|
60
|
+
def bson_extended
|
61
|
+
(options & ::Regexp::EXTENDED != 0) ? "x" : NO_VALUE
|
62
|
+
end
|
63
|
+
|
64
|
+
def bson_ignorecase
|
65
|
+
(options & ::Regexp::IGNORECASE != 0) ? "i" : NO_VALUE
|
66
|
+
end
|
67
|
+
|
68
|
+
def bson_multiline
|
69
|
+
(options & ::Regexp::MULTILINE != 0) ? "ms" : NO_VALUE
|
70
|
+
end
|
71
|
+
|
72
|
+
module ClassMethods
|
73
|
+
# Deserialize the regular expression from BSON.
|
74
|
+
#
|
75
|
+
# @param [ BSON ] bson The bson representing a regular expression.
|
76
|
+
#
|
77
|
+
# @return [ Regexp ] The decoded regular expression.
|
78
|
+
#
|
79
|
+
# @see http://bsonspec.org/#/specification
|
80
|
+
#
|
81
|
+
# @since 2.0.0
|
82
|
+
def from_bson(bson)
|
83
|
+
pattern = bson.gets(NULL_BYTE).from_bson_string.chop!
|
84
|
+
options = 0
|
85
|
+
while (option = bson.readbyte) != 0
|
86
|
+
case option
|
87
|
+
when 105 # 'i'
|
88
|
+
options |= ::Regexp::IGNORECASE
|
89
|
+
when 109, 115 # 'm', 's'
|
90
|
+
options |= ::Regexp::MULTILINE
|
91
|
+
when 120 # 'x'
|
92
|
+
options |= ::Regexp::EXTENDED
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
new(pattern, options)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Register this type when the module is loaded.
|
101
|
+
#
|
102
|
+
# @since 2.0.0
|
103
|
+
Registry.register(BSON_TYPE, ::Regexp)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Enrich the core Regexp class with this module.
|
107
|
+
#
|
108
|
+
# @since 2.0.0
|
109
|
+
::Regexp.send(:include, Regexp)
|
110
|
+
::Regexp.send(:extend, Regexp::ClassMethods)
|
111
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module BSON
|
3
|
+
|
4
|
+
# Provides constant values for each to the BSON types and mappings from raw
|
5
|
+
# bytes back to these types.
|
6
|
+
#
|
7
|
+
# @see http://bsonspec.org/#/specification
|
8
|
+
#
|
9
|
+
# @since 2.0.0
|
10
|
+
module Registry
|
11
|
+
extend self
|
12
|
+
|
13
|
+
# A Mapping of all the BSON types to their corresponding Ruby classes.
|
14
|
+
#
|
15
|
+
# @since 2.0.0
|
16
|
+
MAPPINGS = {}
|
17
|
+
|
18
|
+
# Get the class for the single byte identifier for the type in the BSON
|
19
|
+
# specification.
|
20
|
+
#
|
21
|
+
# @example Get the type for the byte.
|
22
|
+
# BSON::Registry.get("\x01")
|
23
|
+
#
|
24
|
+
# @return [ Class ] The corresponding Ruby class for the type.
|
25
|
+
#
|
26
|
+
# @see http://bsonspec.org/#/specification
|
27
|
+
#
|
28
|
+
# @since 2.0.0
|
29
|
+
def get(byte)
|
30
|
+
MAPPINGS.fetch(byte)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Register the Ruby type for the corresponding single byte.
|
34
|
+
#
|
35
|
+
# @example Register the type.
|
36
|
+
# BSON::Registry.register("\x01", Float)
|
37
|
+
#
|
38
|
+
# @param [ String ] byte The single byte.
|
39
|
+
# @param [ Class ] The class the byte maps to.
|
40
|
+
#
|
41
|
+
# @return [ Class ] The class.
|
42
|
+
#
|
43
|
+
# @since 2.0.0
|
44
|
+
def register(byte, type)
|
45
|
+
MAPPINGS.store(byte, type)
|
46
|
+
define_type_reader(type)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def define_type_reader(type)
|
52
|
+
type.module_eval <<-MOD
|
53
|
+
def bson_type; BSON_TYPE; end
|
54
|
+
MOD
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module BSON
|
3
|
+
|
4
|
+
# Provides behaviour to special values that exist in the BSON spec that don't
|
5
|
+
# have a native type, like $minKey and $maxKey.
|
6
|
+
#
|
7
|
+
# @see http://bsonspec.org/#/specification
|
8
|
+
#
|
9
|
+
# @since 2.0.0
|
10
|
+
module Specialized
|
11
|
+
|
12
|
+
# Determine if the min key is equal to another object.
|
13
|
+
#
|
14
|
+
# @example Check min key equality.
|
15
|
+
# BSON::MinKey.new == object
|
16
|
+
#
|
17
|
+
# @param [ Object ] other The object to check against.
|
18
|
+
#
|
19
|
+
# @return [ true, false ] If the objects are equal.
|
20
|
+
#
|
21
|
+
# @since 2.0.0
|
22
|
+
def ==(other)
|
23
|
+
self.class == other.class
|
24
|
+
end
|
25
|
+
|
26
|
+
# Encode the min key - has no value since it only needs the type and field
|
27
|
+
# name when being encoded.
|
28
|
+
#
|
29
|
+
# @example Encode the min key value.
|
30
|
+
# min_key.to_bson
|
31
|
+
#
|
32
|
+
# @return [ String ] An empty string.
|
33
|
+
#
|
34
|
+
# @since 2.0.0
|
35
|
+
def to_bson(encoded = ''.force_encoding(BINARY))
|
36
|
+
encoded
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def self.included(klass)
|
42
|
+
klass.extend(ClassMethods)
|
43
|
+
end
|
44
|
+
|
45
|
+
module ClassMethods
|
46
|
+
|
47
|
+
# Deserialize MinKey from BSON.
|
48
|
+
#
|
49
|
+
# @param [ BSON ] bson The encoded MinKey.
|
50
|
+
#
|
51
|
+
# @return [ MinKey ] The decoded MinKey.
|
52
|
+
#
|
53
|
+
# @see http://bsonspec.org/#/specification
|
54
|
+
#
|
55
|
+
# @since 2.0.0
|
56
|
+
def from_bson(bson)
|
57
|
+
new
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/bson/string.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module BSON
|
3
|
+
|
4
|
+
# Injects behaviour for encoding and decoding string 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 String
|
11
|
+
include Encodable
|
12
|
+
|
13
|
+
# A string is type 0x02 in the BSON spec.
|
14
|
+
#
|
15
|
+
# @since 2.0.0
|
16
|
+
BSON_TYPE = 2.chr.force_encoding(BINARY).freeze
|
17
|
+
|
18
|
+
# Get the string as encoded BSON.
|
19
|
+
#
|
20
|
+
# @example Get the string as encoded BSON.
|
21
|
+
# "test".to_bson
|
22
|
+
#
|
23
|
+
# @raise [ EncodingError ] If the string is not UTF-8.
|
24
|
+
#
|
25
|
+
# @return [ String ] The encoded string.
|
26
|
+
#
|
27
|
+
# @see http://bsonspec.org/#/specification
|
28
|
+
#
|
29
|
+
# @since 2.0.0
|
30
|
+
def to_bson(encoded = ''.force_encoding(BINARY))
|
31
|
+
encode_with_placeholder_and_null(STRING_ADJUST, encoded) do |encoded|
|
32
|
+
to_bson_string(encoded)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Get the string as a BSON key name encoded C string with checking for special characters.
|
37
|
+
#
|
38
|
+
# @example Get the string as key name.
|
39
|
+
# "test".to_bson_key
|
40
|
+
#
|
41
|
+
# @raise [ EncodingError ] If the string is not UTF-8.
|
42
|
+
#
|
43
|
+
# @return [ String ] The encoded string.
|
44
|
+
#
|
45
|
+
# @see http://bsonspec.org/#/specification
|
46
|
+
#
|
47
|
+
# @since 2.0.0
|
48
|
+
def to_bson_key(encoded = ''.force_encoding(BINARY))
|
49
|
+
check_for_illegal_characters!
|
50
|
+
to_bson_cstring(encoded)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get the string as an encoded C string.
|
54
|
+
#
|
55
|
+
# @example Get the string as an encoded C string.
|
56
|
+
# "test".to_bson_cstring
|
57
|
+
#
|
58
|
+
# @raise [ EncodingError ] If the string is not UTF-8.
|
59
|
+
#
|
60
|
+
# @return [ String ] The encoded string.
|
61
|
+
#
|
62
|
+
# @see http://bsonspec.org/#/specification
|
63
|
+
#
|
64
|
+
# @since 2.0.0
|
65
|
+
def to_bson_cstring(encoded = ''.force_encoding(BINARY))
|
66
|
+
check_for_illegal_characters!
|
67
|
+
to_bson_string(encoded) << NULL_BYTE
|
68
|
+
end
|
69
|
+
|
70
|
+
# Convert the string to a UTF-8 string then force to binary. This is so
|
71
|
+
# we get errors for strings that are not UTF-8 encoded.
|
72
|
+
#
|
73
|
+
# @example Convert to valid BSON string.
|
74
|
+
# "Straße".to_bson_string
|
75
|
+
#
|
76
|
+
# @raise [ EncodingError ] If the string is not UTF-8.
|
77
|
+
#
|
78
|
+
# @return [ String ] The binary string.
|
79
|
+
#
|
80
|
+
# @since 2.0.0
|
81
|
+
def to_bson_string(encoded = ''.force_encoding(BINARY))
|
82
|
+
begin
|
83
|
+
to_utf8_binary(encoded)
|
84
|
+
rescue EncodingError
|
85
|
+
data = dup.force_encoding(UTF8)
|
86
|
+
raise unless data.valid_encoding?
|
87
|
+
encoded << data.force_encoding(BINARY)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Convert the string to a hexidecimal representation.
|
92
|
+
#
|
93
|
+
# @example Convert the string to hex.
|
94
|
+
# "\x01".to_hex_string
|
95
|
+
#
|
96
|
+
# @return [ String ] The string as hex.
|
97
|
+
#
|
98
|
+
# @since 2.0.0
|
99
|
+
def to_hex_string
|
100
|
+
unpack("H*")[0]
|
101
|
+
end
|
102
|
+
|
103
|
+
# Take the binary string and return a UTF-8 encoded string.
|
104
|
+
#
|
105
|
+
# @example Convert from a BSON string.
|
106
|
+
# "\x00".from_bson_string
|
107
|
+
#
|
108
|
+
# @raise [ EncodingError ] If the string is not UTF-8.
|
109
|
+
#
|
110
|
+
# @return [ String ] The UTF-8 string.
|
111
|
+
#
|
112
|
+
# @since 2.0.0
|
113
|
+
def from_bson_string
|
114
|
+
force_encoding(UTF8)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Set four bytes for int32 in a binary string and return it.
|
118
|
+
#
|
119
|
+
# @example Set int32 in a BSON string.
|
120
|
+
# "".set_int32(pos, int32)
|
121
|
+
#
|
122
|
+
# @param [ Fixnum ] The position to set.
|
123
|
+
# @param [ Fixnum ] The int32 value.
|
124
|
+
#
|
125
|
+
# @return [ String ] The binary string.
|
126
|
+
#
|
127
|
+
# @since 2.0.0
|
128
|
+
def set_int32(pos, int32)
|
129
|
+
self[pos, 4] = [ int32 ].pack(Int32::PACK)
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def to_utf8_binary(encoded)
|
135
|
+
encoded << encode(UTF8).force_encoding(BINARY)
|
136
|
+
end
|
137
|
+
|
138
|
+
module ClassMethods
|
139
|
+
|
140
|
+
# Deserialize a string from BSON.
|
141
|
+
#
|
142
|
+
# @param [ BSON ] bson The bson representing a string.
|
143
|
+
#
|
144
|
+
# @return [ Regexp ] The decoded string.
|
145
|
+
#
|
146
|
+
# @see http://bsonspec.org/#/specification
|
147
|
+
#
|
148
|
+
# @since 2.0.0
|
149
|
+
def from_bson(bson)
|
150
|
+
bson.read(Int32.from_bson(bson)).from_bson_string.chop!
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
def check_for_illegal_characters!
|
157
|
+
if include?(NULL_BYTE)
|
158
|
+
raise RuntimeError.new("Illegal C-String '#{self}' contains a null byte.")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Register this type when the module is loaded.
|
163
|
+
#
|
164
|
+
# @since 2.0.0
|
165
|
+
Registry.register(BSON_TYPE, ::String)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Enrich the core String class with this module.
|
169
|
+
#
|
170
|
+
# @since 2.0.0
|
171
|
+
::String.send(:include, String)
|
172
|
+
::String.send(:extend, String::ClassMethods)
|
173
|
+
end
|
data/lib/bson/symbol.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module BSON
|
3
|
+
|
4
|
+
# Injects behaviour for encoding and decoding symbol values to and from
|
5
|
+
# raw bytes as specified by the BSON spec.
|
6
|
+
#
|
7
|
+
# @note Symbols are deprecated in the BSON spec, but they are still
|
8
|
+
# currently supported here for backwards compatibility.
|
9
|
+
#
|
10
|
+
# @see http://bsonspec.org/#/specification
|
11
|
+
#
|
12
|
+
# @since 2.0.0
|
13
|
+
module Symbol
|
14
|
+
|
15
|
+
# A symbol is type 0x0E in the BSON spec.
|
16
|
+
#
|
17
|
+
# @since 2.0.0
|
18
|
+
BSON_TYPE = 14.chr.force_encoding(BINARY).freeze
|
19
|
+
|
20
|
+
# Get the symbol as encoded BSON.
|
21
|
+
#
|
22
|
+
# @example Get the symbol as encoded BSON.
|
23
|
+
# :test.to_bson
|
24
|
+
#
|
25
|
+
# @return [ Symbol ] The encoded symbol.
|
26
|
+
#
|
27
|
+
# @see http://bsonspec.org/#/specification
|
28
|
+
#
|
29
|
+
# @since 2.0.0
|
30
|
+
def to_bson(encoded = ''.force_encoding(BINARY))
|
31
|
+
to_s.to_bson(encoded)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Get the symbol as a BSON key name encoded C symbol.
|
35
|
+
#
|
36
|
+
# @example Get the symbol as a key name.
|
37
|
+
# :test.to_bson_key
|
38
|
+
#
|
39
|
+
# @return [ String ] The encoded symbol as a BSON key.
|
40
|
+
#
|
41
|
+
# @see http://bsonspec.org/#/specification
|
42
|
+
#
|
43
|
+
# @since 2.0.0
|
44
|
+
def to_bson_key(encoded = ''.force_encoding(BINARY))
|
45
|
+
to_s.to_bson_cstring(encoded)
|
46
|
+
end
|
47
|
+
|
48
|
+
module ClassMethods
|
49
|
+
# Deserialize a symbol from BSON.
|
50
|
+
#
|
51
|
+
# @param [ BSON ] bson The bson representing a symbol.
|
52
|
+
#
|
53
|
+
# @return [ Regexp ] The decoded symbol.
|
54
|
+
#
|
55
|
+
# @see http://bsonspec.org/#/specification
|
56
|
+
#
|
57
|
+
# @since 2.0.0
|
58
|
+
def from_bson(bson)
|
59
|
+
bson.read(Int32.from_bson(bson)).from_bson_string.chop!.intern
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Register this type when the module is loaded.
|
64
|
+
#
|
65
|
+
# @since 2.0.0
|
66
|
+
Registry.register(BSON_TYPE, ::Symbol)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Enrich the core Symbol class with this module.
|
70
|
+
#
|
71
|
+
# @since 2.0.0
|
72
|
+
::Symbol.send(:include, Symbol)
|
73
|
+
::Symbol.send(:extend, Symbol::ClassMethods)
|
74
|
+
end
|