Class: Veriform::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/veriform/parser.rb

Overview

Parses encoded Veriform messages, invoking callbacks in the given handler (i.e. this is a “push parser” which supports different backends)

Constant Summary collapse

MAX_LENGTH =

Default maximum length of a Veriform message. This is a conservative choice as Veriform’s main intended use is a credential format.

1024
MAX_DEPTH =

Default maximum depth (i.e. number of levels of child objects)

8

Instance Method Summary collapse

Constructor Details

#initialize(handler, max_length = MAX_LENGTH, max_depth = MAX_DEPTH) ⇒ Parser

Create a new message parser with the given parse event handler



15
16
17
18
19
20
# File 'lib/veriform/parser.rb', line 15

def initialize(handler, max_length = MAX_LENGTH, max_depth = MAX_DEPTH)
  @handler = handler
  @max_length = max_length
  @max_depth = max_depth
  @remaining = []
end

Instance Method Details

#finishObject

Finish parsing, returning the resulting object produced by the builder



47
48
49
# File 'lib/veriform/parser.rb', line 47

def finish
  @handler.finish
end

#parse(msg) ⇒ Object

Parse the given Veriform message, invoking callbacks as necessary



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/veriform/parser.rb', line 23

def parse(msg)
  raise OversizeMessageError, "length #{msg.length} exceeds max of #{@max_length}" if msg.length > @max_length
  raise EncodingError, "expected BINARY encoding, got #{msg.encoding}" unless msg.encoding == Encoding::BINARY
  @remaining << msg

  raise DepthError, "exceeded max depth of #{@max_depth}" if @remaining.size > @max_depth

  until @remaining.last.empty?
    id, wiretype = parse_field_prefix

    case wiretype
    when 0 then parse_uint64(id)
    when 2 then parse_message(id)
    when 3 then parse_binary(id)
    else raise ParseError, "unknown wiretype: #{wiretype.inspect}"
    end
  end

  @remaining.pop

  true
end