Class: Aws::EventStream::Encoder

Inherits:
Object
  • Object
show all
Defined in:
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.



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

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

#encode_headers(msg) ⇒ Aws::EventStream::BytesBuffer

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

into Aws::EventStream::BytesBuffer


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/aws-eventstream/encoder.rb', line 107

def encode_headers(msg)
  buffer = BytesBuffer.new('')
  msg.headers.each do |k, v|
    # header key
    buffer << pack_uint8(k.bytesize)
    buffer << k

    # header value
    pattern, val_len, idx = Types.pattern[v.type]
    buffer << pack_uint8(idx)
    # 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
  end
  if buffer.bytesize > MAX_HEADERS_LENGTH
    raise Aws::EventStream::Errors::EventHeadersLengthExceedError.new
  end
  buffer
end

#encode_message(message) ⇒ Aws::EventStream::BytesBuffer

Encodes an Aws::EventStream::Message

into Aws::EventStream::BytesBuffer


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

def encode_message(message)
  # create context buffer with encode headers
  ctx_buffer = encode_headers(message)
  headers_len = ctx_buffer.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

  # create message buffer with prelude section
  buffer = prelude(total_len, headers_len)

  # append message context (headers, payload)
  buffer << ctx_buffer.read
  # append message checksum
  buffer << pack_uint32(Zlib.crc32(buffer.read))

  # write buffered message to io
  buffer.rewind
  buffer
end