lib/mongo/protocol/serializers.rb in mongo-2.4.3 vs lib/mongo/protocol/serializers.rb in mongo-2.5.0.beta

- old
+ new

@@ -145,10 +145,173 @@ def self.deserialize(buffer) buffer.get_int64 end end + # MongoDB wire protocol serialization strategy for a Section of OP_MSG. + # + # Serializes and de-serializes a list of Sections. + # + # @since 2.5.0 + module Sections + + # Serializes the sections of an OP_MSG, payload type 0 or 1. + # + # @param [ BSON::ByteBuffer ] buffer Buffer to receive the serialized Sections. + # @param [ Array<Hash, BSON::Document> ] value The sections to be serialized. + # @param [ Fixnum ] max_bson_size The max bson size of documents in the sections. + # @param [ true, false ] validating_keys Whether to validate document keys. + # + # @return [ BSON::ByteBuffer ] Buffer with serialized value. + # + # @since 2.5.0 + def self.serialize(buffer, value, max_bson_size = nil, validating_keys = BSON::Config.validating_keys?) + value.each do |section| + case section[:type] + when PayloadZero::TYPE + PayloadZero.serialize(buffer, section[:payload], max_bson_size, false) + when nil + PayloadZero.serialize(buffer, section[:payload], max_bson_size, false) + when PayloadOne::TYPE + PayloadOne.serialize(buffer, section[:payload], max_bson_size, validating_keys) + else + raise Error::UnknownPayloadType.new(section[:type]) + end + end + end + + # Deserializes a section of an OP_MSG from the IO stream. + # + # @param [ BSON::ByteBuffer ] buffer Buffer containing the sections. + # + # @return [ Array<BSON::Document> ] Deserialized sections. + # + # @since 2.5.0 + def self.deserialize(buffer) + end_length = (@flag_bits & Msg::FLAGS.index(:checksum_present)) == 1 ? 32 : 0 + sections = [] + until buffer.length == end_length + case byte = buffer.get_byte + when PayloadZero::TYPE_BYTE + sections << PayloadZero.deserialize(buffer) + when PayloadOne::TYPE_BYTE + sections += PayloadOne.deserialize(buffer) + else + raise Error::UnknownPayloadType.new(byte) + end + end + sections + end + + # Whether there can be a size limit on this type after serialization. + # + # @return [ true ] Documents can be size limited upon serialization. + # + # @since 2.5.0 + def self.size_limited? + true + end + + # MongoDB wire protocol serialization strategy for a payload 0 type Section of OP_MSG. + # + # @since 2.5.0 + module PayloadZero + + # The byte identifier for this payload type. + # + # @since 2.5.0 + TYPE = 0x0 + + # The byte corresponding to this payload type. + # + # @since 2.5.0 + TYPE_BYTE = TYPE.chr.force_encoding(BSON::BINARY).freeze + + # Serializes a section of an OP_MSG, payload type 0. + # + # @param [ BSON::ByteBuffer ] buffer Buffer to receive the serialized Sections. + # @param [ BSON::Document, Hash ] value The object to serialize. + # @param [ Fixnum ] max_bson_size The max bson size of documents in the section. + # @param [ true, false ] validating_keys Whether to validate document keys. + # + # @return [ BSON::ByteBuffer ] Buffer with serialized value. + # + # @since 2.5.0 + def self.serialize(buffer, value, max_bson_size = nil, validating_keys = BSON::Config.validating_keys?) + buffer.put_byte(TYPE_BYTE) + Serializers::Document.serialize(buffer, value, max_bson_size, validating_keys) + end + + # Deserializes a section of payload type 0 of an OP_MSG from the IO stream. + # + # @param [ BSON::ByteBuffer ] buffer Buffer containing the sections. + # + # @return [ Array<BSON::Document> ] Deserialized section. + # + # @since 2.5.0 + def self.deserialize(buffer) + BSON::Document.from_bson(buffer) + end + end + + # MongoDB wire protocol serialization strategy for a payload 1 type Section of OP_MSG. + # + # @since 2.5.0 + module PayloadOne + + # The byte identifier for this payload type. + # + # @since 2.5.0 + TYPE = 0x1 + + # The byte corresponding to this payload type. + # + # @since 2.5.0 + TYPE_BYTE = TYPE.chr.force_encoding(BSON::BINARY).freeze + + # Serializes a section of an OP_MSG, payload type 1. + # + # @param [ BSON::ByteBuffer ] buffer Buffer to receive the serialized Sections. + # @param [ BSON::Document, Hash ] value The object to serialize. + # @param [ Fixnum ] max_bson_size The max bson size of documents in the section. + # @param [ true, false ] validating_keys Whether to validate document keys. + # + # @return [ BSON::ByteBuffer ] Buffer with serialized value. + # + # @since 2.5.0 + def self.serialize(buffer, value, max_bson_size = nil, validating_keys = BSON::Config.validating_keys?) + buffer.put_byte(TYPE_BYTE) + start = buffer.length + buffer.put_int32(0) # hold for size + buffer.put_cstring(value[:identifier]) + value[:sequence].each do |document| + Document.serialize(buffer, document, max_bson_size, validating_keys) + end + buffer.replace_int32(start, buffer.length - start) + end + + # Deserializes a section of payload type 1 of an OP_MSG from the IO stream. + # + # @param [ BSON::ByteBuffer ] buffer Buffer containing the sections. + # + # @return [ Array<BSON::Document> ] Deserialized section. + # + # @since 2.5.0 + def self.deserialize(buffer) + start_size = buffer.length + section_size = buffer.get_int32 # get the size + end_size = start_size - section_size + buffer.get_cstring # get the identifier + documents = [] + until buffer.length == end_size + documents << BSON::Document.from_bson(buffer) + end + documents + end + end + end + # MongoDB wire protocol serialization strategy for a BSON Document. # # Serializes and de-serializes a single document. module Document @@ -180,9 +343,70 @@ # @return [ true ] Documents can be size limited upon serialization. # # @since 2.0.0 def self.size_limited? true + end + end + + # MongoDB wire protocol serialization strategy for a single byte. + # + # Writes and fetches a single byte from the byte buffer. + module Byte + + # Writes a byte into the buffer. + # + # @param buffer [ BSON::ByteBuffer ] buffer Buffer to receive the single byte. + # @param value [ String ] value The byte to write to the buffer. + # @param value [ true, false ] validating_keys Whether to validate keys. + # + # @return [ BSON::ByteBuffer ] Buffer with serialized value. + # + # @since 2.5.0 + def self.serialize(buffer, value, validating_keys = BSON::Config.validating_keys?) + buffer.put_byte(value) + end + + # Deserializes a byte from the byte buffer. + # + # @param [ BSON::ByteBuffer ] buffer Buffer containing the value to read. + # + # @return [ String ] The byte. + # + # @since 2.5.0 + def self.deserialize(buffer) + buffer.get_byte + end + end + + # MongoDB wire protocol serialization strategy for n bytes. + # + # Writes and fetches bytes from the byte buffer. + module Bytes + + # Writes bytes into the buffer. + # + # @param buffer [ BSON::ByteBuffer ] buffer Buffer to receive the bytes. + # @param value [ String ] value The bytes to write to the buffer. + # @param value [ true, false ] validating_keys Whether to validate keys. + # + # @return [ BSON::ByteBuffer ] Buffer with serialized value. + # + # @since 2.5.0 + def self.serialize(buffer, value, validating_keys = BSON::Config.validating_keys?) + buffer.put_bytes(value) + end + + # Deserializes bytes from the byte buffer. + # + # @param [ BSON::ByteBuffer ] buffer Buffer containing the value to read. + # @param [ Integer ] num_bytes Number of bytes to read. + # + # @return [ String ] The bytes. + # + # @since 2.5.0 + def self.deserialize(buffer, num_bytes = nil) + buffer.get_bytes(num_bytes || buffer.length) end end end end end