Module: LittleGhost::CodeMode::Protocol

Defined in:
lib/little_ghost/code_mode/protocol.rb

Overview

Length-prefixed JSON framing shared by code-mode parent and child hosts. Frames are bounded before allocation and parsing.

Constant Summary collapse

MAX_FRAME_BYTES =

Largest encoded JSON payload accepted by the protocol.

64 * 1024 * 1024
Error =

Raised for malformed or oversized frames.

Class.new(StandardError)

Class Method Summary collapse

Class Method Details

.dump(value) ⇒ Object

Returns one encoded frame for value.



37
38
39
40
41
42
43
44
# File 'lib/little_ghost/code_mode/protocol.rb', line 37

def dump(value)
  payload = JSON.generate(value)
  raise Error, "Code-mode frame exceeds the size limit" if payload.bytesize > MAX_FRAME_BYTES

  [payload.bytesize].pack("N") << payload.b
rescue JSON::GeneratorError, EncodingError => error
  raise Error, "Code-mode frame cannot be encoded as JSON: #{error.message}"
end

.extract!(buffer) ⇒ Object

Removes and returns one complete frame from buffer, or returns nil while more bytes are required.



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/little_ghost/code_mode/protocol.rb', line 48

def extract!(buffer)
  return if buffer.bytesize < 4

  length = buffer.unpack1("N")
  raise Error, "Code-mode frame exceeds the size limit" if length > MAX_FRAME_BYTES
  return if buffer.bytesize < length + 4

  payload = buffer.byteslice(4, length)
  buffer.slice!(0, length + 4)
  JSON.parse(payload)
rescue JSON::ParserError, EncodingError => error
  raise Error, "Code-mode frame is not valid JSON: #{error.message}"
end

.read(io) ⇒ Object

Reads one complete frame from io, or returns nil at clean EOF.



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/little_ghost/code_mode/protocol.rb', line 18

def read(io)
  header = read_exactly(io, 4)
  return if header.nil?

  length = header.unpack1("N")
  raise Error, "Code-mode frame exceeds the size limit" if length > MAX_FRAME_BYTES

  JSON.parse(read_exactly(io, length) || raise(EOFError, "Code-mode frame ended early"))
rescue JSON::ParserError, EncodingError => error
  raise Error, "Code-mode frame is not valid JSON: #{error.message}"
end

.write(io, value) ⇒ Object

Encodes value and writes one complete frame to io.



31
32
33
34
# File 'lib/little_ghost/code_mode/protocol.rb', line 31

def write(io, value)
  io.write(dump(value))
  io.flush if io.respond_to?(:flush)
end