yajl-ruby 0.6.5 → 0.6.6
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/.gitignore +1 -0
- data/CHANGELOG.md +4 -0
- data/VERSION.yml +1 -1
- data/benchmark/encode.rb +22 -12
- data/benchmark/encode_json_and_marshal.rb +11 -6
- data/benchmark/encode_json_and_yaml.rb +11 -6
- data/benchmark/parse.rb +24 -14
- data/benchmark/parse_json_and_marshal.rb +12 -7
- data/benchmark/parse_json_and_yaml.rb +12 -7
- data/benchmark/parse_stream.rb +28 -18
- data/ext/yajl_ext.c +88 -55
- data/ext/yajl_ext.h +32 -9
- data/lib/yajl/http_stream.rb +52 -3
- data/spec/http/fixtures/http.chunked.dump +11 -0
- data/spec/http/fixtures/http.html.dump +1220 -0
- data/spec/http/http_delete_spec.rb +6 -0
- data/spec/http/http_get_spec.rb +15 -0
- data/spec/http/http_post_spec.rb +31 -1
- data/spec/http/http_put_spec.rb +12 -0
- data/spec/rcov.opts +0 -1
- data/yajl-ruby.gemspec +4 -2
- metadata +4 -2
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.6.6 (December 1st, 2009)
|
4
|
+
* Brought over some optimizations from Macruby's use of some yajl-ruby codez
|
5
|
+
* Yajl::HttpStream now supports being killed for long-running requests, thanks to Filipe Giusti <filipegiusti@gmail.com>
|
6
|
+
|
3
7
|
## 0.6.5 (November 13th, 2009)
|
4
8
|
* optimize symbol creation while symbolize_keys is turned on
|
5
9
|
* fix for 32bit integer conversion into ruby
|
data/VERSION.yml
CHANGED
data/benchmark/encode.rb
CHANGED
@@ -3,9 +3,15 @@ require 'rubygems'
|
|
3
3
|
require 'benchmark'
|
4
4
|
require 'yajl_ext'
|
5
5
|
require 'stringio'
|
6
|
-
|
6
|
+
begin
|
7
|
+
require 'json'
|
8
|
+
rescue LoadError
|
9
|
+
end
|
7
10
|
# Can't use ActiveSuport::JSON.encode with the JSON gem loaded
|
8
|
-
#
|
11
|
+
# begin
|
12
|
+
# require 'activesupport'
|
13
|
+
# rescue LoadError
|
14
|
+
# end
|
9
15
|
|
10
16
|
filename = ARGV[0] || 'benchmark/subjects/ohai.json'
|
11
17
|
json = File.new(filename, 'r')
|
@@ -29,18 +35,22 @@ Benchmark.bmbm { |x|
|
|
29
35
|
output = string_encoder.encode(hash)
|
30
36
|
}
|
31
37
|
}
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
38
|
+
if defined?(JSON)
|
39
|
+
x.report {
|
40
|
+
puts "JSON.generate"
|
41
|
+
times.times {
|
42
|
+
JSON.generate(hash)
|
43
|
+
}
|
36
44
|
}
|
37
|
-
|
45
|
+
end
|
38
46
|
# Can't use ActiveSuport::JSON.encode with the JSON gem loaded
|
39
47
|
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
48
|
+
# if defined?(ActiveSupport::JSON)
|
49
|
+
# x.report {
|
50
|
+
# puts "ActiveSupport::JSON.encode"
|
51
|
+
# times.times {
|
52
|
+
# ActiveSupport::JSON.encode(hash)
|
53
|
+
# }
|
44
54
|
# }
|
45
|
-
#
|
55
|
+
# end
|
46
56
|
}
|
@@ -3,7 +3,10 @@ require 'rubygems'
|
|
3
3
|
require 'benchmark'
|
4
4
|
require 'yajl_ext'
|
5
5
|
require 'stringio'
|
6
|
-
|
6
|
+
begin
|
7
|
+
require 'json'
|
8
|
+
rescue LoadError
|
9
|
+
end
|
7
10
|
|
8
11
|
times = ARGV[0] ? ARGV[0].to_i : 1000
|
9
12
|
filename = 'benchmark/subjects/ohai.json'
|
@@ -20,12 +23,14 @@ Benchmark.bmbm { |x|
|
|
20
23
|
encoder.encode(hash, StringIO.new)
|
21
24
|
}
|
22
25
|
}
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
if defined?(JSON)
|
27
|
+
x.report {
|
28
|
+
puts "JSON's #to_json"
|
29
|
+
times.times {
|
30
|
+
JSON.generate(hash)
|
31
|
+
}
|
27
32
|
}
|
28
|
-
|
33
|
+
end
|
29
34
|
x.report {
|
30
35
|
puts "Marshal.dump"
|
31
36
|
times.times {
|
@@ -2,7 +2,10 @@
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'benchmark'
|
4
4
|
require 'yajl_ext'
|
5
|
-
|
5
|
+
begin
|
6
|
+
require 'json'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
6
9
|
require 'yaml'
|
7
10
|
|
8
11
|
# JSON Section
|
@@ -21,12 +24,14 @@ Benchmark.bmbm { |x|
|
|
21
24
|
encoder.encode(hash, StringIO.new)
|
22
25
|
}
|
23
26
|
}
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
if defined?(JSON)
|
28
|
+
x.report {
|
29
|
+
puts "JSON's #to_json"
|
30
|
+
times.times {
|
31
|
+
JSON.generate(hash)
|
32
|
+
}
|
28
33
|
}
|
29
|
-
|
34
|
+
end
|
30
35
|
}
|
31
36
|
|
32
37
|
# YAML Section
|
data/benchmark/parse.rb
CHANGED
@@ -2,8 +2,14 @@
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'benchmark'
|
4
4
|
require 'yajl_ext'
|
5
|
-
|
6
|
-
require '
|
5
|
+
begin
|
6
|
+
require 'json'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
begin
|
10
|
+
require 'activesupport'
|
11
|
+
rescue LoadError
|
12
|
+
end
|
7
13
|
|
8
14
|
filename = ARGV[0] || 'benchmark/subjects/twitter_search.json'
|
9
15
|
json = File.new(filename, 'r')
|
@@ -29,19 +35,23 @@ Benchmark.bmbm { |x|
|
|
29
35
|
string_parser.parse(json.read)
|
30
36
|
}
|
31
37
|
}
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
38
|
+
if defined?(JSON)
|
39
|
+
x.report {
|
40
|
+
puts "JSON.parse"
|
41
|
+
times.times {
|
42
|
+
json.rewind
|
43
|
+
JSON.parse(json.read, :max_nesting => false)
|
44
|
+
}
|
37
45
|
}
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
end
|
47
|
+
if defined?(ActiveSupport::JSON)
|
48
|
+
x.report {
|
49
|
+
puts "ActiveSupport::JSON.decode"
|
50
|
+
times.times {
|
51
|
+
json.rewind
|
52
|
+
ActiveSupport::JSON.decode(json.read)
|
53
|
+
}
|
44
54
|
}
|
45
|
-
|
55
|
+
end
|
46
56
|
}
|
47
57
|
json.close
|
@@ -2,7 +2,10 @@
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'benchmark'
|
4
4
|
require 'yajl_ext'
|
5
|
-
|
5
|
+
begin
|
6
|
+
require 'json'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
6
9
|
|
7
10
|
# JSON section
|
8
11
|
filename = 'benchmark/subjects/ohai.json'
|
@@ -24,13 +27,15 @@ Benchmark.bmbm { |x|
|
|
24
27
|
hash = yajl.parse(json)
|
25
28
|
}
|
26
29
|
}
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
if defined?(JSON)
|
31
|
+
x.report {
|
32
|
+
puts "JSON.parse"
|
33
|
+
times.times {
|
34
|
+
json.rewind
|
35
|
+
JSON.parse(json.read, :max_nesting => false)
|
36
|
+
}
|
32
37
|
}
|
33
|
-
|
38
|
+
end
|
34
39
|
x.report {
|
35
40
|
puts "Marshal.load"
|
36
41
|
times.times {
|
@@ -2,7 +2,10 @@
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'benchmark'
|
4
4
|
require 'yajl_ext'
|
5
|
-
|
5
|
+
begin
|
6
|
+
require 'json'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
6
9
|
require 'yaml'
|
7
10
|
|
8
11
|
# JSON section
|
@@ -21,13 +24,15 @@ Benchmark.bmbm { |x|
|
|
21
24
|
parser.parse(json)
|
22
25
|
}
|
23
26
|
}
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
if defined?(JSON)
|
28
|
+
x.report {
|
29
|
+
puts "JSON.parse"
|
30
|
+
times.times {
|
31
|
+
json.rewind
|
32
|
+
JSON.parse(json.read, :max_nesting => false)
|
33
|
+
}
|
29
34
|
}
|
30
|
-
|
35
|
+
end
|
31
36
|
}
|
32
37
|
json.close
|
33
38
|
|
data/benchmark/parse_stream.rb
CHANGED
@@ -2,8 +2,14 @@
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'benchmark'
|
4
4
|
require 'yajl_ext'
|
5
|
-
|
6
|
-
require '
|
5
|
+
begin
|
6
|
+
require 'json'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
begin
|
10
|
+
require 'activesupport'
|
11
|
+
rescue LoadError
|
12
|
+
end
|
7
13
|
|
8
14
|
filename = 'benchmark/subjects/twitter_stream.json'
|
9
15
|
json = File.new(filename, 'r')
|
@@ -20,23 +26,27 @@ Benchmark.bmbm { |x|
|
|
20
26
|
parser.parse(json)
|
21
27
|
}
|
22
28
|
}
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
if defined?(JSON)
|
30
|
+
x.report {
|
31
|
+
puts "JSON.parse"
|
32
|
+
times.times {
|
33
|
+
json.rewind
|
34
|
+
while chunk = json.gets
|
35
|
+
JSON.parse(chunk, :max_nesting => false)
|
36
|
+
end
|
37
|
+
}
|
30
38
|
}
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
+
end
|
40
|
+
if defined?(ActiveSupport::JSON)
|
41
|
+
x.report {
|
42
|
+
puts "ActiveSupport::JSON.decode"
|
43
|
+
times.times {
|
44
|
+
json.rewind
|
45
|
+
while chunk = json.gets
|
46
|
+
ActiveSupport::JSON.decode(chunk)
|
47
|
+
end
|
48
|
+
}
|
39
49
|
}
|
40
|
-
|
50
|
+
end
|
41
51
|
}
|
42
52
|
json.close
|
data/ext/yajl_ext.c
CHANGED
@@ -1,8 +1,31 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2008-2009 Brian Lopez - http://github.com/brianmario
|
3
|
+
*
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
* a copy of this software and associated documentation files (the
|
6
|
+
* "Software"), to deal in the Software without restriction, including
|
7
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
* the following conditions:
|
11
|
+
*
|
12
|
+
* The above copyright notice and this permission notice shall be
|
13
|
+
* included in all copies or substantial portions of the Software.
|
14
|
+
*
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
*/
|
23
|
+
|
1
24
|
#include "yajl_ext.h"
|
2
25
|
|
3
26
|
/* Helpers for building objects */
|
4
27
|
inline void yajl_check_and_fire_callback(void * ctx) {
|
5
|
-
|
28
|
+
yajl_parser_wrapper * wrapper;
|
6
29
|
GetParser((VALUE)ctx, wrapper);
|
7
30
|
|
8
31
|
/* No need to do any of this if the callback isn't even setup */
|
@@ -23,7 +46,7 @@ inline void yajl_check_and_fire_callback(void * ctx) {
|
|
23
46
|
}
|
24
47
|
|
25
48
|
inline void yajl_set_static_value(void * ctx, VALUE val) {
|
26
|
-
|
49
|
+
yajl_parser_wrapper * wrapper;
|
27
50
|
VALUE lastEntry, hash;
|
28
51
|
int len;
|
29
52
|
|
@@ -61,23 +84,28 @@ inline void yajl_set_static_value(void * ctx, VALUE val) {
|
|
61
84
|
}
|
62
85
|
|
63
86
|
static void yajl_encoder_wrapper_free(void * wrapper) {
|
64
|
-
|
65
|
-
|
66
|
-
|
87
|
+
yajl_encoder_wrapper * w = wrapper;
|
88
|
+
if (w) {
|
89
|
+
yajl_gen_free(w->encoder);
|
90
|
+
free(w);
|
91
|
+
}
|
67
92
|
}
|
68
93
|
|
69
94
|
static void yajl_encoder_wrapper_mark(void * wrapper) {
|
70
|
-
|
71
|
-
|
72
|
-
|
95
|
+
yajl_encoder_wrapper * w = wrapper;
|
96
|
+
if (w) {
|
97
|
+
rb_gc_mark(w->on_progress_callback);
|
98
|
+
rb_gc_mark(w->terminator);
|
99
|
+
}
|
73
100
|
}
|
74
101
|
|
75
102
|
void yajl_encode_part(void * wrapper, VALUE obj, VALUE io) {
|
76
103
|
VALUE str, outBuff, otherObj;
|
77
|
-
|
104
|
+
yajl_encoder_wrapper * w = wrapper;
|
78
105
|
yajl_gen_status status;
|
79
106
|
int idx = 0;
|
80
107
|
const unsigned char * buffer;
|
108
|
+
const char * cptr;
|
81
109
|
unsigned int len;
|
82
110
|
int quote_strings = 1;
|
83
111
|
|
@@ -133,13 +161,15 @@ void yajl_encode_part(void * wrapper, VALUE obj, VALUE io) {
|
|
133
161
|
case T_FLOAT:
|
134
162
|
case T_BIGNUM:
|
135
163
|
str = rb_funcall(obj, intern_to_s, 0);
|
136
|
-
|
137
|
-
|
164
|
+
cptr = RSTRING_PTR(str);
|
165
|
+
if (strcmp(cptr, "NaN") == 0 || strcmp(cptr, "Infinity") == 0 || strcmp(cptr, "-Infinity") == 0) {
|
166
|
+
rb_raise(cEncodeError, "'%s' is an invalid number", cptr);
|
138
167
|
}
|
139
|
-
status = yajl_gen_number(w->encoder,
|
168
|
+
status = yajl_gen_number(w->encoder, cptr, (unsigned int)strlen(cptr));
|
140
169
|
break;
|
141
170
|
case T_STRING:
|
142
|
-
|
171
|
+
cptr = RSTRING_PTR(obj);
|
172
|
+
status = yajl_gen_string(w->encoder, (const unsigned char *)cptr, (unsigned int)strlen(cptr), 1);
|
143
173
|
break;
|
144
174
|
default:
|
145
175
|
if (rb_respond_to(obj, intern_to_json)) {
|
@@ -148,21 +178,26 @@ void yajl_encode_part(void * wrapper, VALUE obj, VALUE io) {
|
|
148
178
|
} else {
|
149
179
|
str = rb_funcall(obj, intern_to_s, 0);
|
150
180
|
}
|
151
|
-
|
181
|
+
cptr = RSTRING_PTR(str);
|
182
|
+
status = yajl_gen_string(w->encoder, (const unsigned char *)cptr, (unsigned int)strlen(cptr), quote_strings);
|
152
183
|
break;
|
153
184
|
}
|
154
185
|
}
|
155
186
|
|
156
187
|
void yajl_parser_wrapper_free(void * wrapper) {
|
157
|
-
|
158
|
-
|
159
|
-
|
188
|
+
yajl_parser_wrapper * w = wrapper;
|
189
|
+
if (w) {
|
190
|
+
yajl_free(w->parser);
|
191
|
+
free(w);
|
192
|
+
}
|
160
193
|
}
|
161
194
|
|
162
195
|
void yajl_parser_wrapper_mark(void * wrapper) {
|
163
|
-
|
164
|
-
|
165
|
-
|
196
|
+
yajl_parser_wrapper * w = wrapper;
|
197
|
+
if (w) {
|
198
|
+
rb_gc_mark(w->builderStack);
|
199
|
+
rb_gc_mark(w->parse_complete_callback);
|
200
|
+
}
|
166
201
|
}
|
167
202
|
|
168
203
|
void yajl_parse_chunk(const unsigned char * chunk, unsigned int len, yajl_handle parser) {
|
@@ -191,19 +226,16 @@ static int yajl_found_boolean(void * ctx, int boolean) {
|
|
191
226
|
}
|
192
227
|
|
193
228
|
static int yajl_found_number(void * ctx, const char * numberVal, unsigned int numberLen) {
|
194
|
-
char
|
195
|
-
|
196
|
-
|
229
|
+
char buf[numberLen+1];
|
230
|
+
memcpy(buf, numberVal, numberLen);
|
231
|
+
buf[numberLen] = 0;
|
232
|
+
|
233
|
+
if (strchr(buf, '.') || strchr(buf, 'e') || strchr(buf, 'E')) {
|
234
|
+
yajl_set_static_value(ctx, rb_float_new(strtod(buf, NULL)));
|
197
235
|
}
|
198
|
-
|
199
|
-
|
200
|
-
if (strchr(cSubString, '.') != NULL || strchr(cSubString, 'e') != NULL || strchr(cSubString, 'E') != NULL) {
|
201
|
-
yajl_set_static_value(ctx, rb_float_new(rb_cstr_to_dbl(cSubString, 10)));
|
202
|
-
} else {
|
203
|
-
yajl_set_static_value(ctx, rb_cstr2inum(cSubString, 10));
|
236
|
+
else {
|
237
|
+
yajl_set_static_value(ctx, rb_cstr2inum(buf, 10));
|
204
238
|
}
|
205
|
-
yajl_check_and_fire_callback(ctx);
|
206
|
-
free(cSubString);
|
207
239
|
return 1;
|
208
240
|
}
|
209
241
|
|
@@ -214,18 +246,15 @@ static int yajl_found_string(void * ctx, const unsigned char * stringVal, unsign
|
|
214
246
|
}
|
215
247
|
|
216
248
|
static int yajl_found_hash_key(void * ctx, const unsigned char * stringVal, unsigned int stringLen) {
|
217
|
-
|
249
|
+
yajl_parser_wrapper * wrapper;
|
218
250
|
GetParser((VALUE)ctx, wrapper);
|
219
251
|
VALUE keyStr;
|
220
252
|
|
221
253
|
if (wrapper->symbolizeKeys) {
|
222
|
-
char
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
cSubString[stringLen] = '\0';
|
227
|
-
yajl_set_static_value(ctx, ID2SYM(rb_intern(cSubString)));
|
228
|
-
free(cSubString);
|
254
|
+
char buf[stringLen+1];
|
255
|
+
memcpy(buf, stringVal, stringLen);
|
256
|
+
buf[stringLen] = 0;
|
257
|
+
yajl_set_static_value(ctx, ID2SYM(rb_intern(buf)));
|
229
258
|
} else {
|
230
259
|
keyStr = rb_str_new((const char *)stringVal, stringLen);
|
231
260
|
yajl_set_static_value(ctx, keyStr);
|
@@ -235,7 +264,7 @@ static int yajl_found_hash_key(void * ctx, const unsigned char * stringVal, unsi
|
|
235
264
|
}
|
236
265
|
|
237
266
|
static int yajl_found_start_hash(void * ctx) {
|
238
|
-
|
267
|
+
yajl_parser_wrapper * wrapper;
|
239
268
|
GetParser((VALUE)ctx, wrapper);
|
240
269
|
wrapper->nestedHashLevel++;
|
241
270
|
yajl_set_static_value(ctx, rb_hash_new());
|
@@ -243,7 +272,7 @@ static int yajl_found_start_hash(void * ctx) {
|
|
243
272
|
}
|
244
273
|
|
245
274
|
static int yajl_found_end_hash(void * ctx) {
|
246
|
-
|
275
|
+
yajl_parser_wrapper * wrapper;
|
247
276
|
GetParser((VALUE)ctx, wrapper);
|
248
277
|
wrapper->nestedHashLevel--;
|
249
278
|
if (RARRAY_LEN(wrapper->builderStack) > 1) {
|
@@ -254,7 +283,7 @@ static int yajl_found_end_hash(void * ctx) {
|
|
254
283
|
}
|
255
284
|
|
256
285
|
static int yajl_found_start_array(void * ctx) {
|
257
|
-
|
286
|
+
yajl_parser_wrapper * wrapper;
|
258
287
|
GetParser((VALUE)ctx, wrapper);
|
259
288
|
wrapper->nestedArrayLevel++;
|
260
289
|
yajl_set_static_value(ctx, rb_ary_new());
|
@@ -262,7 +291,7 @@ static int yajl_found_start_array(void * ctx) {
|
|
262
291
|
}
|
263
292
|
|
264
293
|
static int yajl_found_end_array(void * ctx) {
|
265
|
-
|
294
|
+
yajl_parser_wrapper * wrapper;
|
266
295
|
GetParser((VALUE)ctx, wrapper);
|
267
296
|
wrapper->nestedArrayLevel--;
|
268
297
|
if (RARRAY_LEN(wrapper->builderStack) > 1) {
|
@@ -295,7 +324,7 @@ static int yajl_found_end_array(void * ctx) {
|
|
295
324
|
* :check_utf8 will validate UTF8 characters found in the JSON stream, defaults to true.
|
296
325
|
*/
|
297
326
|
static VALUE rb_yajl_parser_new(int argc, VALUE * argv, VALUE klass) {
|
298
|
-
|
327
|
+
yajl_parser_wrapper * wrapper;
|
299
328
|
yajl_parser_config cfg;
|
300
329
|
VALUE opts, obj;
|
301
330
|
int allowComments = 1, checkUTF8 = 1, symbolizeKeys = 0;
|
@@ -316,7 +345,7 @@ static VALUE rb_yajl_parser_new(int argc, VALUE * argv, VALUE klass) {
|
|
316
345
|
}
|
317
346
|
cfg = (yajl_parser_config){allowComments, checkUTF8};
|
318
347
|
|
319
|
-
obj = Data_Make_Struct(klass,
|
348
|
+
obj = Data_Make_Struct(klass, yajl_parser_wrapper, yajl_parser_wrapper_mark, yajl_parser_wrapper_free, wrapper);
|
320
349
|
wrapper->parser = yajl_alloc(&callbacks, &cfg, NULL, (void *)obj);
|
321
350
|
wrapper->nestedArrayLevel = 0;
|
322
351
|
wrapper->nestedHashLevel = 0;
|
@@ -366,8 +395,9 @@ static VALUE rb_yajl_parser_init(int argc, VALUE * argv, VALUE self) {
|
|
366
395
|
*/
|
367
396
|
static VALUE rb_yajl_parser_parse(int argc, VALUE * argv, VALUE self) {
|
368
397
|
yajl_status stat;
|
369
|
-
|
398
|
+
yajl_parser_wrapper * wrapper;
|
370
399
|
VALUE rbufsize, input, blk;
|
400
|
+
const char * cptr;
|
371
401
|
|
372
402
|
GetParser(self, wrapper);
|
373
403
|
|
@@ -383,12 +413,14 @@ static VALUE rb_yajl_parser_parse(int argc, VALUE * argv, VALUE self) {
|
|
383
413
|
}
|
384
414
|
|
385
415
|
if (TYPE(input) == T_STRING) {
|
386
|
-
|
416
|
+
cptr = RSTRING_PTR(input);
|
417
|
+
yajl_parse_chunk((const unsigned char*)cptr, (unsigned int)strlen(cptr), wrapper->parser);
|
387
418
|
} else if (rb_respond_to(input, intern_eof)) {
|
388
419
|
VALUE parsed = rb_str_new2("");
|
389
420
|
while (rb_funcall(input, intern_eof, 0) != Qtrue) {
|
390
421
|
rb_funcall(input, intern_io_read, 2, rbufsize, parsed);
|
391
|
-
|
422
|
+
cptr = RSTRING_PTR(parsed);
|
423
|
+
yajl_parse_chunk((const unsigned char*)cptr, (unsigned int)strlen(cptr), wrapper->parser);
|
392
424
|
}
|
393
425
|
} else {
|
394
426
|
rb_raise(cParseError, "input must be a string or IO");
|
@@ -417,7 +449,7 @@ static VALUE rb_yajl_parser_parse(int argc, VALUE * argv, VALUE self) {
|
|
417
449
|
* parsed off the stream as they're found.
|
418
450
|
*/
|
419
451
|
static VALUE rb_yajl_parser_parse_chunk(VALUE self, VALUE chunk) {
|
420
|
-
|
452
|
+
yajl_parser_wrapper * wrapper;
|
421
453
|
|
422
454
|
GetParser(self, wrapper);
|
423
455
|
if (NIL_P(chunk)) {
|
@@ -426,7 +458,8 @@ static VALUE rb_yajl_parser_parse_chunk(VALUE self, VALUE chunk) {
|
|
426
458
|
}
|
427
459
|
|
428
460
|
if (wrapper->parse_complete_callback != Qnil) {
|
429
|
-
|
461
|
+
const char * cptr = RSTRING_PTR(chunk);
|
462
|
+
yajl_parse_chunk((const unsigned char*)cptr, (unsigned int)strlen(cptr), wrapper->parser);
|
430
463
|
} else {
|
431
464
|
rb_raise(cParseError, "The on_parse_complete callback isn't setup, parsing useless.");
|
432
465
|
}
|
@@ -444,7 +477,7 @@ static VALUE rb_yajl_parser_parse_chunk(VALUE self, VALUE chunk) {
|
|
444
477
|
* It will pass a single parameter, the ruby object built from the last parsed JSON object
|
445
478
|
*/
|
446
479
|
static VALUE rb_yajl_parser_set_complete_cb(VALUE self, VALUE callback) {
|
447
|
-
|
480
|
+
yajl_parser_wrapper * wrapper;
|
448
481
|
GetParser(self, wrapper);
|
449
482
|
wrapper->parse_complete_callback = callback;
|
450
483
|
return Qnil;
|
@@ -474,7 +507,7 @@ static VALUE rb_yajl_parser_set_complete_cb(VALUE self, VALUE callback) {
|
|
474
507
|
* the encoder will still pass it - I hope that makes sense ;).
|
475
508
|
*/
|
476
509
|
static VALUE rb_yajl_encoder_new(int argc, VALUE * argv, VALUE klass) {
|
477
|
-
|
510
|
+
yajl_encoder_wrapper * wrapper;
|
478
511
|
yajl_gen_config cfg;
|
479
512
|
VALUE opts, obj, indent;
|
480
513
|
const char * indentString = " ";
|
@@ -495,7 +528,7 @@ static VALUE rb_yajl_encoder_new(int argc, VALUE * argv, VALUE klass) {
|
|
495
528
|
}
|
496
529
|
cfg = (yajl_gen_config){beautify, indentString};
|
497
530
|
|
498
|
-
obj = Data_Make_Struct(klass,
|
531
|
+
obj = Data_Make_Struct(klass, yajl_encoder_wrapper, yajl_encoder_wrapper_mark, yajl_encoder_wrapper_free, wrapper);
|
499
532
|
wrapper->encoder = yajl_gen_alloc(&cfg, NULL);
|
500
533
|
wrapper->on_progress_callback = Qnil;
|
501
534
|
if (opts != Qnil && rb_funcall(opts, intern_has_key, 1, sym_terminator) == Qtrue) {
|
@@ -543,7 +576,7 @@ static VALUE rb_yajl_encoder_init(int argc, VALUE * argv, VALUE self) {
|
|
543
576
|
* ruby objects to encode. This is how streaming is accomplished.
|
544
577
|
*/
|
545
578
|
static VALUE rb_yajl_encoder_encode(int argc, VALUE * argv, VALUE self) {
|
546
|
-
|
579
|
+
yajl_encoder_wrapper * wrapper;
|
547
580
|
const unsigned char * buffer;
|
548
581
|
unsigned int len;
|
549
582
|
VALUE obj, io, blk, outBuff;
|
@@ -596,7 +629,7 @@ static VALUE rb_yajl_encoder_encode(int argc, VALUE * argv, VALUE self) {
|
|
596
629
|
* 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).
|
597
630
|
*/
|
598
631
|
static VALUE rb_yajl_encoder_set_progress_cb(VALUE self, VALUE callback) {
|
599
|
-
|
632
|
+
yajl_encoder_wrapper * wrapper;
|
600
633
|
GetEncoder(self, wrapper);
|
601
634
|
wrapper->on_progress_callback = callback;
|
602
635
|
return Qnil;
|