class JsonSequence::Parser

Constants

RS

Public Class Methods

new() click to toggle source
# File lib/json_sequence/parser.rb, line 8
def initialize
  @buffer = ''
end

Public Instance Methods

parse(chunk, &block) click to toggle source
# File lib/json_sequence/parser.rb, line 12
def parse(chunk, &block)
  @buffer = do_parse(@buffer + chunk, &block)
end

Private Instance Methods

do_parse(buffer) { |result| ... } click to toggle source

Takes a String buffer to parse and returns String containing any text remaining to parse when more data is available.

# File lib/json_sequence/parser.rb, line 20
def do_parse(buffer)
  records = buffer.split(RS, -1) # -1 stops suppression of trailing null fields

  records.each_with_index do |record, i|
    # RFC7464 2.1 Multiple consecutive RS octets do not denote empty
    # sequence elements between them and can be ignored.
    next if record == ''

    # Try to decode the record
    begin
      value = MultiJson.load(record)
      result, remaining = handle_parsed(record, value, is_last_record: i == records.size - 1)
    rescue MultiJson::ParseError => err
      result, remaining = handle_err(record, err, is_last_record: i == records.size - 1)
    end

    return remaining if result.nil?
    yield result
  end

  ''
end
handle_err(record, err, is_last_record:) click to toggle source
# File lib/json_sequence/parser.rb, line 56
def handle_err(record, err, is_last_record:)
  # Last record, might be incomplete, stash for later
  is_last_record ? [nil, record] : [JsonSequence::Result::ParseError.new(record, err), '']
end
handle_parsed(record, value, is_last_record:) click to toggle source
# File lib/json_sequence/parser.rb, line 43
def handle_parsed(record, value, is_last_record:)
  case value
  when Numeric, TrueClass, FalseClass, NilClass
    # Check for truncation, if record was parsed but doesn't end in
    # whitespace it may be truncated
    if record !~ /\s$/
      return is_last_record ? [nil, record] : [JsonSequence::Result::MaybeTruncated.new(value), '']
    end
  end

  [JsonSequence::Result::Json.new(value), '']
end