Class: Hypertube::Core::Protocol::CommandSerializer
- Inherits:
-
Object
- Object
- Hypertube::Core::Protocol::CommandSerializer
- Defined in:
- lib/hypertube-ruby-sdk/core/protocol/command_serializer.rb
Constant Summary collapse
- EMPTY_CONNECTION_DATA =
Packed once and frozen, reused for every call that has no connection data (instead of allocating + packing a fresh Array on every serialize call).
[0, 0, 0, 0, 0, 0, 0].pack('C*').freeze
Class Method Summary collapse
- .serialize(root_command, connection_data = nil, runtime_version = 0) ⇒ Object
- .serialize_recursively(command, buffer) ⇒ Object
Class Method Details
.serialize(root_command, connection_data = nil, runtime_version = 0) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/hypertube-ruby-sdk/core/protocol/command_serializer.rb', line 19 def self.serialize(root_command, connection_data = nil, runtime_version = 0) # Binary (ASCII-8BIT) buffer so that appending Integers (0..255) via `<<` # writes the raw byte instead of encoding it as a multi-byte character. buffer = String.new(encoding: Encoding::ASCII_8BIT, capacity: 256) buffer << root_command.runtime_name buffer << runtime_version if connection_data buffer << connection_data.serialize_connection_data.pack('C*') else buffer << EMPTY_CONNECTION_DATA end buffer << Hypertube::Utils::RuntimeNameHt::RUBY buffer << root_command.command_type # Payload (recursive) - primitives/headers are written straight into the # binary buffer, no per-item Array + pack('C*') round-trip. serialize_recursively(root_command, buffer) # Single conversion to Array<Integer> at the very end, since downstream # callers (FFI transmitter, WebSocket/HTTP2 clients) expect that shape. buffer.bytes end |
.serialize_recursively(command, buffer) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/hypertube-ruby-sdk/core/protocol/command_serializer.rb', line 47 def self.serialize_recursively(command, buffer) command.payload.each do |item| if item.is_a?(Hypertube::Utils::Command) Hypertube::Core::Protocol::TypeSerializer.write_command_header(buffer, item) serialize_recursively(item, buffer) elsif Hypertube::Utils::TypesHandler.primitive_or_none?(item) Hypertube::Core::Protocol::TypeSerializer.write_primitive(buffer, item) else cached_reference = Hypertube::Core::ReferenceCache::ReferencesCache.instance.cache_reference(item) ref_command = Hypertube::Utils::Command.new(Hypertube::Utils::RuntimeNameHt::RUBY, Hypertube::Utils::CommandType::REFERENCE, [cached_reference]) Hypertube::Core::Protocol::TypeSerializer.write_command_header(buffer, ref_command) serialize_recursively(ref_command, buffer) end end end |