brianmario-yajl-ruby 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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