yajl-ruby 0.5.11 → 0.5.12

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of yajl-ruby might be problematic. Click here for more details.

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 (although not in gem form just yet) is a C binding to the excellent YAJL JSON parsing and generation library.
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 support?
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
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 11
3
- :major: 0
4
2
  :minor: 5
3
+ :patch: 12
4
+ :major: 0
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: new([:pretty => false[, :indent => ' ']])
449
- *
450
- * :pretty will enable/disable beautifying or "pretty priting" the output string.
451
- *
452
- * :indent is the character(s) used to indent the output string.
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
@@ -13,7 +13,7 @@ require 'yajl_ext'
13
13
  #
14
14
  # Ruby bindings to the excellent Yajl (Yet Another JSON Parser) ANSI C library.
15
15
  module Yajl
16
- VERSION = "0.5.11"
16
+ VERSION = "0.5.12"
17
17
 
18
18
  class Parser
19
19
  # A helper method for parse-and-forget use-cases
@@ -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.11"
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-14}
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.4}
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.11
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-14 00:00:00 -07:00
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.4
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: