Class: Yajl::Parser

Inherits:
Object show all
Defined in:
lib/yajl.rb,
ext/yajl/yajl_ext.c

Overview

This class contains methods for parsing JSON directly from an IO object. The only basic requirment currently is that the IO object respond to #read(len) and #eof? The IO is parsed until a complete JSON object has been read and a ruby object will be returned.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#new([:symbolize_keys) ⇒ true, Array

:symbolize_keys will turn hash keys into Ruby symbols, defaults to false.

:allow_comments will turn on/off the check for comments inside the JSON stream, defaults to true.

:check_utf8 will validate UTF8 characters found in the JSON stream, defaults to true.



# File 'ext/yajl/yajl_ext.c'

/*
 * Document-method: initialize
 *
 * call-seq: new([:symbolize_keys => true, [:allow_comments => false[, :check_utf8 => false]]])
 *
 * :symbolize_keys will turn hash keys into Ruby symbols, defaults to false.
 *
 * :allow_comments will turn on/off the check for comments inside the JSON stream, defaults to true.
 *
 * :check_utf8 will validate UTF8 characters found in the JSON stream, defaults to true.
 */
static VALUE rb_yajl_parser_init(int argc, VALUE * argv, VALUE self) {
    return self;
}

Class Method Details

.new([:symbolize_keys) ⇒ true, Array

:symbolize_keys will turn hash keys into Ruby symbols, defaults to false.

:allow_comments will turn on/off the check for comments inside the JSON stream, defaults to true.

:check_utf8 will validate UTF8 characters found in the JSON stream, defaults to true.

Returns:

  • (true, Array)


# File 'ext/yajl/yajl_ext.c'

/*
 * Document-method: new
 *
 * call-seq: new([:symbolize_keys => true, [:allow_comments => false[, :check_utf8 => false]]])
 *
 * :symbolize_keys will turn hash keys into Ruby symbols, defaults to false.
 *
 * :allow_comments will turn on/off the check for comments inside the JSON stream, defaults to true.
 *
 * :check_utf8 will validate UTF8 characters found in the JSON stream, defaults to true.
 */
static VALUE rb_yajl_parser_new(int argc, VALUE * argv, VALUE klass) {
    yajl_parser_wrapper * wrapper;
    yajl_parser_config cfg;
    VALUE opts, obj;
    int allowComments = 1, checkUTF8 = 1, symbolizeKeys = 0;

    /* Scan off config vars */
    if (rb_scan_args(argc, argv, "01", &opts) == 1) {
Check_Type(opts, T_HASH);

if (rb_hash_aref(opts, sym_allow_comments) == Qfalse) {
    allowComments = 0;
}

.parse(str_or_io, options = {}, read_bufsize = nil, &block) ⇒ Object

A helper method for parse-and-forget use-cases

io is the stream to parse JSON from

The options hash allows you to set two parsing options - :allow_comments and :check_utf8

:allow_comments accepts a boolean will enable/disable checks for in-line comments in the JSON stream

:check_utf8 accepts a boolean will enable/disable UTF8 validation for the JSON stream



36
37
38
# File 'lib/yajl.rb', line 36

def self.parse(str_or_io, options={}, read_bufsize=nil, &block)
  new(options).parse(str_or_io, read_bufsize, &block)
end

Instance Method Details

#<<Object

call-seq: parse_chunk(string_chunk)

string_chunk can be a partial or full JSON string to push on the parser.

This method will throw an exception if the on_parse_complete callback hasn't been assigned yet. The on_parse_complete callback assignment is required so the user can handle objects that have been parsed off the stream as they're found.



# File 'ext/yajl/yajl_ext.c'

static VALUE rb_yajl_parser_parse_chunk(VALUE self, VALUE chunk) {
yajl_parser_wrapper * wrapper;
unsigned int len;

GetParser(self, wrapper);
if (NIL_P(chunk)) {
    rb_raise(cParseError, "Can't parse a nil string.");
}

#on_parse_complete=(Proc) {|obj| ... } ⇒ Object

This callback setter allows you to pass a Proc/lambda or any other object that responds to #call.

It will pass a single parameter, the ruby object built from the last parsed JSON object

Yields:

  • (obj)


# File 'ext/yajl/yajl_ext.c'

/*
 * Document-method: on_parse_complete=
 *
 * call-seq: on_parse_complete = Proc.new { |obj| ... }
 *
 * This callback setter allows you to pass a Proc/lambda or any other object that responds to #call.
 *
 * It will pass a single parameter, the ruby object built from the last parsed JSON object
 */
static VALUE rb_yajl_parser_set_complete_cb(VALUE self, VALUE callback) {
    yajl_parser_wrapper * wrapper;
    GetParser(self, wrapper);
    wrapper->parse_complete_callback = callback;
    return Qnil;
}

#parse(input, buffer_size = 8092) ⇒ Object #parse(input, buffer_size = 8092) {|obj| ... } ⇒ Object

input can either be a string or an IO to parse JSON from

buffer_size is the size of chunk that will be parsed off the input (if it's an IO) for each loop of the parsing process. 8092 is a good balance between the different types of streams (off disk, off a socket, etc???), but this option is here so the caller can better tune their parsing depending on the type of stream being passed. A larger read buffer will perform better for files off disk, where as a smaller size may be more efficient for reading off of a socket directly.

If a block was passed, it's called when an object has been parsed off the stream. This is especially usefull when parsing a stream of multiple JSON objects.

NOTE: you can optionally assign the on_parse_complete callback, and it will be called the same way the optional block is for this method.

Overloads:

  • #parse(input, buffer_size = 8092) {|obj| ... } ⇒ Object

    Yields:

    • (obj)


# File 'ext/yajl/yajl_ext.c'

/*
 * Document-method: parse
 *
 * call-seq:
 *  parse(input, buffer_size=8092)
 *  parse(input, buffer_size=8092) { |obj| ... }
 *
 * +input+ can either be a string or an IO to parse JSON from
 *
 * +buffer_size+ is the size of chunk that will be parsed off the input (if it's an IO) for each loop of the parsing process.
 * 8092 is a good balance between the different types of streams (off disk, off a socket, etc...), but this option
 * is here so the caller can better tune their parsing depending on the type of stream being passed.
 * A larger read buffer will perform better for files off disk, where as a smaller size may be more efficient for
 * reading off of a socket directly.
 *
 * If a block was passed, it's called when an object has been parsed off the stream. This is especially
 * usefull when parsing a stream of multiple JSON objects.
 *
 * NOTE: you can optionally assign the +on_parse_complete+ callback, and it will be called the same way the optional
 * block is for this method.
*/
static VALUE rb_yajl_parser_parse(int argc, VALUE * argv, VALUE self) {
yajl_status stat;
yajl_parser_wrapper * wrapper;
VALUE rbufsize, input, blk;
unsigned int len;
const char * cptr;

GetParser(self, wrapper);

/* setup our parameters */
rb_scan_args(argc, argv, "11&", &input, &rbufsize, &blk);
if (NIL_P(rbufsize)) {
    rbufsize = INT2FIX(READ_BUFSIZE);
}

#parse_chunk(string_chunk) ⇒ Object

string_chunk can be a partial or full JSON string to push on the parser.

This method will throw an exception if the on_parse_complete callback hasn't been assigned yet. The on_parse_complete callback assignment is required so the user can handle objects that have been parsed off the stream as they're found.



# File 'ext/yajl/yajl_ext.c'

/*
 * Document-method: parse_chunk
 *
 * call-seq: parse_chunk(string_chunk)
 *
 * +string_chunk+ can be a partial or full JSON string to push on the parser.
 *
 * This method will throw an exception if the +on_parse_complete+ callback hasn't been assigned yet.
 * The +on_parse_complete+ callback assignment is required so the user can handle objects that have been
 * parsed off the stream as they're found.
 */
static VALUE rb_yajl_parser_parse_chunk(VALUE self, VALUE chunk) {
yajl_parser_wrapper * wrapper;
unsigned int len;

GetParser(self, wrapper);
if (NIL_P(chunk)) {
    rb_raise(cParseError, "Can't parse a nil string.");
}