yajl-ruby 0.5.11 → 0.5.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of yajl-ruby might be problematic. Click here for more details.
- data/CHANGELOG.md +4 -0
- data/README.rdoc +45 -2
- data/VERSION.yml +2 -2
- data/ext/yajl_ext.c +36 -6
- data/ext/yajl_ext.h +3 -2
- data/lib/yajl.rb +1 -1
- data/spec/encoding/encoding_spec.rb +36 -0
- data/yajl-ruby.gemspec +3 -3
- metadata +4 -3
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.5.12 (July 31st, 2009)
|
4
|
+
* Add another option that can be passed to Yajl::Encoder's constructor (:terminator) to allow the caller some control over
|
5
|
+
when a full JSON string has been generated by the encoder. More information on it's use in the README
|
6
|
+
|
3
7
|
## 0.5.11 (July 14th, 2009)
|
4
8
|
* fixing a bug Aman found with to_json on non-primitive Ruby objects and double-quoting in the JSON compat API
|
5
9
|
|
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= YAJL C Bindings for Ruby
|
2
2
|
|
3
|
-
This gem
|
3
|
+
This gem is a C binding to the excellent YAJL JSON parsing and generation library.
|
4
4
|
|
5
5
|
You can read more info at the projects website http://lloydforge.org/projects/yajl or check out it's codes at http://github.com/lloyd/yajl.
|
6
6
|
|
@@ -27,6 +27,8 @@ Install it like any other gem hosted at the Githubs like so:
|
|
27
27
|
|
28
28
|
== Example of use
|
29
29
|
|
30
|
+
NOTE: I'm building up a collection of small examples in the examples (http://github.com/brianmario/yajl-ruby/tree/master/examples) folder.
|
31
|
+
|
30
32
|
First, you're probably gonna want to require it:
|
31
33
|
|
32
34
|
require 'yajl'
|
@@ -77,6 +79,11 @@ only had access to chunks of it at a time. No problem!
|
|
77
79
|
@parser << data
|
78
80
|
end
|
79
81
|
|
82
|
+
Or if you don't need to stream it, it'll just return the built object from the parse when it's done.
|
83
|
+
NOTE: if there are going to be multiple JSON strings in the input, you *must* specify a block or callback as this
|
84
|
+
is how yajl-ruby will hand you (the caller) each object as it's parsed off the input.
|
85
|
+
|
86
|
+
obj = Yajl::Parser.parse(str_or_io)
|
80
87
|
|
81
88
|
Or how about a JSON API HTTP request?
|
82
89
|
This actually makes a request using a raw TCPSocket, then parses the JSON body right off the socket. While it's being received over the wire!
|
@@ -150,6 +157,42 @@ This example will encode and send 50 JSON objects over the same stream, continuo
|
|
150
157
|
encoder.encode(hash, socket)
|
151
158
|
end
|
152
159
|
|
160
|
+
Using EventMachine and you want to encode and send in chunks?
|
161
|
+
(Assume we're in an EventMachine::Connection instance)
|
162
|
+
|
163
|
+
def post_init
|
164
|
+
# Passing a :terminator character will let us determine when the encoder
|
165
|
+
# is done encoding the current object
|
166
|
+
@encoder = Yajl::Encoder.new(:terminator => nil)
|
167
|
+
motd_contents = File.read("/path/to/motd.txt")
|
168
|
+
status = File.read("/path/to/huge/status_file.txt")
|
169
|
+
@motd = {:motd => motd_contents, :system_status => status}
|
170
|
+
end
|
171
|
+
|
172
|
+
def connection_completed
|
173
|
+
# The encoder will do it's best to hand you data in chunks that
|
174
|
+
# are around 8kb (but you may see some that are larger)
|
175
|
+
#
|
176
|
+
# It should be noted that you could have also assigned the _on_progress_ callback
|
177
|
+
# much like you can assign the _on_parse_complete_ callback with the parser class.
|
178
|
+
# Passing a block (like below) essentially tells the encoder to use that block
|
179
|
+
# as the callback normally assigned to _on_progress_.
|
180
|
+
#
|
181
|
+
# Send our MOTD and status
|
182
|
+
@encoder.encode(@motd) do |chunk|
|
183
|
+
if chunk.nil?
|
184
|
+
close_connection_after_writing
|
185
|
+
else
|
186
|
+
send_data(chunk)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
But to make things simple, you might just want to let yajl-ruby do all the hard work for you and just hand back
|
192
|
+
a string when it's finished. In that case, just don't provide and IO or block (or assign the on_progress callback).
|
193
|
+
|
194
|
+
str = Yajl::Encoder.encode(obj)
|
195
|
+
|
153
196
|
You can also use Yajl::Bzip2::StreamWriter and Yajl::Deflate::StreamWriter. So you can pick whichever fits your CPU/bandwidth sweet-spot.
|
154
197
|
|
155
198
|
== JSON gem Compatibility API
|
@@ -174,7 +217,7 @@ There are a lot more possibilities that I'd love to see other gems/plugins for s
|
|
174
217
|
Some ideas are:
|
175
218
|
* parsing logs in JSON format
|
176
219
|
* a Rails plugin (http://github.com/technoweenie/yajl-rails)
|
177
|
-
* builtin Rails 3
|
220
|
+
* builtin support in Rails 3?
|
178
221
|
* Rack middleware (ideally the JSON body could be handed to the parser while it's still being received)
|
179
222
|
* use with ohai (http://github.com/brianmario/ohai)
|
180
223
|
* JSON API clients (http://github.com/brianmario/crack, http://github.com/brianmario/freckle-api)
|
data/VERSION.yml
CHANGED
data/ext/yajl_ext.c
CHANGED
@@ -69,6 +69,7 @@ static void yajl_encoder_wrapper_free(void * wrapper) {
|
|
69
69
|
static void yajl_encoder_wrapper_mark(void * wrapper) {
|
70
70
|
struct yajl_encoder_wrapper * w = wrapper;
|
71
71
|
rb_gc_mark(w->on_progress_callback);
|
72
|
+
rb_gc_mark(w->terminator);
|
72
73
|
}
|
73
74
|
|
74
75
|
void yajl_encode_part(void * wrapper, VALUE obj, VALUE io) {
|
@@ -445,11 +446,17 @@ static VALUE rb_yajl_parser_set_complete_cb(VALUE self, VALUE callback) {
|
|
445
446
|
/*
|
446
447
|
* Document-method: new
|
447
448
|
*
|
448
|
-
* call-seq:
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
449
|
+
* call-seq: initialize([:pretty => false[, :indent => ' '][, :terminator => "\n"]])
|
450
|
+
*
|
451
|
+
* :pretty will enable/disable beautifying or "pretty priting" the output string.
|
452
|
+
*
|
453
|
+
* :indent is the character(s) used to indent the output string.
|
454
|
+
*
|
455
|
+
* :terminator allows you to specify a character to be used as the termination character after a full JSON string has been generated by
|
456
|
+
* the encoder. This would be especially useful when encoding in chunks (via a block or callback during the encode process), to be able to
|
457
|
+
* determine when the last chunk of the current encode is sent.
|
458
|
+
* 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,
|
459
|
+
* the encoder will still pass it - I hope that makes sense ;).
|
453
460
|
*/
|
454
461
|
static VALUE rb_yajl_encoder_new(int argc, VALUE * argv, VALUE klass) {
|
455
462
|
struct yajl_encoder_wrapper * wrapper;
|
@@ -476,6 +483,11 @@ static VALUE rb_yajl_encoder_new(int argc, VALUE * argv, VALUE klass) {
|
|
476
483
|
obj = Data_Make_Struct(klass, struct yajl_encoder_wrapper, yajl_encoder_wrapper_mark, yajl_encoder_wrapper_free, wrapper);
|
477
484
|
wrapper->encoder = yajl_gen_alloc(&cfg, NULL);
|
478
485
|
wrapper->on_progress_callback = Qnil;
|
486
|
+
if (opts != Qnil && rb_funcall(opts, intern_has_key, 1, ID2SYM(sym_terminator)) == Qtrue) {
|
487
|
+
wrapper->terminator = rb_hash_aref(opts, ID2SYM(sym_terminator));
|
488
|
+
} else {
|
489
|
+
wrapper->terminator = 0;
|
490
|
+
}
|
479
491
|
rb_obj_call_init(obj, 0, 0);
|
480
492
|
return obj;
|
481
493
|
}
|
@@ -483,11 +495,17 @@ static VALUE rb_yajl_encoder_new(int argc, VALUE * argv, VALUE klass) {
|
|
483
495
|
/*
|
484
496
|
* Document-method: initialize
|
485
497
|
*
|
486
|
-
* call-seq: initialize([:pretty => false[, :indent => ' ']])
|
498
|
+
* call-seq: initialize([:pretty => false[, :indent => ' '][, :terminator => "\n"]])
|
487
499
|
*
|
488
500
|
* :pretty will enable/disable beautifying or "pretty priting" the output string.
|
489
501
|
*
|
490
502
|
* :indent is the character(s) used to indent the output string.
|
503
|
+
*
|
504
|
+
* :terminator allows you to specify a character to be used as the termination character after a full JSON string has been generated by
|
505
|
+
* the encoder. This would be especially useful when encoding in chunks (via a block or callback during the encode process), to be able to
|
506
|
+
* determine when the last chunk of the current encode is sent.
|
507
|
+
* 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,
|
508
|
+
* the encoder will still pass it - I hope that makes sense ;).
|
491
509
|
*/
|
492
510
|
static VALUE rb_yajl_encoder_init(int argc, VALUE * argv, VALUE self) {
|
493
511
|
return self;
|
@@ -530,13 +548,23 @@ static VALUE rb_yajl_encoder_encode(int argc, VALUE * argv, VALUE self) {
|
|
530
548
|
yajl_gen_get_buf(wrapper->encoder, &buffer, &len);
|
531
549
|
outBuff = rb_str_new((const char *)buffer, len);
|
532
550
|
yajl_gen_clear(wrapper->encoder);
|
551
|
+
|
533
552
|
if (io != Qnil) {
|
534
553
|
rb_io_write(io, outBuff);
|
554
|
+
if (wrapper->terminator != 0 && wrapper->terminator != Qnil) {
|
555
|
+
rb_io_write(io, wrapper->terminator);
|
556
|
+
}
|
535
557
|
return Qnil;
|
536
558
|
} else if (blk != Qnil) {
|
537
559
|
rb_funcall(blk, intern_call, 1, outBuff);
|
560
|
+
if (wrapper->terminator != 0) {
|
561
|
+
rb_funcall(blk, intern_call, 1, wrapper->terminator);
|
562
|
+
}
|
538
563
|
return Qnil;
|
539
564
|
} else {
|
565
|
+
if (wrapper->terminator != 0 && wrapper->terminator != Qnil) {
|
566
|
+
rb_str_concat(outBuff, wrapper->terminator);
|
567
|
+
}
|
540
568
|
return outBuff;
|
541
569
|
}
|
542
570
|
return Qnil;
|
@@ -787,5 +815,7 @@ void Init_yajl_ext() {
|
|
787
815
|
sym_check_utf8 = rb_intern("check_utf8");
|
788
816
|
sym_pretty = rb_intern("pretty");
|
789
817
|
sym_indent = rb_intern("indent");
|
818
|
+
sym_terminator = rb_intern("terminator");
|
790
819
|
sym_symbolize_keys = rb_intern("symbolize_keys");
|
820
|
+
intern_has_key = rb_intern("has_key?");
|
791
821
|
}
|
data/ext/yajl_ext.h
CHANGED
@@ -6,8 +6,8 @@
|
|
6
6
|
#define WRITE_BUFSIZE 8092
|
7
7
|
|
8
8
|
static VALUE cParseError, cEncodeError, mYajl, cParser, cEncoder;
|
9
|
-
static ID intern_io_read, intern_eof, intern_call, intern_keys, intern_to_s, intern_to_json,
|
10
|
-
sym_allow_comments, sym_check_utf8, sym_pretty, sym_indent, sym_symbolize_keys;
|
9
|
+
static ID intern_io_read, intern_eof, intern_call, intern_keys, intern_to_s, intern_to_json, intern_has_key,
|
10
|
+
sym_allow_comments, sym_check_utf8, sym_pretty, sym_indent, sym_terminator, sym_symbolize_keys;
|
11
11
|
|
12
12
|
#define GetParser(obj, sval) (sval = (struct yajl_parser_wrapper*)DATA_PTR(obj));
|
13
13
|
#define GetEncoder(obj, sval) (sval = (struct yajl_encoder_wrapper*)DATA_PTR(obj));
|
@@ -53,6 +53,7 @@ struct yajl_parser_wrapper {
|
|
53
53
|
|
54
54
|
struct yajl_encoder_wrapper {
|
55
55
|
VALUE on_progress_callback;
|
56
|
+
VALUE terminator;
|
56
57
|
yajl_gen encoder;
|
57
58
|
};
|
58
59
|
|
data/lib/yajl.rb
CHANGED
@@ -187,4 +187,40 @@ describe "Yajl JSON encoder" do
|
|
187
187
|
it "should encode a hash where the key and value can be symbols" do
|
188
188
|
Yajl::Encoder.encode({:foo => :bar}).should eql('{"foo":"bar"}')
|
189
189
|
end
|
190
|
+
|
191
|
+
it "should encode using a newline or nil terminator" do
|
192
|
+
Yajl::Encoder.new(:terminator => "\n").encode({:foo => :bar}).should eql("{\"foo\":\"bar\"}\n")
|
193
|
+
Yajl::Encoder.new(:terminator => nil).encode({:foo => :bar}).should eql("{\"foo\":\"bar\"}")
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should encode using a newline or nil terminator, to an IO" do
|
197
|
+
s = StringIO.new
|
198
|
+
Yajl::Encoder.new(:terminator => "\n").encode({:foo => :bar}, s)
|
199
|
+
s.rewind
|
200
|
+
s.read.should eql("{\"foo\":\"bar\"}\n")
|
201
|
+
|
202
|
+
s = StringIO.new
|
203
|
+
Yajl::Encoder.new(:terminator => nil).encode({:foo => :bar}, s)
|
204
|
+
s.rewind
|
205
|
+
s.read.should eql("{\"foo\":\"bar\"}")
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should encode using a newline or nil terminator, using a block" do
|
209
|
+
s = StringIO.new
|
210
|
+
Yajl::Encoder.new(:terminator => "\n").encode({:foo => :bar}) do |chunk|
|
211
|
+
s << chunk
|
212
|
+
end
|
213
|
+
s.rewind
|
214
|
+
s.read.should eql("{\"foo\":\"bar\"}\n")
|
215
|
+
|
216
|
+
s = StringIO.new
|
217
|
+
nilpassed = false
|
218
|
+
Yajl::Encoder.new(:terminator => nil).encode({:foo => :bar}) do |chunk|
|
219
|
+
nilpassed = true if chunk.nil?
|
220
|
+
s << chunk
|
221
|
+
end
|
222
|
+
nilpassed.should be_true
|
223
|
+
s.rewind
|
224
|
+
s.read.should eql("{\"foo\":\"bar\"}")
|
225
|
+
end
|
190
226
|
end
|
data/yajl-ruby.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{yajl-ruby}
|
5
|
-
s.version = "0.5.
|
5
|
+
s.version = "0.5.12"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Brian Lopez", "Lloyd Hilaiel"]
|
9
|
-
s.date = %q{2009-07-
|
9
|
+
s.date = %q{2009-07-31}
|
10
10
|
s.email = %q{seniorlopez@gmail.com}
|
11
11
|
s.extensions = ["ext/extconf.rb"]
|
12
12
|
s.extra_rdoc_files = [
|
@@ -152,7 +152,7 @@ Gem::Specification.new do |s|
|
|
152
152
|
s.rdoc_options = ["--charset=UTF-8"]
|
153
153
|
s.require_paths = ["lib", "ext"]
|
154
154
|
s.rubyforge_project = %q{yajl-ruby}
|
155
|
-
s.rubygems_version = %q{1.3.
|
155
|
+
s.rubygems_version = %q{1.3.5}
|
156
156
|
s.summary = %q{Ruby C bindings to the excellent Yajl JSON stream-based parser library.}
|
157
157
|
s.test_files = [
|
158
158
|
"spec/encoding/encoding_spec.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yajl-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Lopez
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-07-
|
13
|
+
date: 2009-07-31 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -182,8 +182,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
182
182
|
requirements: []
|
183
183
|
|
184
184
|
rubyforge_project: yajl-ruby
|
185
|
-
rubygems_version: 1.3.
|
185
|
+
rubygems_version: 1.3.5
|
186
186
|
signing_key:
|
187
|
+
source:
|
187
188
|
specification_version: 3
|
188
189
|
summary: Ruby C bindings to the excellent Yajl JSON stream-based parser library.
|
189
190
|
test_files:
|