Module: TriCoreDB::Frame
- Defined in:
- lib/tricoredb/frame.rb
Overview
The native frame format: version:u8 | tag:u8 | payload_len:u32be | payload.
Constant Summary collapse
- VERSION =
The frame format version this driver writes.
1- MAX_SUPPORTED_VERSION =
The highest frame format version this driver can read.
1- HEADER_SIZE =
6- MAX_DATA_PAYLOAD =
Ceiling for REQUEST and RESPONSE payloads.
16 * 1024 * 1024
- MAX_CONTROL_PAYLOAD =
Ceiling for every other frame.
64 * 1024
- HELLO =
0- AUTH =
1- REQUEST =
2- RESPONSE =
3- PING =
4- PONG =
5- ERROR =
6- CLOSE =
7- HELLO_OK =
8- AUTH_OK =
9- BYE =
10- CANCEL =
11- CANCEL_OK =
12- NAMES =
{ HELLO => "HELLO", AUTH => "AUTH", REQUEST => "REQUEST", RESPONSE => "RESPONSE", PING => "PING", PONG => "PONG", ERROR => "ERROR", CLOSE => "CLOSE", HELLO_OK => "HELLO_OK", AUTH_OK => "AUTH_OK", BYE => "BYE", CANCEL => "CANCEL", CANCEL_OK => "CANCEL_OK" }.freeze
Class Method Summary collapse
-
.decode_body(body) ⇒ Object?
The parsed JSON, or nil for an empty payload.
-
.decode_header(header) ⇒ Array(Integer, Integer)
Decode and validate a six-byte header before any payload byte is read.
-
.encode(tag, payload) ⇒ String
Encode one frame.
-
.max_payload_for(tag) ⇒ Integer
The payload ceiling for that tag; an unknown tag gets the tighter one.
- .name(tag) ⇒ String
Class Method Details
.decode_body(body) ⇒ Object?
Returns the parsed JSON, or nil for an empty payload.
98 99 100 101 102 103 104 |
# File 'lib/tricoredb/frame.rb', line 98 def decode_body(body) return nil if body.empty? JSON.parse(body.dup.force_encoding(Encoding::UTF_8)) rescue JSON::ParserError => e raise ProtocolError, "frame payload is not valid JSON: #{e.}" end |
.decode_header(header) ⇒ Array(Integer, Integer)
Decode and validate a six-byte header before any payload byte is read.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/tricoredb/frame.rb', line 76 def decode_header(header) raise ProtocolError, "short frame header (#{header.bytesize} bytes)" if header.bytesize != HEADER_SIZE version, tag, length = header.unpack("CCN") if version > MAX_SUPPORTED_VERSION raise ProtocolError.new( "frame header version #{version} is newer than this driver can read (max #{MAX_SUPPORTED_VERSION})", code: "frame_version" ) end limit = max_payload_for(tag) if length > limit raise ProtocolError.new( "#{name(tag)} frame declares a #{length}-byte payload, above the #{limit}-byte limit; refusing to buffer it", code: "frame_too_large" ) end [tag, length] end |
.encode(tag, payload) ⇒ String
Encode one frame.
59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/tricoredb/frame.rb', line 59 def encode(tag, payload) body = payload.nil? ? "".b : JSON.generate(payload).b limit = max_payload_for(tag) if body.bytesize > limit raise ProtocolError.new( "refusing to send a #{body.bytesize}-byte #{name(tag)} payload; the protocol caps it at #{limit} bytes", code: "frame_too_large" ) end [VERSION, tag, body.bytesize].pack("CCN") + body end |
.max_payload_for(tag) ⇒ Integer
Returns the payload ceiling for that tag; an unknown tag gets the tighter one.
43 44 45 |
# File 'lib/tricoredb/frame.rb', line 43 def max_payload_for(tag) tag == REQUEST || tag == RESPONSE ? MAX_DATA_PAYLOAD : MAX_CONTROL_PAYLOAD end |
.name(tag) ⇒ String
49 50 51 |
# File 'lib/tricoredb/frame.rb', line 49 def name(tag) NAMES.fetch(tag) { "tag #{tag}" } end |