lib/aws-eventstream/encoder.rb in aws-eventstream-1.0.3 vs lib/aws-eventstream/encoder.rb in aws-eventstream-1.1.0

- old
+ new

@@ -1,9 +1,9 @@ require 'zlib' module Aws - module EventStream + module EventStream # This class provides #encode method for encoding # Aws::EventStream::Message into binary. # # * {#encode} - encode Aws::EventStream::Message into binary @@ -57,104 +57,84 @@ # @return [nil, String] when output IO is provided, # encoded message will be written to that IO, nil # will be returned. Else, encoded binary string is # returned. def encode(message, io = nil) - encoded = encode_message(message).read + encoded = encode_message(message) if io io.write(encoded) io.close else encoded end end # Encodes an Aws::EventStream::Message - # into Aws::EventStream::BytesBuffer + # into String # - # @param [Aws::EventStream::Message] msg + # @param [Aws::EventStream::Message] message # - # @return [Aws::EventStream::BytesBuffer] + # @return [String] def encode_message(message) # create context buffer with encode headers - ctx_buffer = encode_headers(message) - headers_len = ctx_buffer.bytesize + encoded_header = encode_headers(message) + header_length = encoded_header.bytesize # encode payload if message.payload.length > MAX_PAYLOAD_LENGTH raise Aws::EventStream::Errors::EventPayloadLengthExceedError.new end - ctx_buffer << message.payload.read - total_len = ctx_buffer.bytesize + OVERHEAD_LENGTH + encoded_payload = message.payload.read + total_length = header_length + encoded_payload.bytesize + OVERHEAD_LENGTH # create message buffer with prelude section - buffer = prelude(total_len, headers_len) + encoded_prelude = encode_prelude(total_length, header_length) # append message context (headers, payload) - buffer << ctx_buffer.read + encoded_content = [ + encoded_prelude, + encoded_header, + encoded_payload, + ].pack('a*a*a*') # append message checksum - buffer << pack_uint32(Zlib.crc32(buffer.read)) - - # write buffered message to io - buffer.rewind - buffer + message_checksum = Zlib.crc32(encoded_content) + [encoded_content, message_checksum].pack('a*N') end # Encodes headers part of an Aws::EventStream::Message - # into Aws::EventStream::BytesBuffer + # into String # - # @param [Aws::EventStream::Message] msg + # @param [Aws::EventStream::Message] message # - # @return [Aws::EventStream::BytesBuffer] - def encode_headers(msg) - buffer = BytesBuffer.new('') - msg.headers.each do |k, v| - # header key - buffer << pack_uint8(k.bytesize) - buffer << k + # @return [String] + def encode_headers(message) + header_entries = message.headers.map do |key, value| + encoded_key = [key.bytesize, key].pack('Ca*') # header value - pattern, val_len, idx = Types.pattern[v.type] - buffer << pack_uint8(idx) + pattern, value_length, type_index = Types.pattern[value.type] + encoded_value = [type_index].pack('C') # boolean types doesn't need to specify value - next if !!pattern == pattern - buffer << pack_uint16(v.value.bytesize) unless val_len - pattern ? buffer << [v.value].pack(pattern) : - buffer << v.value + next [encoded_key, encoded_value].pack('a*a*') if !!pattern == pattern + encoded_value = [encoded_value, value.value.bytesize].pack('a*S>') unless value_length + + [ + encoded_key, + encoded_value, + pattern ? [value.value].pack(pattern) : value.value, + ].pack('a*a*a*') end - if buffer.bytesize > MAX_HEADERS_LENGTH + header_entries.join.tap do |encoded_header| + break encoded_header if encoded_header.bytesize <= MAX_HEADERS_LENGTH raise Aws::EventStream::Errors::EventHeadersLengthExceedError.new end - buffer end private - def prelude(total_len, headers_len) - BytesBuffer.new(pack_uint32([ - total_len, - headers_len, - Zlib.crc32(pack_uint32([total_len, headers_len])) - ])) + def encode_prelude(total_length, headers_length) + prelude_body = [total_length, headers_length].pack('NN') + checksum = Zlib.crc32(prelude_body) + [prelude_body, checksum].pack('a*N') end - - # overhead encode helpers - - def pack_uint8(val) - [val].pack('C') - end - - def pack_uint16(val) - [val].pack('S>') - end - - def pack_uint32(val) - if val.respond_to?(:each) - val.pack('N*') - else - [val].pack('N') - end - end - end - end end