brianmario-yajl-ruby 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +7 -1
- data/README.rdoc +20 -16
- data/VERSION.yml +1 -1
- data/ext/yajl_ext.c +2 -2
- data/ext/yajl_ext.h +2 -2
- data/lib/yajl.rb +1 -1
- data/spec/encoding/encoding_spec.rb +20 -0
- data/spec/parsing/one_off_spec.rb +26 -0
- data/yajl-ruby.gemspec +1 -1
- metadata +1 -1
data/CHANGELOG.rdoc
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
= Changelog
|
2
2
|
|
3
|
-
0.5.
|
3
|
+
0.5.1 (May 25th, 2009)
|
4
|
+
* added some more tests for the new API
|
5
|
+
* inlined a couple of hot functions used in parsing for a little speedup
|
6
|
+
* updates to readme, reflecting changes in API
|
7
|
+
* version bump to push another gem build
|
8
|
+
|
9
|
+
0.5.0 (May 25th, 2009)
|
4
10
|
* Refactored internal API so the caller can specify initialization options for the Parser and Encoder
|
5
11
|
respectively. Two new classes were introduced as a result - Yajl::Parser and Yajl::Encoder.
|
6
12
|
The newly refactored codebase is cleaner, thread-safe and removed all of the hack-code that was trickled
|
data/README.rdoc
CHANGED
@@ -25,16 +25,18 @@ Then maybe parse some JSON from:
|
|
25
25
|
a File IO
|
26
26
|
|
27
27
|
json = File.new('test.json', 'r')
|
28
|
-
|
28
|
+
parser = Yajl::Parser.new
|
29
|
+
hash = parser.parse(json)
|
29
30
|
|
30
31
|
or maybe a StringIO
|
31
32
|
|
32
|
-
json = StringIO.new
|
33
|
-
|
33
|
+
json = StringIO.new("...some JSON...")
|
34
|
+
parser = Yajl::Parser.new
|
35
|
+
hash = parser.parse(json)
|
34
36
|
|
35
37
|
or maybe STDIN
|
36
38
|
|
37
|
-
cat someJsonFile.json | ruby -ryajl -e "puts Yajl::
|
39
|
+
cat someJsonFile.json | ruby -ryajl -e "puts Yajl::Parser.new.parse(STDIN).inspect"
|
38
40
|
|
39
41
|
|
40
42
|
Or lets say you didn't have access to the IO object that contained JSON data, but instead
|
@@ -42,6 +44,10 @@ only had access to chunks of it at a time. No problem!
|
|
42
44
|
|
43
45
|
(Assume we're in an EventMachine::Connection instance)
|
44
46
|
|
47
|
+
def post_init
|
48
|
+
@parser = Yajl::Parser.new
|
49
|
+
end
|
50
|
+
|
45
51
|
def object_parsed(obj)
|
46
52
|
puts "Sometimes one pays most for the things one gets for nothing. - Albert Einstein"
|
47
53
|
puts obj.inspect
|
@@ -50,15 +56,12 @@ only had access to chunks of it at a time. No problem!
|
|
50
56
|
def connection_completed
|
51
57
|
# once a full JSON object has been parsed from the stream
|
52
58
|
# object_parsed will be called, and passed the constructed object
|
53
|
-
|
59
|
+
@parser.on_parse_complete = method(:object_parsed)
|
54
60
|
end
|
55
61
|
|
56
62
|
def receive_data(data)
|
57
63
|
# continue passing chunks
|
58
|
-
|
59
|
-
|
60
|
-
# Or as an alias, you could have done:
|
61
|
-
# Yajl::Chunked << data
|
64
|
+
@parser << data
|
62
65
|
end
|
63
66
|
|
64
67
|
|
@@ -110,7 +113,8 @@ This allows you to encode JSON as a stream, writing directly to a socket
|
|
110
113
|
|
111
114
|
socket = TCPSocket.new(192.168.1.101, 9000)
|
112
115
|
hash = {:foo => 12425125, :bar => "some string", ... }
|
113
|
-
Yajl::
|
116
|
+
encoder = Yajl::Encoder.new
|
117
|
+
Yajl::encoder.encode(hash, socket)
|
114
118
|
|
115
119
|
Or what if you wanted to compress the stream over the wire?
|
116
120
|
|
@@ -148,25 +152,25 @@ Here's what parsing a 2.43MB JSON file off the filesystem 20 times looks like:
|
|
148
152
|
|
149
153
|
==== Average
|
150
154
|
|
151
|
-
* Yajl::
|
155
|
+
* Yajl::Parser#parse: 32MB
|
152
156
|
* JSON.parse: 54MB
|
153
157
|
* ActiveSupport::JSON.decode: 63MB
|
154
158
|
|
155
159
|
==== Peak
|
156
160
|
|
157
|
-
* Yajl::
|
161
|
+
* Yajl::Parser#parse: 32MB
|
158
162
|
* JSON.parse: 57MB
|
159
163
|
* ActiveSupport::JSON.decode: 67MB
|
160
164
|
|
161
165
|
=== Parse Time
|
162
166
|
|
163
|
-
* Yajl::
|
167
|
+
* Yajl::Parser#parse: 4.54s
|
164
168
|
* JSON.parse: 5.47s
|
165
169
|
* ActiveSupport::JSON.decode: 64.42s
|
166
170
|
|
167
171
|
=== Encode Time
|
168
172
|
|
169
|
-
* Yajl::
|
173
|
+
* Yajl::Encoder#encode: 3.59s
|
170
174
|
* JSON#to_json: 6.2s
|
171
175
|
* ActiveSupport::JSON.encode: 45.58s
|
172
176
|
|
@@ -176,13 +180,13 @@ NOTE: I converted the 2.4MB JSON file to YAML for this test.
|
|
176
180
|
|
177
181
|
==== Parse Time (from their respective formats)
|
178
182
|
|
179
|
-
* Yajl::
|
183
|
+
* Yajl::Parser#parse: 4.33s
|
180
184
|
* JSON.parse: 5.37s
|
181
185
|
* YAML.load_stream: 19.47s
|
182
186
|
|
183
187
|
==== Encode Time (to their respective formats)
|
184
188
|
|
185
|
-
* Yajl::
|
189
|
+
* Yajl::Encoder#encode: 3.47s
|
186
190
|
* JSON#to_json: 6.6s
|
187
191
|
* YAML.dump(obj, io): 1309.93s
|
188
192
|
|
data/VERSION.yml
CHANGED
data/ext/yajl_ext.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#include "yajl_ext.h"
|
2
2
|
|
3
3
|
// Helpers for building objects
|
4
|
-
void yajl_check_and_fire_callback(void * ctx) {
|
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
|
|
@@ -14,7 +14,7 @@ void yajl_check_and_fire_callback(void * ctx) {
|
|
14
14
|
}
|
15
15
|
}
|
16
16
|
|
17
|
-
void yajl_set_static_value(void * ctx, VALUE val) {
|
17
|
+
inline void yajl_set_static_value(void * ctx, VALUE val) {
|
18
18
|
struct yajl_parser_wrapper * wrapper;
|
19
19
|
VALUE lastEntry, hash;
|
20
20
|
int len;
|
data/ext/yajl_ext.h
CHANGED
@@ -11,8 +11,8 @@ static ID intern_io_read, intern_eof, intern_call, intern_keys, intern_to_s,
|
|
11
11
|
#define GetParser(obj, sval) (sval = (struct yajl_parser_wrapper*)DATA_PTR(obj));
|
12
12
|
#define GetEncoder(obj, sval) (sval = (yajl_gen*)DATA_PTR(obj));
|
13
13
|
|
14
|
-
void yajl_check_and_fire_callback(void * ctx);
|
15
|
-
void yajl_set_static_value(void * ctx, VALUE val);
|
14
|
+
inline void yajl_check_and_fire_callback(void * ctx);
|
15
|
+
inline void yajl_set_static_value(void * ctx, VALUE val);
|
16
16
|
void yajl_encode_part(yajl_gen hand, VALUE obj, VALUE io);
|
17
17
|
|
18
18
|
static int yajl_found_null(void * ctx);
|
data/lib/yajl.rb
CHANGED
@@ -25,4 +25,24 @@ describe "Yajl JSON encoder" do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
+
|
29
|
+
it "should encode with :pretty turned on and a single space indent" do
|
30
|
+
output = "{\n \"foo\": {\n \"name\": \"bar\",\n \"id\": 1234\n }\n}\n"
|
31
|
+
obj = {:foo => {:id => 1234, :name => "bar"}}
|
32
|
+
io = StringIO.new
|
33
|
+
encoder = Yajl::Encoder.new(:pretty => true, :indent => ' ')
|
34
|
+
encoder.encode(obj, io)
|
35
|
+
io.rewind
|
36
|
+
io.read.should == output
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should encode with :pretty turned on and a tab character indent" do
|
40
|
+
output = "{\n\t\"foo\": {\n\t\t\"name\": \"bar\",\n\t\t\"id\": 1234\n\t}\n}\n"
|
41
|
+
obj = {:foo => {:id => 1234, :name => "bar"}}
|
42
|
+
io = StringIO.new
|
43
|
+
encoder = Yajl::Encoder.new(:pretty => true, :indent => "\t")
|
44
|
+
encoder.encode(obj, io)
|
45
|
+
io.rewind
|
46
|
+
io.read.should == output
|
47
|
+
end
|
28
48
|
end
|
@@ -9,4 +9,30 @@ describe "One-off JSON examples" do
|
|
9
9
|
parser.parse(StringIO.new('{"key": 23456789012E666}')).should == {"key" => infinity}
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
it "should not parse JSON with a comment, with :allow_comments set to false" do
|
14
|
+
parser = Yajl::Parser.new(:allow_comments => false)
|
15
|
+
json = StringIO.new('{"key": /* this is a comment */ "value"}')
|
16
|
+
lambda {
|
17
|
+
parser.parse(json)
|
18
|
+
}.should raise_error(Yajl::ParseError)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should parse JSON with a comment, with :allow_comments set to true" do
|
22
|
+
parser = Yajl::Parser.new(:allow_comments => true)
|
23
|
+
json = StringIO.new('{"key": /* this is a comment */ "value"}')
|
24
|
+
lambda {
|
25
|
+
parser.parse(json)
|
26
|
+
}.should_not raise_error(Yajl::ParseError)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not parse invalid UTF8 with :check_utf8 set to true" do
|
30
|
+
pending
|
31
|
+
# not sure how to write this test yet
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should parse invalid UTF8 with :check_utf8 set to false" do
|
35
|
+
pending
|
36
|
+
# not sure how to write this test yet
|
37
|
+
end
|
12
38
|
end
|
data/yajl-ruby.gemspec
CHANGED