Class: Yajl::Encoder
- Defined in:
- ext/yajl_ext.c,
lib/yajl.rb,
ext/yajl_ext.c
Overview
This class contains methods for encoding a Ruby object into JSON, streaming it’s output into an IO object. The IO object need only respond to #write(str) The JSON stream created is written to the IO in chunks, as it’s being created.
Class Method Summary collapse
-
.enable_json_gem_compatability ⇒ Object
call-seq: enable_json_gem_compatability.
-
.encode(obj, *args, &block) ⇒ Object
A helper method for encode-and-forget use-cases.
-
.new(*args) ⇒ Object
call-seq: initialize([:pretty => false[, :indent => ‘ ’][, :terminator => “n”]]).
Instance Method Summary collapse
-
#encode(*args) ⇒ Object
call-seq: encode(obj[, io[, &block]]).
-
#initialize(*args) ⇒ Object
constructor
call-seq: initialize([:pretty => false[, :indent => ‘ ’][, :terminator => “n”]]).
-
#on_progress=(callback) ⇒ Object
call-seq: on_progress = Proc.new {|str| …}.
Constructor Details
#initialize(*args) ⇒ Object
call-seq: initialize([:pretty => false[, :indent => ‘ ’][, :terminator => “n”]])
:pretty will enable/disable beautifying or “pretty priting” the output string.
:indent is the character(s) used to indent the output string.
:terminator allows you to specify a character to be used as the termination character after a full JSON string has been generated by the encoder. This would be especially useful when encoding in chunks (via a block or callback during the encode process), to be able to determine when the last chunk of the current encode is sent. If you specify this option to be nil, it will be ignored if encoding directly to an IO or simply returning a string. But if a block is used, the encoder will still pass it - I hope that makes sense ;).
519 520 521 |
# File 'ext/yajl_ext.c', line 519
static VALUE rb_yajl_encoder_init(int argc, VALUE * argv, VALUE self) {
return self;
}
|
Class Method Details
.enable_json_gem_compatability ⇒ Object
call-seq: enable_json_gem_compatability
Enables the JSON gem compatibility API
780 781 782 783 784 785 786 787 788 789 790 |
# File 'ext/yajl_ext.c', line 780 static VALUE rb_yajl_encoder_enable_json_gem_ext(VALUE klass) { rb_define_method(rb_cHash, "to_json", rb_yajl_json_ext_hash_to_json, -1); rb_define_method(rb_cArray, "to_json", rb_yajl_json_ext_array_to_json, -1); rb_define_method(rb_cFixnum, "to_json", rb_yajl_json_ext_fixnum_to_json, -1); rb_define_method(rb_cFloat, "to_json", rb_yajl_json_ext_float_to_json, -1); rb_define_method(rb_cString, "to_json", rb_yajl_json_ext_string_to_json, -1); rb_define_method(rb_cTrueClass, "to_json", rb_yajl_json_ext_true_to_json, -1); rb_define_method(rb_cFalseClass, "to_json", rb_yajl_json_ext_false_to_json, -1); rb_define_method(rb_cNilClass, "to_json", rb_yajl_json_ext_nil_to_json, -1); return Qnil; } |
.encode(obj, *args, &block) ⇒ Object
A helper method for encode-and-forget use-cases
Examples:
Yajl::Encoder.encode(obj[, io, :pretty => true, :indent => "\t", &block])
output = Yajl::Encoder.encode(obj[, :pretty => true, :indent => "\t", &block])
obj
is a ruby object to encode to JSON format
io
is the optional IO stream to encode the ruby object to. If io
isn’t passed, the resulting JSON string is returned. If io
is passed, nil is returned.
The options
hash allows you to set two encoding options - :pretty and :indent
:pretty accepts a boolean and will enable/disable “pretty printing” the resulting output
:indent accepts a string and will be used as the indent character(s) during the pretty print process
If a block is passed, it will be used as (and work the same as) the on_progress
callback
53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/yajl.rb', line 53 def self.encode(obj, *args, &block) # TODO: this code smells, any ideas? = {} io = nil args.each do |arg| if arg.is_a?(Hash) = arg elsif arg.respond_to?(:read) io = arg end end if args.any? new().encode(obj, io, &block) end |
.new(*args) ⇒ Object
call-seq: initialize([:pretty => false[, :indent => ‘ ’][, :terminator => “n”]])
:pretty will enable/disable beautifying or “pretty priting” the output string.
:indent is the character(s) used to indent the output string.
:terminator allows you to specify a character to be used as the termination character after a full JSON string has been generated by the encoder. This would be especially useful when encoding in chunks (via a block or callback during the encode process), to be able to determine when the last chunk of the current encode is sent. If you specify this option to be nil, it will be ignored if encoding directly to an IO or simply returning a string. But if a block is used, the encoder will still pass it - I hope that makes sense ;).
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 |
# File 'ext/yajl_ext.c', line 470
static VALUE rb_yajl_encoder_new(int argc, VALUE * argv, VALUE klass) {
struct yajl_encoder_wrapper * wrapper;
yajl_gen_config cfg;
VALUE opts, obj, indent;
const char * indentString = " ";
int beautify = 0;
// Scan off config vars
if (rb_scan_args(argc, argv, "01", &opts) == 1) {
Check_Type(opts, T_HASH);
if (rb_hash_aref(opts, ID2SYM(sym_pretty)) == Qtrue) {
beautify = 1;
indent = rb_hash_aref(opts, ID2SYM(sym_indent));
if (indent != Qnil) {
Check_Type(indent, T_STRING);
indentString = RSTRING_PTR(indent);
}
}
}
cfg = (yajl_gen_config){beautify, indentString};
obj = Data_Make_Struct(klass, struct yajl_encoder_wrapper, yajl_encoder_wrapper_mark, yajl_encoder_wrapper_free, wrapper);
wrapper->encoder = yajl_gen_alloc(&cfg, NULL);
wrapper->on_progress_callback = Qnil;
if (opts != Qnil && rb_funcall(opts, intern_has_key, 1, ID2SYM(sym_terminator)) == Qtrue) {
wrapper->terminator = rb_hash_aref(opts, ID2SYM(sym_terminator));
} else {
wrapper->terminator = 0;
}
rb_obj_call_init(obj, 0, 0);
return obj;
}
|
Instance Method Details
#encode(*args) ⇒ Object
call-seq: encode(obj[, io[, &block]])
obj
is the Ruby object to encode to JSON
io
is an optional IO used to stream the encoded JSON string to. If io
isn’t specified, this method will return the resulting JSON string. If io
is specified, this method returns nil
If an optional block is passed, it’s called when encoding is complete and passed the resulting JSON string
It should be noted that you can reuse an instance of this class to continue encoding multiple JSON to the same stream. Just continue calling this method, passing it the same IO object with new/different ruby objects to encode. This is how streaming is accomplished.
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 |
# File 'ext/yajl_ext.c', line 539
static VALUE rb_yajl_encoder_encode(int argc, VALUE * argv, VALUE self) {
struct yajl_encoder_wrapper * wrapper;
const unsigned char * buffer;
unsigned int len;
VALUE obj, io, blk, outBuff;
GetEncoder(self, wrapper);
rb_scan_args(argc, argv, "11&", &obj, &io, &blk);
if (blk != Qnil) {
wrapper->on_progress_callback = blk;
}
// begin encode process
yajl_encode_part(wrapper, obj, io);
// just make sure we output the remaining buffer
yajl_gen_get_buf(wrapper->encoder, &buffer, &len);
outBuff = rb_str_new((const char *)buffer, len);
yajl_gen_clear(wrapper->encoder);
if (io != Qnil) {
rb_io_write(io, outBuff);
if (wrapper->terminator != 0 && wrapper->terminator != Qnil) {
rb_io_write(io, wrapper->terminator);
}
return Qnil;
} else if (blk != Qnil) {
rb_funcall(blk, intern_call, 1, outBuff);
if (wrapper->terminator != 0) {
rb_funcall(blk, intern_call, 1, wrapper->terminator);
}
return Qnil;
} else {
if (wrapper->terminator != 0 && wrapper->terminator != Qnil) {
rb_str_concat(outBuff, wrapper->terminator);
}
return outBuff;
}
return Qnil;
}
|
#on_progress=(callback) ⇒ Object
call-seq: on_progress = Proc.new {|str| …}
This callback setter allows you to pass a Proc/lambda or any other object that responds to #call.
It will pass the caller a chunk of the encode buffer after it’s reached it’s internal max buffer size (defaults to 8kb). For example, encoding a large object that would normally result in 24288 bytes of data will result in 3 calls to this callback (assuming the 8kb default encode buffer).
592 593 594 595 596 597 |
# File 'ext/yajl_ext.c', line 592
static VALUE rb_yajl_encoder_set_progress_cb(VALUE self, VALUE callback) {
struct yajl_encoder_wrapper * wrapper;
GetEncoder(self, wrapper);
wrapper->on_progress_callback = callback;
return Qnil;
}
|