diff --git a/lib/mongo/collection.rb b/lib/mongo/collection.rb index e0a5d20..ffa3474 100644 --- a/lib/mongo/collection.rb +++ b/lib/mongo/collection.rb @@ -241,11 +241,11 @@ module Mongo # @example remove only documents that have expired: # users.remove({:expire => {"$lte" => Time.now}}) def remove(selector={}) - message = ByteBuffer.new - message.put_int(0) + # Initial byte is 0. + message = ByteBuffer.new([0, 0, 0, 0]) BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}") message.put_int(0) - message.put_array(BSON.serialize(selector, false).unpack("C*")) + message.put_array(BSON.serialize(selector, false).to_a) @connection.send_message(Mongo::Constants::OP_DELETE, message, "db.#{@db.name}.remove(#{selector.inspect})") end @@ -269,15 +269,15 @@ module Mongo # will be raised on an error. Note that a safe check requires an extra # round-trip to the database. def update(selector, document, options={}) - message = ByteBuffer.new - message.put_int(0) + # Initial byte is 0. + message = ByteBuffer.new([0, 0, 0, 0]) BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}") update_options = 0 update_options += 1 if options[:upsert] update_options += 2 if options[:multi] message.put_int(update_options) - message.put_array(BSON.serialize(selector, false).unpack("C*")) - message.put_array(BSON.serialize(document, false).unpack("C*")) + message.put_array(BSON.serialize(selector, false).to_a) + message.put_array(BSON.serialize(document, false).to_a) if options[:safe] @connection.send_message_with_safe_check(Mongo::Constants::OP_UPDATE, message, @db.name, "db.#{@name}.update(#{selector.inspect}, #{document.inspect})") @@ -589,10 +589,10 @@ EOS # Takes an array of +documents+, an optional +collection_name+, and a # +check_keys+ setting. def insert_documents(documents, collection_name=@name, check_keys=true, safe=false) - message = ByteBuffer.new - message.put_int(0) + # Initial byte is 0. + message = ByteBuffer.new([0, 0, 0, 0]) BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{collection_name}") - documents.each { |doc| message.put_array(BSON.serialize(doc, check_keys).unpack("C*")) } + documents.each { |doc| message.put_array(BSON.serialize(doc, check_keys).to_a) } if safe @connection.send_message_with_safe_check(Mongo::Constants::OP_INSERT, message, @db.name, "db.#{collection_name}.insert(#{documents.inspect})") diff --git a/lib/mongo/cursor.rb b/lib/mongo/cursor.rb index 7be53ac..5663692 100644 --- a/lib/mongo/cursor.rb +++ b/lib/mongo/cursor.rb @@ -220,8 +220,7 @@ module Mongo # @return [True] def close if @cursor_id - message = ByteBuffer.new - message.put_int(0) + message = ByteBuffer.new([0, 0, 0, 0]) message.put_int(1) message.put_long(@cursor_id) @connection.send_message(Mongo::Constants::OP_KILL_CURSORS, message, "cursor.close()") @@ -315,9 +314,7 @@ module Mongo def refill_via_get_more return if send_initial_query || @cursor_id.zero? - message = ByteBuffer.new - # Reserved. - message.put_int(0) + message = ByteBuffer.new([0, 0, 0, 0]) # DB name. db_name = @admin ? 'admin' : @db.name @@ -359,8 +356,8 @@ module Mongo if query_contains_special_fields? selector = selector_with_special_query_fields end - message.put_array(BSON.serialize(selector, false).unpack("C*")) - message.put_array(BSON.serialize(@fields, false).unpack("C*")) if @fields + message.put_array(BSON.serialize(selector, false).to_a) + message.put_array(BSON.serialize(@fields, false).to_a) if @fields message end diff --git a/lib/mongo/util/byte_buffer.rb b/lib/mongo/util/byte_buffer.rb index eea9b09..678d738 100644 --- a/lib/mongo/util/byte_buffer.rb +++ b/lib/mongo/util/byte_buffer.rb @@ -17,6 +17,20 @@ # A byte buffer. class ByteBuffer + # Commonly-used integers. + INT_LOOKUP = { + 0 => [0, 0, 0, 0], + 1 => [1, 0, 0, 0], + 2 => [2, 0, 0, 0], + 3 => [3, 0, 0, 0], + 4 => [4, 0, 0, 0], + 2001 => [209, 7, 0, 0], + 2002 => [210, 7, 0, 0], + 2004 => [212, 7, 0, 0], + 2005 => [213, 7, 0, 0], + 2006 => [214, 7, 0, 0] + } + attr_reader :order def initialize(initial_data=[]) @@ -100,8 +114,10 @@ class ByteBuffer end def put_int(i, offset=nil) - a = [] - [i].pack(@int_pack_order).each_byte { |b| a << b } + unless a = INT_LOOKUP[i] + a = [] + [i].pack(@int_pack_order).each_byte { |b| a << b } + end put_array(a, offset) end