class FFI_Yajl::Parser
def self.parse(obj, *args)
def self.parse(obj, *args) new(*args).parse(obj) end
def initialize(opts = {})
def initialize(opts = {}) @opts = opts ? opts.dup : {} # JSON gem uses 'symbolize_names' and ruby-yajl supports this as well @opts[:symbolize_keys] = true if @opts[:symbolize_names] end
def key_stack
stack to keep track of keys as we create nested hashes
def key_stack @key_stack ||= [] end
def parse(str)
def parse(str) raise FFI_Yajl::ParseError, "input must be a string or IO" unless str.is_a?(String) || str.respond_to?(:read) # initialization that we can do in pure ruby yajl_opts = {} if @opts[:check_utf8] == false && @opts[:dont_validate_strings] == false raise ArgumentError, "options check_utf8 and dont_validate_strings are both false which conflict" end if @opts[:check_utf8] == true && @opts[:dont_validate_strings] == true raise ArgumentError, "options check_utf8 and dont_validate_strings are both true which conflict" end yajl_opts[:yajl_allow_comments] = true if @opts.key?(:allow_comments) yajl_opts[:yajl_allow_comments] = @opts[:allow_comments] end yajl_opts[:yajl_dont_validate_strings] = (@opts[:check_utf8] == false || @opts[:dont_validate_strings]) yajl_opts[:yajl_allow_trailing_garbage] = @opts[:allow_trailing_garbage] yajl_opts[:yajl_allow_multiple_values] = @opts[:allow_multiple_values] yajl_opts[:yajl_allow_partial_values] = @opts[:allow_partial_values] yajl_opts[:unique_key_checking] = @opts[:unique_key_checking] # XXX: bug-compat with ruby-yajl return nil if str == "" str = str.read if str.respond_to?(:read) # call either the ext or ffi hook do_yajl_parse(str, yajl_opts) end
def stack
stack used to build up our complex object
def stack @stack ||= [] end