bson 1.2.0-jruby

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.

@@ -0,0 +1,276 @@
1
+ # encoding: UTF-8
2
+
3
+ # --
4
+ # Copyright (C) 2008-2011 10gen Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ # ++
18
+
19
+ # A byte buffer.
20
+ module BSON
21
+ class ByteBuffer
22
+
23
+ attr_reader :order
24
+
25
+ def initialize(initial_data="")
26
+ @str = case initial_data
27
+ when String then
28
+ if initial_data.respond_to?(:force_encoding)
29
+ initial_data.force_encoding('binary')
30
+ else
31
+ initial_data
32
+ end
33
+ when BSON::ByteBuffer then
34
+ initial_data.to_a.pack('C*')
35
+ else
36
+ initial_data.pack('C*')
37
+ end
38
+
39
+ @cursor = @str.length
40
+ @order = :little_endian
41
+ @int_pack_order = 'V'
42
+ @double_pack_order = 'E'
43
+ end
44
+
45
+ if RUBY_VERSION >= '1.9'
46
+ NULL_BYTE = "\0".force_encoding('binary').freeze
47
+ UTF8_ENCODING = Encoding.find('utf-8')
48
+ BINARY_ENCODING = Encoding.find('binary')
49
+
50
+ def self.to_utf8_binary(str)
51
+ str.encode(UTF8_ENCODING).force_encoding(BINARY_ENCODING)
52
+ end
53
+ else
54
+ NULL_BYTE = "\0"
55
+
56
+ def self.to_utf8_binary(str)
57
+ begin
58
+ str.unpack("U*")
59
+ rescue => ex
60
+ raise InvalidStringEncoding, "String not valid utf-8: #{str.inspect}"
61
+ end
62
+ str
63
+ end
64
+ end
65
+
66
+ def self.serialize_cstr(buf, val)
67
+ buf.append!(to_utf8_binary(val.to_s))
68
+ buf.append!(NULL_BYTE)
69
+ end
70
+
71
+ # +endianness+ should be :little_endian or :big_endian. Default is :little_endian
72
+ def order=(endianness)
73
+ @order = endianness
74
+ @int_pack_order = endianness == :little_endian ? 'V' : 'N'
75
+ @double_pack_order = endianness == :little_endian ? 'E' : 'G'
76
+ end
77
+
78
+ def rewind
79
+ @cursor = 0
80
+ end
81
+
82
+ def position
83
+ @cursor
84
+ end
85
+
86
+ def position=(val)
87
+ @cursor = val
88
+ end
89
+
90
+ def clear
91
+ @str = ""
92
+ @str.force_encoding('binary') if @str.respond_to?(:force_encoding)
93
+ rewind
94
+ end
95
+
96
+ def size
97
+ @str.size
98
+ end
99
+ alias_method :length, :size
100
+
101
+ # Appends a second ByteBuffer object, +buffer+, to the current buffer.
102
+ def append!(buffer)
103
+ @str << buffer.to_s
104
+ self
105
+ end
106
+
107
+ # Prepends a second ByteBuffer object, +buffer+, to the current buffer.
108
+ def prepend!(buffer)
109
+ @str = buffer.to_s + @str
110
+ self
111
+ end
112
+
113
+ def put(byte, offset=nil)
114
+ @cursor = offset if offset
115
+ if more?
116
+ @str[@cursor] = chr(byte)
117
+ else
118
+ ensure_length(@cursor)
119
+ @str << chr(byte)
120
+ end
121
+ @cursor += 1
122
+ end
123
+
124
+ def put_binary(data, offset=nil)
125
+ @cursor = offset if offset
126
+ if defined?(BINARY_ENCODING)
127
+ data = data.dup.force_encoding(BINARY_ENCODING)
128
+ end
129
+ if more?
130
+ @str[@cursor, data.length] = data
131
+ else
132
+ ensure_length(@cursor)
133
+ @str << data
134
+ end
135
+ @cursor += data.length
136
+ end
137
+
138
+ def put_array(array, offset=nil)
139
+ @cursor = offset if offset
140
+ if more?
141
+ @str[@cursor, array.length] = array.pack("C*")
142
+ else
143
+ ensure_length(@cursor)
144
+ @str << array.pack("C*")
145
+ end
146
+ @cursor += array.length
147
+ end
148
+
149
+ def put_int(i, offset=nil)
150
+ @cursor = offset if offset
151
+ if more?
152
+ @str[@cursor, 4] = [i].pack(@int_pack_order)
153
+ else
154
+ ensure_length(@cursor)
155
+ @str << [i].pack(@int_pack_order)
156
+ end
157
+ @cursor += 4
158
+ end
159
+
160
+ def put_long(i, offset=nil)
161
+ offset = @cursor unless offset
162
+ if @int_pack_order == 'N'
163
+ put_int(i >> 32, offset)
164
+ put_int(i & 0xffffffff, offset + 4)
165
+ else
166
+ put_int(i & 0xffffffff, offset)
167
+ put_int(i >> 32, offset + 4)
168
+ end
169
+ end
170
+
171
+ def put_double(d, offset=nil)
172
+ a = []
173
+ [d].pack(@double_pack_order).each_byte { |b| a << b }
174
+ put_array(a, offset)
175
+ end
176
+
177
+ # If +size+ == nil, returns one byte. Else returns array of bytes of length
178
+ # # +size+.
179
+ if "x"[0].is_a?(Integer)
180
+ def get(len=nil)
181
+ one_byte = len.nil?
182
+ len ||= 1
183
+ check_read_length(len)
184
+ start = @cursor
185
+ @cursor += len
186
+ if one_byte
187
+ @str[start]
188
+ else
189
+ @str[start, len].unpack("C*")
190
+ end
191
+ end
192
+ else
193
+ def get(len=nil)
194
+ one_byte = len.nil?
195
+ len ||= 1
196
+ check_read_length(len)
197
+ start = @cursor
198
+ @cursor += len
199
+ if one_byte
200
+ @str[start, 1].ord
201
+ else
202
+ @str[start, len].unpack("C*")
203
+ end
204
+ end
205
+ end
206
+
207
+ def get_int
208
+ check_read_length(4)
209
+ vals = @str[@cursor..@cursor+3]
210
+ @cursor += 4
211
+ vals.unpack(@int_pack_order)[0]
212
+ end
213
+
214
+ def get_long
215
+ i1 = get_int
216
+ i2 = get_int
217
+ if @int_pack_order == 'N'
218
+ (i1 << 32) + i2
219
+ else
220
+ (i2 << 32) + i1
221
+ end
222
+ end
223
+
224
+ def get_double
225
+ check_read_length(8)
226
+ vals = @str[@cursor..@cursor+7]
227
+ @cursor += 8
228
+ vals.unpack(@double_pack_order)[0]
229
+ end
230
+
231
+ def more?
232
+ @cursor < @str.size
233
+ end
234
+
235
+ def to_a
236
+ @str.unpack("C*")
237
+ end
238
+
239
+ def unpack(args)
240
+ to_a
241
+ end
242
+
243
+ def to_s
244
+ @str
245
+ end
246
+
247
+ def dump
248
+ i = 0
249
+ @str.each_byte do |c, i|
250
+ $stderr.puts "#{'%04d' % i}: #{'%02x' % c} #{'%03o' % c} #{'%s' % c.chr} #{'%3d' % c}"
251
+ i += 1
252
+ end
253
+ end
254
+
255
+ private
256
+
257
+ def ensure_length(length)
258
+ if @str.size < length
259
+ @str << NULL_BYTE * (length - @str.size)
260
+ end
261
+ end
262
+
263
+ def chr(byte)
264
+ if byte < 0
265
+ [byte].pack('c')
266
+ else
267
+ byte.chr
268
+ end
269
+ end
270
+
271
+ def check_read_length(len)
272
+ raise "attempt to read past end of buffer" if @cursor + len > @str.length
273
+ end
274
+
275
+ end
276
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: UTF-8
2
+
3
+ # --
4
+ # Copyright (C) 2008-2011 10gen Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ # ++
18
+
19
+ module BSON
20
+ # Generic Mongo Ruby Driver exception class.
21
+ class MongoRubyError < StandardError; end
22
+
23
+ # Raised when MongoDB itself has returned an error.
24
+ class MongoDBError < RuntimeError; end
25
+
26
+ # This will replace MongoDBError.
27
+ class BSONError < MongoDBError; end
28
+
29
+ # Raised when given a string is not valid utf-8 (Ruby 1.8 only).
30
+ class InvalidStringEncoding < BSONError; end
31
+
32
+ # Raised when attempting to initialize an invalid ObjectID.
33
+ class InvalidObjectID < BSONError; end
34
+
35
+ # Raised when attempting to initialize an invalid ObjectID.
36
+ class InvalidObjectId < BSONError; end
37
+
38
+ # Raised when trying to insert a document that exceeds the 4MB limit or
39
+ # when the document contains objects that can't be serialized as BSON.
40
+ class InvalidDocument < BSONError; end
41
+
42
+ # Raised when an invalid name is used.
43
+ class InvalidKeyName < BSONError; end
44
+ end
@@ -0,0 +1,159 @@
1
+ # encoding: UTF-8
2
+
3
+ # --
4
+ # Copyright (C) 2008-2011 10gen Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ # ++
18
+
19
+ # A hash in which the order of keys are preserved.
20
+ #
21
+ # Under Ruby 1.9 and greater, this class has no added methods because Ruby's
22
+ # Hash already keeps its keys ordered by order of insertion.
23
+
24
+ module BSON
25
+ class OrderedHash < Hash
26
+
27
+ def ==(other)
28
+ begin
29
+ case other
30
+ when BSON::OrderedHash
31
+ keys == other.keys && values == other.values
32
+ else
33
+ super
34
+ end
35
+ rescue
36
+ false
37
+ end
38
+ end
39
+
40
+ # We only need the body of this class if the RUBY_VERSION is before 1.9
41
+ if RUBY_VERSION < '1.9'
42
+ attr_accessor :ordered_keys
43
+
44
+ def self.[] *args
45
+ oh = BSON::OrderedHash.new
46
+ if Hash === args[0]
47
+ oh.merge! args[0]
48
+ elsif (args.size % 2) != 0
49
+ raise ArgumentError, "odd number of elements for Hash"
50
+ else
51
+ 0.step(args.size - 1, 2) do |key|
52
+ value = key + 1
53
+ oh[args[key]] = args[value]
54
+ end
55
+ end
56
+ oh
57
+ end
58
+
59
+ def initialize(*a, &b)
60
+ super
61
+ @ordered_keys = []
62
+ end
63
+
64
+ def keys
65
+ @ordered_keys || []
66
+ end
67
+
68
+ def []=(key, value)
69
+ @ordered_keys ||= []
70
+ unless has_key?(key)
71
+ @ordered_keys << key
72
+ end
73
+ super(key, value)
74
+ end
75
+
76
+ def each
77
+ @ordered_keys ||= []
78
+ @ordered_keys.each { |k| yield k, self[k] }
79
+ self
80
+ end
81
+ alias :each_pair :each
82
+
83
+ def to_a
84
+ @ordered_keys ||= []
85
+ @ordered_keys.map { |k| [k, self[k]] }
86
+ end
87
+
88
+ def values
89
+ collect { |k, v| v }
90
+ end
91
+
92
+ def merge(other)
93
+ oh = self.dup
94
+ oh.merge!(other)
95
+ oh
96
+ end
97
+
98
+ def merge!(other)
99
+ @ordered_keys ||= []
100
+ @ordered_keys += other.keys # unordered if not an BSON::OrderedHash
101
+ @ordered_keys.uniq!
102
+ super(other)
103
+ end
104
+
105
+ alias :update :merge!
106
+
107
+ def inspect
108
+ str = '{'
109
+ str << (@ordered_keys || []).collect { |k| "\"#{k}\"=>#{self.[](k).inspect}" }.join(", ")
110
+ str << '}'
111
+ end
112
+
113
+ def delete(key, &block)
114
+ @ordered_keys.delete(key) if @ordered_keys
115
+ super
116
+ end
117
+
118
+ def delete_if(&block)
119
+ self.each { |k,v|
120
+ if yield k, v
121
+ delete(k)
122
+ end
123
+ }
124
+ end
125
+
126
+ def reject(&block)
127
+ clone = self.clone
128
+ return clone unless block_given?
129
+ clone.delete_if(&block)
130
+ end
131
+
132
+ def clear
133
+ super
134
+ @ordered_keys = []
135
+ end
136
+
137
+ def hash
138
+ code = 17
139
+ each_pair do |key, value|
140
+ code = 37 * code + key.hash
141
+ code = 37 * code + value.hash
142
+ end
143
+ code & 0x7fffffff
144
+ end
145
+
146
+ def eql?(o)
147
+ if o.instance_of? BSON::OrderedHash
148
+ self.hash == o.hash
149
+ else
150
+ false
151
+ end
152
+ end
153
+
154
+ def clone
155
+ Marshal::load(Marshal.dump(self))
156
+ end
157
+ end
158
+ end
159
+ end