yajl-ruby 0.6.3 → 0.6.4
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 +13 -0
- data/README.rdoc +9 -7
- data/VERSION.yml +2 -2
- data/benchmark/encode.rb +3 -3
- data/benchmark/encode_json_and_marshal.rb +2 -2
- data/benchmark/encode_json_and_yaml.rb +4 -5
- data/benchmark/http.rb +2 -2
- data/benchmark/parse.rb +5 -7
- data/benchmark/parse_json_and_marshal.rb +5 -9
- data/benchmark/parse_json_and_yaml.rb +5 -13
- data/benchmark/parse_stream.rb +13 -19
- data/ext/api/yajl_gen.h +7 -1
- data/ext/yajl_ext.c +48 -41
- data/ext/yajl_ext.h +20 -3
- data/ext/yajl_gen.c +10 -1
- data/ext/yajl_parser.c +2 -2
- data/lib/yajl.rb +20 -9
- data/lib/yajl/json_gem/encoding.rb +9 -6
- data/lib/yajl/json_gem/parsing.rb +2 -1
- data/spec/encoding/encoding_spec.rb +82 -96
- data/spec/global/global_spec.rb +55 -0
- data/spec/http/http_delete_spec.rb +15 -9
- data/spec/http/http_get_spec.rb +14 -8
- data/spec/http/http_post_spec.rb +14 -8
- data/spec/http/http_put_spec.rb +14 -8
- data/spec/json_gem_compatibility/compatibility_spec.rb +18 -4
- data/spec/parsing/one_off_spec.rb +6 -2
- data/yajl-ruby.gemspec +4 -2
- metadata +4 -2
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.6.4 (November 4th, 2009)
|
4
|
+
* All specs pass on Rubinius :)
|
5
|
+
* Fixed a bug in Yajl::Encoder which allowed direct, unescaped encoding of NaN, Infinity and -Infinity.
|
6
|
+
It will now properly throw a Yajl::EncodeError exception if either of these values are found unescaped.
|
7
|
+
* Update bundled Yajl library to 1.0.7
|
8
|
+
* Conditionally define RSTRING_* and RARRAY_* for older versions of ruby (1.8.5 is still the default on CentOS)
|
9
|
+
* Bugfix for JSON gem exception classes to more accurately match those of the actual JSON gem
|
10
|
+
* A few small speed optimizations
|
11
|
+
* Updated specs to not run bzip2 related examples if unable to load the bzip2 library
|
12
|
+
* Finally added UTF-8 checking specs
|
13
|
+
* Removed needless calls to ID2SYM all over the place
|
14
|
+
* Updated benchmark scripts to bring the GC into the picture a little more
|
15
|
+
|
3
16
|
## 0.6.3 (August 25th, 2009)
|
4
17
|
* Fixed a bug in the JSON gem compatibility API where strings weren't being properly escaped
|
5
18
|
|
data/README.rdoc
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
This gem is a C binding to the excellent YAJL JSON parsing and generation library.
|
4
4
|
|
5
|
-
You can read more info at the projects website http://
|
5
|
+
You can read more info at the projects website http://lloyd.github.com/yajl or check out it's codes at http://github.com/lloyd/yajl.
|
6
6
|
|
7
7
|
== Features
|
8
8
|
|
@@ -19,11 +19,13 @@ You can read more info at the projects website http://lloydforge.org/projects/ya
|
|
19
19
|
|
20
20
|
== How to install
|
21
21
|
|
22
|
-
|
22
|
+
First make sure you've got Gemcutter in your sources list:
|
23
23
|
|
24
|
-
|
24
|
+
gem sources -a http://gemcutter.org
|
25
25
|
|
26
|
-
|
26
|
+
Then go ahead and install it as usual:
|
27
|
+
|
28
|
+
sudo gem install yajl-ruby
|
27
29
|
|
28
30
|
== Example of use
|
29
31
|
|
@@ -216,10 +218,10 @@ There are a lot more possibilities that I'd love to see other gems/plugins for s
|
|
216
218
|
|
217
219
|
Some ideas are:
|
218
220
|
* parsing logs in JSON format
|
219
|
-
* a Rails plugin (http://github.com/technoweenie/yajl-rails)
|
221
|
+
* a Rails plugin - DONE! (http://github.com/technoweenie/yajl-rails)
|
220
222
|
* builtin support in Rails 3?
|
221
|
-
* Rack middleware (ideally the JSON body could be handed to the parser while it's still being received)
|
222
|
-
* use with ohai (http://github.com/
|
223
|
+
* Rack middleware (ideally the JSON body could be handed to the parser while it's still being received, this is apparently possible with Unicorn)
|
224
|
+
* use with ohai - DONE! (http://github.com/opscode/ohai/commit/f89baccc3b9ab587d23e0b6257f6fedffe223c02)
|
223
225
|
* JSON API clients (http://github.com/brianmario/crack, http://github.com/brianmario/freckle-api)
|
224
226
|
* Patch Marshal#load and Marshal#dump to use JSON? ;)
|
225
227
|
* etc...
|
data/VERSION.yml
CHANGED
data/benchmark/encode.rb
CHANGED
@@ -12,9 +12,9 @@ json = File.new(filename, 'r')
|
|
12
12
|
hash = Yajl::Parser.new.parse(json)
|
13
13
|
json.close
|
14
14
|
|
15
|
-
times = ARGV[1] ? ARGV[1].to_i :
|
15
|
+
times = ARGV[1] ? ARGV[1].to_i : 1000
|
16
16
|
puts "Starting benchmark encoding #{filename} #{times} times\n\n"
|
17
|
-
Benchmark.
|
17
|
+
Benchmark.bmbm { |x|
|
18
18
|
io_encoder = Yajl::Encoder.new
|
19
19
|
x.report {
|
20
20
|
puts "Yajl::Encoder#encode (to an IO)"
|
@@ -30,7 +30,7 @@ Benchmark.bm { |x|
|
|
30
30
|
}
|
31
31
|
}
|
32
32
|
x.report {
|
33
|
-
puts "JSON
|
33
|
+
puts "JSON.generate"
|
34
34
|
times.times {
|
35
35
|
JSON.generate(hash)
|
36
36
|
}
|
@@ -5,14 +5,14 @@ require 'yajl_ext'
|
|
5
5
|
require 'stringio'
|
6
6
|
require 'json'
|
7
7
|
|
8
|
-
times = ARGV[0] ? ARGV[0].to_i :
|
8
|
+
times = ARGV[0] ? ARGV[0].to_i : 1000
|
9
9
|
filename = 'benchmark/subjects/ohai.json'
|
10
10
|
json = File.new(filename, 'r')
|
11
11
|
hash = Yajl::Parser.new.parse(json)
|
12
12
|
json.close
|
13
13
|
|
14
14
|
puts "Starting benchmark encoding #{filename} #{times} times\n\n"
|
15
|
-
Benchmark.
|
15
|
+
Benchmark.bmbm { |x|
|
16
16
|
encoder = Yajl::Encoder.new
|
17
17
|
x.report {
|
18
18
|
puts "Yajl::Encoder#encode"
|
@@ -11,9 +11,9 @@ json = File.new(filename, 'r')
|
|
11
11
|
hash = Yajl::Parser.new.parse(json)
|
12
12
|
json.close
|
13
13
|
|
14
|
-
times = ARGV[0] ? ARGV[0].to_i :
|
14
|
+
times = ARGV[0] ? ARGV[0].to_i : 1000
|
15
15
|
puts "Starting benchmark encoding #{filename} into JSON #{times} times\n\n"
|
16
|
-
Benchmark.
|
16
|
+
Benchmark.bmbm { |x|
|
17
17
|
encoder = Yajl::Encoder.new
|
18
18
|
x.report {
|
19
19
|
puts "Yajl::Encoder#encode"
|
@@ -30,14 +30,13 @@ Benchmark.bm { |x|
|
|
30
30
|
}
|
31
31
|
|
32
32
|
# YAML Section
|
33
|
-
filename = 'benchmark/subjects/
|
33
|
+
filename = 'benchmark/subjects/ohai.yml'
|
34
34
|
yml = File.new(filename, 'r')
|
35
35
|
data = YAML.load_stream(yml)
|
36
36
|
yml.close
|
37
37
|
|
38
|
-
times = ARGV[0] ? ARGV[0].to_i : 1
|
39
38
|
puts "Starting benchmark encoding #{filename} into YAML #{times} times\n\n"
|
40
|
-
Benchmark.
|
39
|
+
Benchmark.bmbm { |x|
|
41
40
|
x.report {
|
42
41
|
puts "YAML.dump"
|
43
42
|
times.times {
|
data/benchmark/http.rb
CHANGED
@@ -4,7 +4,7 @@ require 'benchmark'
|
|
4
4
|
require 'yajl/http_stream'
|
5
5
|
require 'yajl/gzip'
|
6
6
|
require 'yajl/deflate'
|
7
|
-
require 'yajl/bzip2'
|
7
|
+
require 'yajl/bzip2' unless defined?(Bzip2)
|
8
8
|
require 'json'
|
9
9
|
require 'uri'
|
10
10
|
require 'net/http'
|
@@ -14,7 +14,7 @@ uri = URI.parse('http://search.twitter.com/search.json?q=github')
|
|
14
14
|
|
15
15
|
times = ARGV[0] ? ARGV[0].to_i : 1
|
16
16
|
puts "Starting benchmark parsing #{uri.to_s} #{times} times\n\n"
|
17
|
-
Benchmark.
|
17
|
+
Benchmark.bmbm { |x|
|
18
18
|
x.report {
|
19
19
|
puts "Yajl::HttpStream.get"
|
20
20
|
times.times {
|
data/benchmark/parse.rb
CHANGED
@@ -5,17 +5,14 @@ require 'yajl_ext'
|
|
5
5
|
require 'json'
|
6
6
|
require 'activesupport'
|
7
7
|
|
8
|
-
filename = ARGV[0] || 'benchmark/subjects/
|
8
|
+
filename = ARGV[0] || 'benchmark/subjects/twitter_search.json'
|
9
9
|
json = File.new(filename, 'r')
|
10
10
|
|
11
|
-
|
12
|
-
json.read
|
13
|
-
json.rewind
|
14
|
-
|
15
|
-
times = ARGV[1] ? ARGV[1].to_i : 1
|
11
|
+
times = ARGV[1] ? ARGV[1].to_i : 1000
|
16
12
|
puts "Starting benchmark parsing #{File.size(filename)} bytes of JSON data #{times} times\n\n"
|
17
|
-
Benchmark.
|
13
|
+
Benchmark.bmbm { |x|
|
18
14
|
io_parser = Yajl::Parser.new
|
15
|
+
io_parser.on_parse_complete = lambda {|obj|} if times > 1
|
19
16
|
x.report {
|
20
17
|
puts "Yajl::Parser#parse (from an IO)"
|
21
18
|
times.times {
|
@@ -24,6 +21,7 @@ Benchmark.bm { |x|
|
|
24
21
|
}
|
25
22
|
}
|
26
23
|
string_parser = Yajl::Parser.new
|
24
|
+
string_parser.on_parse_complete = lambda {|obj|} if times > 1
|
27
25
|
x.report {
|
28
26
|
puts "Yajl::Parser#parse (from a String)"
|
29
27
|
times.times {
|
@@ -10,22 +10,18 @@ marshal_filename = 'benchmark/subjects/ohai.marshal_dump'
|
|
10
10
|
json = File.new(filename, 'r')
|
11
11
|
marshal_file = File.new(marshal_filename, 'r')
|
12
12
|
|
13
|
-
# warm up the filesystem
|
14
|
-
json.read
|
15
|
-
json.rewind
|
16
|
-
marshal_file.read
|
17
|
-
marshal_file.rewind
|
18
|
-
|
19
13
|
hash = {}
|
20
14
|
|
21
|
-
times = ARGV[0] ? ARGV[0].to_i :
|
15
|
+
times = ARGV[0] ? ARGV[0].to_i : 1000
|
22
16
|
puts "Starting benchmark parsing #{File.size(filename)} bytes of JSON data #{times} times\n\n"
|
23
|
-
Benchmark.
|
17
|
+
Benchmark.bmbm { |x|
|
24
18
|
x.report {
|
25
19
|
puts "Yajl::Parser#parse"
|
20
|
+
yajl = Yajl::Parser.new
|
21
|
+
yajl.on_parse_complete = lambda {|obj|} if times > 1
|
26
22
|
times.times {
|
27
23
|
json.rewind
|
28
|
-
hash =
|
24
|
+
hash = yajl.parse(json)
|
29
25
|
}
|
30
26
|
}
|
31
27
|
x.report {
|
@@ -9,14 +9,11 @@ require 'yaml'
|
|
9
9
|
filename = 'benchmark/subjects/ohai.json'
|
10
10
|
json = File.new(filename, 'r')
|
11
11
|
|
12
|
-
|
13
|
-
json.read
|
14
|
-
json.rewind
|
15
|
-
|
16
|
-
times = ARGV[0] ? ARGV[0].to_i : 1
|
12
|
+
times = ARGV[0] ? ARGV[0].to_i : 1000
|
17
13
|
puts "Starting benchmark parsing #{File.size(filename)} bytes of JSON data #{times} times\n\n"
|
18
|
-
Benchmark.
|
14
|
+
Benchmark.bmbm { |x|
|
19
15
|
parser = Yajl::Parser.new
|
16
|
+
parser.on_parse_complete = lambda {|obj|} if times > 1
|
20
17
|
x.report {
|
21
18
|
puts "Yajl::Parser#parse"
|
22
19
|
times.times {
|
@@ -35,16 +32,11 @@ Benchmark.bm { |x|
|
|
35
32
|
json.close
|
36
33
|
|
37
34
|
# YAML section
|
38
|
-
filename = 'benchmark/subjects/
|
35
|
+
filename = 'benchmark/subjects/ohai.yml'
|
39
36
|
yaml = File.new(filename, 'r')
|
40
37
|
|
41
|
-
# warm up the filesystem
|
42
|
-
yaml.read
|
43
|
-
yaml.rewind
|
44
|
-
|
45
|
-
times = ARGV[0] ? ARGV[0].to_i : 1
|
46
38
|
puts "Starting benchmark parsing #{File.size(filename)} bytes of YAML data #{times} times\n\n"
|
47
|
-
Benchmark.
|
39
|
+
Benchmark.bmbm { |x|
|
48
40
|
x.report {
|
49
41
|
puts "YAML.load_stream"
|
50
42
|
times.times {
|
data/benchmark/parse_stream.rb
CHANGED
@@ -3,22 +3,16 @@ require 'rubygems'
|
|
3
3
|
require 'benchmark'
|
4
4
|
require 'yajl_ext'
|
5
5
|
require 'json'
|
6
|
-
|
6
|
+
require 'activesupport'
|
7
7
|
|
8
8
|
filename = 'benchmark/subjects/twitter_stream.json'
|
9
9
|
json = File.new(filename, 'r')
|
10
10
|
|
11
|
-
|
12
|
-
json.read
|
13
|
-
json.rewind
|
14
|
-
|
15
|
-
times = ARGV[0] ? ARGV[0].to_i : 1
|
11
|
+
times = ARGV[0] ? ARGV[0].to_i : 100
|
16
12
|
puts "Starting benchmark parsing JSON stream (#{File.size(filename)} bytes of JSON data with 430 JSON separate strings) #{times} times\n\n"
|
17
|
-
Benchmark.
|
13
|
+
Benchmark.bmbm { |x|
|
18
14
|
parser = Yajl::Parser.new
|
19
|
-
parser.on_parse_complete = lambda {
|
20
|
-
# no-op
|
21
|
-
}
|
15
|
+
parser.on_parse_complete = lambda {|obj|}
|
22
16
|
x.report {
|
23
17
|
puts "Yajl::Parser#parse"
|
24
18
|
times.times {
|
@@ -35,14 +29,14 @@ Benchmark.bm { |x|
|
|
35
29
|
end
|
36
30
|
}
|
37
31
|
}
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
32
|
+
x.report {
|
33
|
+
puts "ActiveSupport::JSON.decode"
|
34
|
+
times.times {
|
35
|
+
json.rewind
|
36
|
+
while chunk = json.gets
|
37
|
+
ActiveSupport::JSON.decode(chunk)
|
38
|
+
end
|
39
|
+
}
|
40
|
+
}
|
47
41
|
}
|
48
42
|
json.close
|
data/ext/api/yajl_gen.h
CHANGED
@@ -57,7 +57,10 @@ extern "C" {
|
|
57
57
|
* state */
|
58
58
|
yajl_gen_in_error_state,
|
59
59
|
/** A complete JSON document has been generated */
|
60
|
-
yajl_gen_generation_complete
|
60
|
+
yajl_gen_generation_complete,
|
61
|
+
/** yajl_gen_double was passed an invalid floating point value
|
62
|
+
* (infinity or NaN). */
|
63
|
+
yajl_gen_invalid_number
|
61
64
|
} yajl_gen_status;
|
62
65
|
|
63
66
|
/** an opaque handle to a generator */
|
@@ -90,6 +93,9 @@ extern "C" {
|
|
90
93
|
void YAJL_API yajl_gen_free(yajl_gen handle);
|
91
94
|
|
92
95
|
yajl_gen_status YAJL_API yajl_gen_integer(yajl_gen hand, long int number);
|
96
|
+
/** generate a floating point number. number may not be infinity or
|
97
|
+
* NaN, as these have no representation in JSON. In these cases the
|
98
|
+
* generator will return 'yajl_gen_invalid_number' */
|
93
99
|
yajl_gen_status YAJL_API yajl_gen_double(yajl_gen hand, double number);
|
94
100
|
yajl_gen_status YAJL_API yajl_gen_number(yajl_gen hand,
|
95
101
|
const char * num,
|
data/ext/yajl_ext.c
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
#include "yajl_ext.h"
|
2
2
|
|
3
|
-
|
3
|
+
/* Helpers for building objects */
|
4
4
|
inline void yajl_check_and_fire_callback(void * ctx) {
|
5
5
|
struct yajl_parser_wrapper * wrapper;
|
6
6
|
GetParser((VALUE)ctx, wrapper);
|
7
7
|
|
8
|
-
|
8
|
+
/* No need to do any of this if the callback isn't even setup */
|
9
9
|
if (wrapper->parse_complete_callback != Qnil) {
|
10
10
|
int len = RARRAY_LEN(wrapper->builderStack);
|
11
11
|
if (len == 1 && wrapper->nestedArrayLevel == 0 && wrapper->nestedHashLevel == 0) {
|
@@ -98,15 +98,15 @@ void yajl_encode_part(void * wrapper, VALUE obj, VALUE io) {
|
|
98
98
|
case T_HASH:
|
99
99
|
status = yajl_gen_map_open(w->encoder);
|
100
100
|
|
101
|
-
|
101
|
+
/* TODO: itterate through keys in the hash */
|
102
102
|
VALUE keys = rb_funcall(obj, intern_keys, 0);
|
103
103
|
VALUE entry, keyStr;
|
104
104
|
for(idx=0; idx<RARRAY_LEN(keys); idx++) {
|
105
105
|
entry = rb_ary_entry(keys, idx);
|
106
|
-
keyStr = rb_funcall(entry, intern_to_s, 0);
|
107
|
-
|
106
|
+
keyStr = rb_funcall(entry, intern_to_s, 0); /* key must be a string */
|
107
|
+
/* the key */
|
108
108
|
yajl_encode_part(w, keyStr, io);
|
109
|
-
|
109
|
+
/* the value */
|
110
110
|
yajl_encode_part(w, rb_hash_aref(obj, entry), io);
|
111
111
|
}
|
112
112
|
|
@@ -133,6 +133,9 @@ void yajl_encode_part(void * wrapper, VALUE obj, VALUE io) {
|
|
133
133
|
case T_FLOAT:
|
134
134
|
case T_BIGNUM:
|
135
135
|
str = rb_funcall(obj, intern_to_s, 0);
|
136
|
+
if (strcmp(RSTRING_PTR(str), "NaN") == 0 || strcmp(RSTRING_PTR(str), "Infinity") == 0 || strcmp(RSTRING_PTR(str), "-Infinity") == 0) {
|
137
|
+
rb_raise(cEncodeError, "'%s' is an invalid number", RSTRING_PTR(str));
|
138
|
+
}
|
136
139
|
status = yajl_gen_number(w->encoder, RSTRING_PTR(str), (unsigned int)RSTRING_LEN(str));
|
137
140
|
break;
|
138
141
|
case T_STRING:
|
@@ -141,7 +144,7 @@ void yajl_encode_part(void * wrapper, VALUE obj, VALUE io) {
|
|
141
144
|
default:
|
142
145
|
if (rb_respond_to(obj, intern_to_json)) {
|
143
146
|
str = rb_funcall(obj, intern_to_json, 0);
|
144
|
-
quote_strings = 0;
|
147
|
+
quote_strings = 0; /* this lets us append on to the buffer without Yajl quoting it again */
|
145
148
|
} else {
|
146
149
|
str = rb_funcall(obj, intern_to_s, 0);
|
147
150
|
}
|
@@ -174,7 +177,7 @@ void yajl_parse_chunk(const unsigned char * chunk, unsigned int len, yajl_handle
|
|
174
177
|
}
|
175
178
|
}
|
176
179
|
|
177
|
-
|
180
|
+
/* YAJL Callbacks */
|
178
181
|
static int yajl_found_null(void * ctx) {
|
179
182
|
yajl_set_static_value(ctx, Qnil);
|
180
183
|
yajl_check_and_fire_callback(ctx);
|
@@ -188,15 +191,19 @@ static int yajl_found_boolean(void * ctx, int boolean) {
|
|
188
191
|
}
|
189
192
|
|
190
193
|
static int yajl_found_number(void * ctx, const char * numberVal, unsigned int numberLen) {
|
191
|
-
|
192
|
-
|
194
|
+
char * cSubString = ALLOC_N(char, numberLen+1);
|
195
|
+
if (cSubString) {
|
196
|
+
memcpy(cSubString, numberVal, numberLen);
|
197
|
+
}
|
198
|
+
cSubString[numberLen] = '\0';
|
193
199
|
|
194
|
-
if (
|
195
|
-
|
200
|
+
if (strchr(cSubString, '.') != NULL || strchr(cSubString, 'e') != NULL || strchr(cSubString, 'E') != NULL) {
|
201
|
+
yajl_set_static_value(ctx, rb_float_new(atof(cSubString)));
|
196
202
|
} else {
|
197
|
-
yajl_set_static_value(ctx,
|
203
|
+
yajl_set_static_value(ctx, INT2FIX(atoi(cSubString)));
|
198
204
|
}
|
199
205
|
yajl_check_and_fire_callback(ctx);
|
206
|
+
free(cSubString);
|
200
207
|
return 1;
|
201
208
|
}
|
202
209
|
|
@@ -210,10 +217,9 @@ static int yajl_found_hash_key(void * ctx, const unsigned char * stringVal, unsi
|
|
210
217
|
struct yajl_parser_wrapper * wrapper;
|
211
218
|
GetParser((VALUE)ctx, wrapper);
|
212
219
|
VALUE keyStr = rb_str_new((const char *)stringVal, stringLen);
|
213
|
-
|
220
|
+
|
214
221
|
if (wrapper->symbolizeKeys) {
|
215
|
-
|
216
|
-
yajl_set_static_value(ctx, ID2SYM(key));
|
222
|
+
yajl_set_static_value(ctx, rb_funcall(keyStr, intern_to_sym, 0));
|
217
223
|
} else {
|
218
224
|
yajl_set_static_value(ctx, keyStr);
|
219
225
|
}
|
@@ -260,7 +266,7 @@ static int yajl_found_end_array(void * ctx) {
|
|
260
266
|
}
|
261
267
|
|
262
268
|
|
263
|
-
|
269
|
+
/* Ruby Interface */
|
264
270
|
|
265
271
|
/*
|
266
272
|
* Document-class: Yajl::Parser
|
@@ -287,17 +293,17 @@ static VALUE rb_yajl_parser_new(int argc, VALUE * argv, VALUE klass) {
|
|
287
293
|
VALUE opts, obj;
|
288
294
|
int allowComments = 1, checkUTF8 = 1, symbolizeKeys = 0;
|
289
295
|
|
290
|
-
|
296
|
+
/* Scan off config vars */
|
291
297
|
if (rb_scan_args(argc, argv, "01", &opts) == 1) {
|
292
298
|
Check_Type(opts, T_HASH);
|
293
299
|
|
294
|
-
if (rb_hash_aref(opts,
|
300
|
+
if (rb_hash_aref(opts, sym_allow_comments) == Qfalse) {
|
295
301
|
allowComments = 0;
|
296
302
|
}
|
297
|
-
if (rb_hash_aref(opts,
|
303
|
+
if (rb_hash_aref(opts, sym_check_utf8) == Qfalse) {
|
298
304
|
checkUTF8 = 0;
|
299
305
|
}
|
300
|
-
if (rb_hash_aref(opts,
|
306
|
+
if (rb_hash_aref(opts, sym_symbolize_keys) == Qtrue) {
|
301
307
|
symbolizeKeys = 1;
|
302
308
|
}
|
303
309
|
}
|
@@ -354,12 +360,11 @@ static VALUE rb_yajl_parser_init(int argc, VALUE * argv, VALUE self) {
|
|
354
360
|
static VALUE rb_yajl_parser_parse(int argc, VALUE * argv, VALUE self) {
|
355
361
|
yajl_status stat;
|
356
362
|
struct yajl_parser_wrapper * wrapper;
|
357
|
-
VALUE
|
363
|
+
VALUE rbufsize, input, blk;
|
358
364
|
|
359
365
|
GetParser(self, wrapper);
|
360
|
-
parsed = rb_str_new2("");
|
361
366
|
|
362
|
-
|
367
|
+
/* setup our parameters */
|
363
368
|
rb_scan_args(argc, argv, "11&", &input, &rbufsize, &blk);
|
364
369
|
if (NIL_P(rbufsize)) {
|
365
370
|
rbufsize = INT2FIX(READ_BUFSIZE);
|
@@ -373,6 +378,7 @@ static VALUE rb_yajl_parser_parse(int argc, VALUE * argv, VALUE self) {
|
|
373
378
|
if (TYPE(input) == T_STRING) {
|
374
379
|
yajl_parse_chunk((const unsigned char *)RSTRING_PTR(input), RSTRING_LEN(input), wrapper->parser);
|
375
380
|
} else if (rb_respond_to(input, intern_eof)) {
|
381
|
+
VALUE parsed = rb_str_new2("");
|
376
382
|
while (rb_funcall(input, intern_eof, 0) != Qtrue) {
|
377
383
|
rb_funcall(input, intern_io_read, 2, rbufsize, parsed);
|
378
384
|
yajl_parse_chunk((const unsigned char *)RSTRING_PTR(parsed), RSTRING_LEN(parsed), wrapper->parser);
|
@@ -381,7 +387,7 @@ static VALUE rb_yajl_parser_parse(int argc, VALUE * argv, VALUE self) {
|
|
381
387
|
rb_raise(cParseError, "input must be a string or IO");
|
382
388
|
}
|
383
389
|
|
384
|
-
|
390
|
+
/* parse any remaining buffered data */
|
385
391
|
stat = yajl_parse_complete(wrapper->parser);
|
386
392
|
|
387
393
|
if (wrapper->parse_complete_callback != Qnil) {
|
@@ -467,13 +473,13 @@ static VALUE rb_yajl_encoder_new(int argc, VALUE * argv, VALUE klass) {
|
|
467
473
|
const char * indentString = " ";
|
468
474
|
int beautify = 0;
|
469
475
|
|
470
|
-
|
476
|
+
/* Scan off config vars */
|
471
477
|
if (rb_scan_args(argc, argv, "01", &opts) == 1) {
|
472
478
|
Check_Type(opts, T_HASH);
|
473
479
|
|
474
|
-
if (rb_hash_aref(opts,
|
480
|
+
if (rb_hash_aref(opts, sym_pretty) == Qtrue) {
|
475
481
|
beautify = 1;
|
476
|
-
indent = rb_hash_aref(opts,
|
482
|
+
indent = rb_hash_aref(opts, sym_indent);
|
477
483
|
if (indent != Qnil) {
|
478
484
|
Check_Type(indent, T_STRING);
|
479
485
|
indentString = RSTRING_PTR(indent);
|
@@ -485,8 +491,8 @@ static VALUE rb_yajl_encoder_new(int argc, VALUE * argv, VALUE klass) {
|
|
485
491
|
obj = Data_Make_Struct(klass, struct yajl_encoder_wrapper, yajl_encoder_wrapper_mark, yajl_encoder_wrapper_free, wrapper);
|
486
492
|
wrapper->encoder = yajl_gen_alloc(&cfg, NULL);
|
487
493
|
wrapper->on_progress_callback = Qnil;
|
488
|
-
if (opts != Qnil && rb_funcall(opts, intern_has_key, 1,
|
489
|
-
wrapper->terminator = rb_hash_aref(opts,
|
494
|
+
if (opts != Qnil && rb_funcall(opts, intern_has_key, 1, sym_terminator) == Qtrue) {
|
495
|
+
wrapper->terminator = rb_hash_aref(opts, sym_terminator);
|
490
496
|
} else {
|
491
497
|
wrapper->terminator = 0;
|
492
498
|
}
|
@@ -543,10 +549,10 @@ static VALUE rb_yajl_encoder_encode(int argc, VALUE * argv, VALUE self) {
|
|
543
549
|
wrapper->on_progress_callback = blk;
|
544
550
|
}
|
545
551
|
|
546
|
-
|
552
|
+
/* begin encode process */
|
547
553
|
yajl_encode_part(wrapper, obj, io);
|
548
554
|
|
549
|
-
|
555
|
+
/* just make sure we output the remaining buffer */
|
550
556
|
yajl_gen_get_buf(wrapper->encoder, &buffer, &len);
|
551
557
|
outBuff = rb_str_new((const char *)buffer, len);
|
552
558
|
yajl_gen_clear(wrapper->encoder);
|
@@ -590,7 +596,7 @@ static VALUE rb_yajl_encoder_set_progress_cb(VALUE self, VALUE callback) {
|
|
590
596
|
}
|
591
597
|
|
592
598
|
|
593
|
-
|
599
|
+
/* JSON Gem compatibility */
|
594
600
|
|
595
601
|
/*
|
596
602
|
* Document-class: Hash
|
@@ -783,7 +789,7 @@ static VALUE rb_yajl_encoder_enable_json_gem_ext(VALUE klass) {
|
|
783
789
|
}
|
784
790
|
|
785
791
|
|
786
|
-
|
792
|
+
/* Ruby Extension initializer */
|
787
793
|
void Init_yajl_ext() {
|
788
794
|
mYajl = rb_define_module("Yajl");
|
789
795
|
|
@@ -812,12 +818,13 @@ void Init_yajl_ext() {
|
|
812
818
|
intern_keys = rb_intern("keys");
|
813
819
|
intern_to_s = rb_intern("to_s");
|
814
820
|
intern_to_json = rb_intern("to_json");
|
815
|
-
|
816
|
-
sym_allow_comments = rb_intern("allow_comments");
|
817
|
-
sym_check_utf8 = rb_intern("check_utf8");
|
818
|
-
sym_pretty = rb_intern("pretty");
|
819
|
-
sym_indent = rb_intern("indent");
|
820
|
-
sym_terminator = rb_intern("terminator");
|
821
|
-
sym_symbolize_keys = rb_intern("symbolize_keys");
|
821
|
+
intern_to_sym = rb_intern("to_sym");
|
822
822
|
intern_has_key = rb_intern("has_key?");
|
823
|
+
|
824
|
+
sym_allow_comments = ID2SYM(rb_intern("allow_comments"));
|
825
|
+
sym_check_utf8 = ID2SYM(rb_intern("check_utf8"));
|
826
|
+
sym_pretty = ID2SYM(rb_intern("pretty"));
|
827
|
+
sym_indent = ID2SYM(rb_intern("indent"));
|
828
|
+
sym_terminator = ID2SYM(rb_intern("terminator"));
|
829
|
+
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
|
823
830
|
}
|