Class: LexerKit::Format::LKB1::Decoder

Inherits:
Object
  • Object
show all
Defined in:
lib/lexer_kit/format/lkb1/decoder.rb

Overview

Decoder handles binary deserialization of LKB1 format

Instance Method Summary collapse

Constructor Details

#initialize(bytes) ⇒ Decoder

Returns a new instance of Decoder.



10
11
12
13
# File 'lib/lexer_kit/format/lkb1/decoder.rb', line 10

def initialize(bytes)
  @bytes = bytes
  @pos = 0
end

Instance Method Details

#decode_containerObject

Raises:

  • (ArgumentError)


15
16
17
18
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/lexer_kit/format/lkb1/decoder.rb', line 15

def decode_container
  raise ArgumentError, "too short" if @bytes.bytesize < FIXED_HEADER_LEN

  magic = read_bytes(4)
  raise ArgumentError, "invalid magic: #{magic.inspect}" unless magic == MAGIC

  header_version = read_u16
  raise ArgumentError, "unsupported header version: #{header_version}" unless header_version == HEADER_VERSION

  flags = read_u16

  # Reject unsupported flags
  if (flags & FLAG_PAYLOAD_COMPRESSED) != 0
    raise ArgumentError, "compressed payload is not supported"
  end

  if (flags & FLAG_PAYLOAD_ENCRYPTED) != 0
    raise ArgumentError, "encrypted payload is not supported"
  end

  header_len = read_u32
  raise ArgumentError, "invalid header_len: #{header_len}" if header_len < FIXED_HEADER_LEN

  payload_len = read_u32
  format_version = read_u16

  @pos += 2 # reserved

  sha256 = read_bytes(32)

  meta = {}
  if header_len > @pos
    meta_bytes = @bytes.byteslice(@pos, header_len - @pos)
    meta = decode_tlv(meta_bytes)
    @pos = header_len
  end

  total_len = header_len + payload_len
  raise ArgumentError, "truncated payload" if @bytes.bytesize < total_len

  payload = @bytes.byteslice(header_len, payload_len)

  if (flags & FLAG_PAYLOAD_SHA256) != 0
    actual = Digest::SHA256.digest(payload)
    raise ArgumentError, "sha256 mismatch" unless actual == sha256
  end

  {
    payload: payload,
    meta: meta,
    header: {
      header_version: header_version,
      flags: flags,
      header_len: header_len,
      payload_len: payload_len,
      format_version: format_version,
      sha256: sha256
    }
  }
end