brianmario-yajl-ruby 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/.gitignore +4 -0
  2. data/CHANGELOG.rdoc +13 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +39 -3
  5. data/Rakefile +4 -12
  6. data/VERSION.yml +2 -2
  7. data/benchmark/http.rb +28 -0
  8. data/benchmark/stream.rb +40 -0
  9. data/benchmark/subjects/contacts.json +1 -0
  10. data/benchmark/subjects/item.json +1 -0
  11. data/benchmark/subjects/ohai.json +1216 -0
  12. data/benchmark/subjects/twitter_search.json +1 -0
  13. data/benchmark/subjects/unicode.json +3315 -0
  14. data/benchmark/subjects/yelp.json +1 -0
  15. data/ext/extconf.rb +1 -0
  16. data/ext/yajl.c +86 -40
  17. data/ext/yajl.h +45 -0
  18. data/lib/yajl/http_stream.rb +67 -0
  19. data/lib/yajl.rb +32 -0
  20. data/specs/active_support_spec.rb +50 -0
  21. data/specs/fixtures/fail.15.json +1 -0
  22. data/specs/fixtures/fail.16.json +1 -0
  23. data/specs/fixtures/fail.17.json +1 -0
  24. data/specs/fixtures/fail.26.json +1 -0
  25. data/specs/fixtures/fail11.json +1 -0
  26. data/specs/fixtures/fail12.json +1 -0
  27. data/specs/fixtures/fail13.json +1 -0
  28. data/specs/fixtures/fail14.json +1 -0
  29. data/specs/fixtures/fail19.json +1 -0
  30. data/specs/fixtures/fail20.json +1 -0
  31. data/specs/fixtures/fail21.json +1 -0
  32. data/specs/fixtures/fail22.json +1 -0
  33. data/specs/fixtures/fail23.json +1 -0
  34. data/specs/fixtures/fail24.json +1 -0
  35. data/specs/fixtures/fail25.json +1 -0
  36. data/specs/fixtures/fail27.json +2 -0
  37. data/specs/fixtures/fail28.json +2 -0
  38. data/specs/fixtures/fail3.json +1 -0
  39. data/specs/fixtures/fail4.json +1 -0
  40. data/specs/fixtures/fail5.json +1 -0
  41. data/specs/fixtures/fail6.json +1 -0
  42. data/specs/fixtures/fail9.json +1 -0
  43. data/specs/fixtures/pass.array.json +6 -0
  44. data/specs/fixtures/pass.codepoints_from_unicode_org.json +1 -0
  45. data/specs/fixtures/pass.contacts.json +1 -0
  46. data/specs/fixtures/pass.db100.xml.json +1 -0
  47. data/specs/fixtures/pass.db1000.xml.json +1 -0
  48. data/specs/fixtures/pass.dc_simple_with_comments.json +11 -0
  49. data/specs/fixtures/pass.deep_arrays.json +1 -0
  50. data/specs/fixtures/pass.difficult_json_c_test_case.json +1 -0
  51. data/specs/fixtures/pass.difficult_json_c_test_case_with_comments.json +1 -0
  52. data/specs/fixtures/pass.doubles.json +1 -0
  53. data/specs/fixtures/pass.empty_array.json +1 -0
  54. data/specs/fixtures/pass.empty_string.json +1 -0
  55. data/specs/fixtures/pass.escaped_bulgarian.json +4 -0
  56. data/specs/fixtures/pass.escaped_foobar.json +1 -0
  57. data/specs/fixtures/pass.item.json +1 -0
  58. data/specs/fixtures/pass.json-org-sample1.json +23 -0
  59. data/specs/fixtures/pass.json-org-sample2.json +11 -0
  60. data/specs/fixtures/pass.json-org-sample3.json +26 -0
  61. data/specs/fixtures/pass.json-org-sample4-nows.json +88 -0
  62. data/specs/fixtures/pass.json-org-sample4.json +89 -0
  63. data/specs/fixtures/pass.json-org-sample5.json +27 -0
  64. data/specs/fixtures/pass.map-spain.xml.json +1 -0
  65. data/specs/fixtures/pass.ns-invoice100.xml.json +1 -0
  66. data/specs/fixtures/pass.ns-soap.xml.json +1 -0
  67. data/specs/fixtures/pass.numbers-fp-4k.json +6 -0
  68. data/specs/fixtures/pass.numbers-fp-64k.json +61 -0
  69. data/specs/fixtures/pass.numbers-int-4k.json +11 -0
  70. data/specs/fixtures/pass.numbers-int-64k.json +154 -0
  71. data/specs/fixtures/pass.twitter-search.json +1 -0
  72. data/specs/fixtures/pass.twitter-search2.json +1 -0
  73. data/specs/fixtures/pass.unicode.json +3315 -0
  74. data/specs/fixtures/pass.yelp.json +1 -0
  75. data/specs/fixtures/pass1.json +56 -0
  76. data/specs/fixtures/pass2.json +1 -0
  77. data/specs/fixtures/pass3.json +6 -0
  78. data/specs/fixtures_spec.rb +25 -0
  79. data/specs/one_off_spec.rb +11 -0
  80. data/specs/spec_helper.rb +4 -0
  81. data/yajl-ruby.gemspec +115 -0
  82. metadata +79 -2
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ Makefile
2
+ *.o
3
+ *.dylib
4
+ *.bundle
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,18 @@
1
1
  = Changelog
2
2
 
3
+ 0.4.0 (?)
4
+ * NOTE: Breaking API change:
5
+ ** refactored Stream parsing methods out of Yajl::Native into Yajl::Stream
6
+ ** removed Yajl::Native namespace/module
7
+ * Addition of Yajl::HttpStream module
8
+ ** This module is for streaming JSON HTTP responses directly into Yajl (as they're being received) for increased awesomeness
9
+ ** it currently supports basic get requests with Yajl::HttpStream.get(uri)
10
+ ** it also supports (and prefers) output compressed (gzip) responses
11
+ * Addition Yajl::Chunked module
12
+ ** This module is for feeding Yajl JSON pieces at a time, instead of an entire IO object
13
+ ** This works very well in environments like an EventMachine app where data is received in chunks by design
14
+ * decreased read buffer for Yajl::Stream from 8kb to 4kb
15
+
3
16
  0.3.4 (April 24th, 2009)
4
17
  * turned Unicode checks back on in the Yajl parser now that it's fixed (thanks Lloyd!)
5
18
  ** this also bumps the yajl version dependency requirement to 1.0.4
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2009 Brian Lopez - http://github.com/brianmario
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc CHANGED
@@ -26,11 +26,36 @@ or maybe STDIN
26
26
 
27
27
  cat someJsonFile.json | ruby -ryajl -e "puts Yajl::Native.parse(STDIN).inspect"
28
28
 
29
+
30
+ Or lets say you didn't have access to the IO object that contained JSON data, but instead
31
+ only had access to chunks of it at a time. No problem!
32
+
33
+ (Assume we're in an EventMachine::Connection instance)
34
+
35
+ def object_parsed(obj)
36
+ puts "Sometimes one pays most for the things one gets for nothing. - Albert Einstein"
37
+ puts obj.inspect
38
+ end
39
+
40
+ def connection_completed
41
+ # once a full JSON object has been parsed from the stream
42
+ # object_parsed will be called, and passed the constructed object
43
+ Yajl::Chunked.on_parse_complete = method(:object_parsed)
44
+ end
45
+
46
+ def receive_data(data)
47
+ # continue passing chunks
48
+ Yajl::Chunked.parse_some(data)
49
+
50
+ # Or as an alias, you could have done:
51
+ # Yajl::Chunked << data
52
+ end
53
+
29
54
  There are a lot more possibilities, some of which I'm going to write other gems/plugins for.
30
55
 
31
56
  Some ideas are:
32
57
  * parsing logs in JSON format
33
- * an ActiveSupport patch (http://github.com/technoweenie/rails/commit/f9abcc93a3660fcf46172c4cd8a2f36ba5a5510d)
58
+ * an ActiveSupport patch (http://github.com/technoweenie/rails/commit/f9abcc93a3660fcf46172c4cd8a2f36ba5a5510d)
34
59
  * Rack middleware (ideally the JSON body could be handed to the parser while it's still being received)
35
60
  * use with ohai
36
61
  * JSON API clients
@@ -40,7 +65,7 @@ Some ideas are:
40
65
 
41
66
  First, Yajl uses CMake to build itself (yes, the author realizes this isn't the norm for open source and is willing and ready to accept patches, fork away kids!) so you'll need to grab it first from http://www.cmake.org.
42
67
 
43
- After you've got that, grab the latest version of Yajl itself from the Githubs at http://github.com/lloyd/yajl.
68
+ After you've got that, grab the latest version (I suggest at least 1.0.4 as it contains fixes for Unicode parsing) of Yajl itself from the Githubs at http://github.com/lloyd/yajl.
44
69
 
45
70
  After you have that installed, you should be able to install it like any other gem hosted here like so:
46
71
 
@@ -79,4 +104,15 @@ Here's a list of things I need to get done to improve the awesomeness of this li
79
104
  * Write up a test suite
80
105
  * Fix known parsing issues with certain JSON strings (Yajl itself works fine, it's the logic in this library that needs a little tweaking)
81
106
  * Write more docs
82
- * Change API so it can accept a String or an IO
107
+ * Change API so it can accept a String or an IO
108
+
109
+ == Special Thanks
110
+
111
+ I've had a lot of inspiration, and a lot of help. Thanks to everyone who's been a part of this and those to come!
112
+
113
+ * Lloyd Hilaiel (http://github.com/lloyd) - for writing Yajl!!
114
+ * Josh Ferguson (http://github.com/besquared) - for peer-pressuring me into getting back into C; it worked ;)
115
+ * Jonathan Novak (http://github.com/cypriss) - C hacking help
116
+ * Tom Smith (http://github.com/rtomsmith) - C hacking help
117
+ * Rick (http://github.com/technoweenie) - for making an ActiveSupport patch with support for this library and teasing me that it might go into Rails 3. You sure lit a fire under my ass and I got a ton of work done because of it! :)
118
+ * The entire Github Crew - my inspiration, time spent writing this, finding Yajl, So many-MANY other things wouldn't have been possible without this awesome service. I owe you guys some whiskey at Kilowatt.
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  begin
2
3
  require 'jeweler'
3
4
  Jeweler::Tasks.new do |gem|
@@ -6,18 +7,9 @@ begin
6
7
  gem.email = "seniorlopez@gmail.com"
7
8
  gem.homepage = "http://github.com/brianmario/yajl-ruby"
8
9
  gem.authors = ["Brian Lopez"]
9
- gem.require_paths = ["ext"]
10
- gem.extra_rdoc_files = [
11
- "README.rdoc",
12
- "CHANGELOG.rdoc"
13
- ]
14
- gem.files = [
15
- "CHANGELOG.rdoc",
16
- "README.rdoc",
17
- "Rakefile",
18
- "VERSION.yml",
19
- "ext/yajl.c"
20
- ]
10
+ gem.require_paths = ["ext", "lib"]
11
+ gem.extra_rdoc_files = `git ls-files *.rdoc`.split("\n")
12
+ gem.files = `git ls-files`.split("\n")
21
13
  gem.extensions = ["ext/extconf.rb"]
22
14
  gem.files.include %w(lib/jeweler/templates/.document lib/jeweler/templates/.gitignore)
23
15
  # gem.rubyforge_project = "yajl-ruby"
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 4
2
+ :patch: 0
3
3
  :major: 0
4
- :minor: 3
4
+ :minor: 4
data/benchmark/http.rb ADDED
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ require 'benchmark'
4
+ require 'yajl'
5
+ require 'yajl/http_stream'
6
+ require 'json'
7
+ require 'activesupport'
8
+ require 'uri'
9
+ require 'net/http'
10
+
11
+ uri = URI.parse('http://search.twitter.com/search.json?q=github')
12
+
13
+ times = ARGV[0] ? ARGV[0].to_i : 1
14
+ puts "Starting benchmark parsing #{uri.to_s} #{times} times\n\n"
15
+ Benchmark.bm { |x|
16
+ x.report {
17
+ puts "Yajl::HttpStream.get"
18
+ times.times {
19
+ Yajl::HttpStream.get(uri)
20
+ }
21
+ }
22
+ x.report {
23
+ puts "JSON.parser"
24
+ times.times {
25
+ JSON.parse(Net::HTTP.get_response(uri).body, :max_nesting => false)
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,40 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ require 'benchmark'
4
+ require 'yajl'
5
+ require 'json'
6
+ require 'activesupport'
7
+
8
+ filename = ARGV[0] || 'subjects/twitter_search.json'
9
+ json = File.new(filename, 'r')
10
+
11
+ # warm up the filesystem
12
+ json.read
13
+ json.rewind
14
+
15
+ times = ARGV[1] ? ARGV[1].to_i : 1
16
+ puts "Starting benchmark parsing #{File.size(filename)} bytes of JSON data #{times} times\n\n"
17
+ Benchmark.bm { |x|
18
+ x.report {
19
+ puts "Yajl::Native.parse (C)"
20
+ times.times {
21
+ json.rewind
22
+ Yajl::Stream.parse(json)
23
+ }
24
+ }
25
+ x.report {
26
+ puts "JSON.parser"
27
+ times.times {
28
+ json.rewind
29
+ JSON.parse(json.read, :max_nesting => false)
30
+ }
31
+ }
32
+ x.report {
33
+ puts "ActiveSupport::JSON.decode"
34
+ times.times {
35
+ json.rewind
36
+ ActiveSupport::JSON.decode(json.read)
37
+ }
38
+ }
39
+ }
40
+ json.close