Class: Aws::EventStream::Encoder

Inherits:
Object
  • Object
show all
Defined in:
gems/aws-eventstream/lib/aws-eventstream/encoder.rb

Overview

This class provides #encode method for encoding Aws::EventStream::Message into binary.

  • #encode - encode Aws::EventStream::Message into binary when output IO-like object is provided, binary string would be written to IO. If not, the encoded binary string would be returned directly

Examples

message = Aws::EventStream::Message.new( headers: { "foo" => Aws::EventStream::HeaderValue.new( value: "bar", type: "string" ) }, payload: "payload" ) encoder = Aws::EventsStream::Encoder.new file = Tempfile.new

# encode into IO ouput encoder.encode(message, file)

# get encoded binary string encoded_message = encoder.encode(message)

file.read == encoded_message # => true

Constant Summary collapse

OVERHEAD_LENGTH =

bytes of total overhead in a message, including prelude and 4 bytes total message crc checksum

16
MAX_HEADERS_LENGTH =

Maximum header length allowed (after encode) 128kb

131072
MAX_PAYLOAD_LENGTH =

Maximum payload length allowed (after encode) 16mb

16777216

Instance Method Summary collapse

Instance Method Details

#encode(message, io = nil) ⇒ nil, String

Encodes Aws::EventStream::Message to output IO when provided, else return the encoded binary string

Parameters:

  • message (Aws::EventStream::Message)
  • io (IO#write, nil) (defaults to: nil)

    An IO-like object that responds to #write, encoded message will be written to this IO when provided

Returns:

  • (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.



63
64
65
66
67
68
69
70
71
# File 'gems/aws-eventstream/lib/aws-eventstream/encoder.rb', line 63

def encode(message, io = nil)
  encoded = encode_message(message)
  if io
    io.write(encoded)
    io.close
  else
    encoded
  end
end

#encode_headers(message) ⇒ String

Encodes headers part of an Aws::EventStream::Message into String

Parameters:

Returns:

  • (String)


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'gems/aws-eventstream/lib/aws-eventstream/encoder.rb', line 110

def encode_headers(message)
  header_entries = message.headers.map do |key, value|
    encoded_key = [key.bytesize, key].pack('Ca*')

    # header value
    pattern, value_length, type_index = Types.pattern[value.type]
    encoded_value = [type_index].pack('C')
    # boolean types doesn't need to specify 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
  header_entries.join.tap do |encoded_header|
    break encoded_header if encoded_header.bytesize <= MAX_HEADERS_LENGTH
    raise Aws::EventStream::Errors::EventHeadersLengthExceedError.new
  end
end

#encode_message(message) ⇒ String

Encodes an Aws::EventStream::Message into String

Parameters:

Returns:

  • (String)


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'gems/aws-eventstream/lib/aws-eventstream/encoder.rb', line 79

def encode_message(message)
  # create context buffer with encode headers
  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
  encoded_payload = message.payload.read
  total_length = header_length + encoded_payload.bytesize + OVERHEAD_LENGTH

  # create message buffer with prelude section
  encoded_prelude = encode_prelude(total_length, header_length)

  # append message context (headers, payload)
  encoded_content = [
    encoded_prelude,
    encoded_header,
    encoded_payload,
  ].pack('a*a*a*')
  # append message checksum
  message_checksum = Zlib.crc32(encoded_content)
  [encoded_content, message_checksum].pack('a*N')
end