lib/bson/bson_ruby.rb in bson-1.0.7 vs lib/bson/bson_ruby.rb in bson-1.0.9
- old
+ new
@@ -45,26 +45,33 @@
def initialize
@buf = ByteBuffer.new
end
if RUBY_VERSION >= '1.9'
- def self.to_utf8(str)
- str.encode("utf-8")
+ NULL_BYTE = "\0".force_encoding('binary').freeze
+ UTF8_ENCODING = Encoding.find('utf-8')
+ BINARY_ENCODING = Encoding.find('binary')
+
+ def self.to_utf8_binary(str)
+ str.encode(UTF8_ENCODING).force_encoding(BINARY_ENCODING)
end
else
- def self.to_utf8(str)
+ NULL_BYTE = "\0"
+
+ def self.to_utf8_binary(str)
begin
str.unpack("U*")
rescue => ex
- raise InvalidStringEncoding, "String not valid utf-8: #{str}"
+ raise InvalidStringEncoding, "String not valid utf-8: #{str.inspect}"
end
str
end
end
def self.serialize_cstr(buf, val)
- buf.put_array(to_utf8(val.to_s).unpack("C*") << 0)
+ buf.put_binary(to_utf8_binary(val.to_s))
+ buf.put_binary(NULL_BYTE)
end
def self.serialize_key(buf, key)
raise InvalidDocument, "Key names / regex patterns must not contain the NULL byte" if key.include? "\x00"
self.serialize_cstr(buf, key)
@@ -269,11 +276,10 @@
str
end
def deserialize_date_data(buf)
unsigned = buf.get_long()
- # see note for deserialize_number_long_data below
milliseconds = unsigned >= 2 ** 64 / 2 ? unsigned - 2**64 : unsigned
Time.at(milliseconds.to_f / 1000.0).utc # at() takes fractional seconds
end
def deserialize_boolean_data(buf)
@@ -283,17 +289,14 @@
def deserialize_number_data(buf)
buf.get_double
end
def deserialize_number_int_data(buf)
- # sometimes ruby makes me angry... why would the same code pack as signed
- # but unpack as unsigned
unsigned = buf.get_int
unsigned >= 2**32 / 2 ? unsigned - 2**32 : unsigned
end
def deserialize_number_long_data(buf)
- # same note as above applies here...
unsigned = buf.get_long
unsigned >= 2 ** 64 / 2 ? unsigned - 2**64 : unsigned
end
def deserialize_object_data(buf)