yajl-ruby 0.8.2 → 0.8.3
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 +7 -0
- data/README.rdoc +6 -10
- data/ext/yajl/api/yajl_version.h +1 -1
- data/ext/yajl/yajl_encode.c +9 -2
- data/ext/yajl/yajl_ext.c +6 -1
- data/ext/yajl/yajl_ext.h +1 -1
- data/ext/yajl/yajl_gen.c +36 -11
- data/ext/yajl/yajl_parser.c +3 -3
- data/lib/yajl/http_stream.rb +26 -13
- data/lib/yajl/version.rb +1 -1
- data/spec/http/http_stream_options_spec.rb +28 -0
- data/spec/parsing/one_off_spec.rb +6 -2
- metadata +6 -4
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.8.3 (August 16th, 2011)
|
4
|
+
* fix bug where Yajl::HttpStream wouldn't pass through a user-specified socket
|
5
|
+
* fix incorrect Ruby initialization hook method name
|
6
|
+
* Bump bundled YAJL version to 1.0.12
|
7
|
+
* fix to correctly symbolize multibyte characters on 1.9
|
8
|
+
* add `:headers` option to Yajl::HttpStream for user-specified arbitrary headers
|
9
|
+
|
3
10
|
## 0.8.2 (March 22nd, 2011)
|
4
11
|
* define RSTRING_NOT_MODIFIED for rbx to prevent string caching, making things A LOT faster (100x)
|
5
12
|
|
data/README.rdoc
CHANGED
@@ -19,13 +19,9 @@ You can read more info at the project's website http://lloyd.github.com/yajl or
|
|
19
19
|
|
20
20
|
== How to install
|
21
21
|
|
22
|
-
|
22
|
+
Go ahead and install it as usual:
|
23
23
|
|
24
|
-
gem
|
25
|
-
|
26
|
-
Then go ahead and install it as usual:
|
27
|
-
|
28
|
-
sudo gem install yajl-ruby
|
24
|
+
gem install yajl-ruby
|
29
25
|
|
30
26
|
== Example of use
|
31
27
|
|
@@ -137,7 +133,7 @@ Since yajl-ruby does everything using streams, you simply need to pass the objec
|
|
137
133
|
|
138
134
|
This allows you to encode JSON as a stream, writing directly to a socket
|
139
135
|
|
140
|
-
socket = TCPSocket.new(192.168.1.101, 9000)
|
136
|
+
socket = TCPSocket.new('192.168.1.101', 9000)
|
141
137
|
hash = {:foo => 12425125, :bar => "some string", ... }
|
142
138
|
encoder = Yajl::Encoder.new
|
143
139
|
Yajl::Encoder.encode(hash, socket)
|
@@ -145,14 +141,14 @@ This allows you to encode JSON as a stream, writing directly to a socket
|
|
145
141
|
Or what if you wanted to compress the stream over the wire?
|
146
142
|
|
147
143
|
require 'yajl/gzip'
|
148
|
-
socket = TCPSocket.new(192.168.1.101, 9000)
|
144
|
+
socket = TCPSocket.new('192.168.1.101', 9000)
|
149
145
|
hash = {:foo => 12425125, :bar => "some string", ... }
|
150
146
|
Yajl::Gzip::StreamWriter.encode(hash, socket)
|
151
147
|
|
152
148
|
Or what about encoding multiple objects to JSON over the same stream?
|
153
149
|
This example will encode and send 50 JSON objects over the same stream, continuously.
|
154
150
|
|
155
|
-
socket = TCPSocket.new(192.168.1.101, 9000)
|
151
|
+
socket = TCPSocket.new('192.168.1.101', 9000)
|
156
152
|
encoder = Yajl::Encoder.new
|
157
153
|
50.times do
|
158
154
|
hash = {:current_time => Time.now.to_f, :foo => 12425125}
|
@@ -327,4 +323,4 @@ I've had a lot of inspiration, and a lot of help. Thanks to everyone who's been
|
|
327
323
|
* Luke Redpath
|
328
324
|
* Neil Berkman
|
329
325
|
* Pavel Valodzka
|
330
|
-
* Rob Sharp
|
326
|
+
* Rob Sharp
|
data/ext/yajl/api/yajl_version.h
CHANGED
data/ext/yajl/yajl_encode.c
CHANGED
@@ -89,7 +89,7 @@ yajl_string_encode2(const yajl_print_t print,
|
|
89
89
|
}
|
90
90
|
if (escaped != NULL) {
|
91
91
|
print(ctx, (const char *) (str + beg), end - beg);
|
92
|
-
print(ctx, escaped, strlen(escaped));
|
92
|
+
print(ctx, escaped, (unsigned int)strlen(escaped));
|
93
93
|
beg = ++end;
|
94
94
|
} else {
|
95
95
|
++end;
|
@@ -179,12 +179,19 @@ void yajl_string_decode(yajl_buf buf, const unsigned char * str,
|
|
179
179
|
|
180
180
|
Utf32toUtf8(codepoint, utf8Buf);
|
181
181
|
unescaped = utf8Buf;
|
182
|
+
|
183
|
+
if (codepoint == 0) {
|
184
|
+
yajl_buf_append(buf, unescaped, 1);
|
185
|
+
beg = ++end;
|
186
|
+
continue;
|
187
|
+
}
|
188
|
+
|
182
189
|
break;
|
183
190
|
}
|
184
191
|
default:
|
185
192
|
assert("this should never happen" == NULL);
|
186
193
|
}
|
187
|
-
yajl_buf_append(buf, unescaped, strlen(unescaped));
|
194
|
+
yajl_buf_append(buf, unescaped, (unsigned int)strlen(unescaped));
|
188
195
|
beg = ++end;
|
189
196
|
} else {
|
190
197
|
end++;
|
data/ext/yajl/yajl_ext.c
CHANGED
@@ -286,7 +286,12 @@ static int yajl_found_hash_key(void * ctx, const unsigned char * stringVal, unsi
|
|
286
286
|
char buf[stringLen+1];
|
287
287
|
memcpy(buf, stringVal, stringLen);
|
288
288
|
buf[stringLen] = 0;
|
289
|
-
|
289
|
+
VALUE stringEncoded = rb_str_new2(buf);
|
290
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
291
|
+
rb_enc_associate(stringEncoded, rb_utf8_encoding());
|
292
|
+
#endif
|
293
|
+
|
294
|
+
yajl_set_static_value(ctx, ID2SYM(rb_to_id(stringEncoded)));
|
290
295
|
} else {
|
291
296
|
keyStr = rb_str_new((const char *)stringVal, stringLen);
|
292
297
|
#ifdef HAVE_RUBY_ENCODING_H
|
data/ext/yajl/yajl_ext.h
CHANGED
@@ -132,4 +132,4 @@ static VALUE rb_yajl_json_ext_false_to_json(int argc, VALUE * argv, VALUE self);
|
|
132
132
|
static VALUE rb_yajl_json_ext_nil_to_json(int argc, VALUE * argv, VALUE self);
|
133
133
|
static VALUE rb_yajl_encoder_enable_json_gem_ext(VALUE klass);
|
134
134
|
|
135
|
-
void
|
135
|
+
void Init_yajl();
|
data/ext/yajl/yajl_gen.c
CHANGED
@@ -91,13 +91,32 @@ yajl_gen_alloc2(const yajl_print_t callback,
|
|
91
91
|
}
|
92
92
|
|
93
93
|
g = (yajl_gen) YA_MALLOC(afs, sizeof(struct yajl_gen_t));
|
94
|
+
if (!g) return NULL;
|
95
|
+
|
94
96
|
memset((void *) g, 0, sizeof(struct yajl_gen_t));
|
95
97
|
/* copy in pointers to allocation routines */
|
96
98
|
memcpy((void *) &(g->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
|
97
99
|
|
98
100
|
if (config) {
|
101
|
+
const char *indent = config->indentString;
|
99
102
|
g->pretty = config->beautify;
|
100
|
-
g->indentString = config->indentString
|
103
|
+
g->indentString = config->indentString;
|
104
|
+
if (indent) {
|
105
|
+
for (; *indent; indent++) {
|
106
|
+
if (*indent != '\n'
|
107
|
+
&& *indent != '\v'
|
108
|
+
&& *indent != '\f'
|
109
|
+
&& *indent != '\t'
|
110
|
+
&& *indent != '\r'
|
111
|
+
&& *indent != ' ') {
|
112
|
+
g->indentString = NULL;
|
113
|
+
break;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
if (!g->indentString) {
|
118
|
+
g->indentString = " ";
|
119
|
+
}
|
101
120
|
g->htmlSafe = config->htmlSafe;
|
102
121
|
}
|
103
122
|
|
@@ -134,15 +153,17 @@ yajl_gen_free(yajl_gen g)
|
|
134
153
|
if (g->state[g->depth] != yajl_gen_map_val) { \
|
135
154
|
unsigned int _i; \
|
136
155
|
for (_i=0;_i<g->depth;_i++) \
|
137
|
-
g->print(g->ctx,
|
138
|
-
|
156
|
+
g->print(g->ctx, \
|
157
|
+
g->indentString, \
|
158
|
+
(unsigned int)strlen(g->indentString)); \
|
139
159
|
} \
|
140
160
|
}
|
141
161
|
|
142
162
|
#define ENSURE_NOT_KEY \
|
143
|
-
if (g->state[g->depth] == yajl_gen_map_key
|
144
|
-
|
145
|
-
|
163
|
+
if (g->state[g->depth] == yajl_gen_map_key || \
|
164
|
+
g->state[g->depth] == yajl_gen_map_start) { \
|
165
|
+
return yajl_gen_keys_must_be_strings; \
|
166
|
+
} \
|
146
167
|
|
147
168
|
/* check that we're not complete, or in error state. in a valid state
|
148
169
|
* to be generating */
|
@@ -156,6 +177,9 @@ yajl_gen_free(yajl_gen g)
|
|
156
177
|
#define INCREMENT_DEPTH \
|
157
178
|
if (++(g->depth) >= YAJL_MAX_DEPTH) return yajl_max_depth_exceeded;
|
158
179
|
|
180
|
+
#define DECREMENT_DEPTH \
|
181
|
+
if (--(g->depth) >= YAJL_MAX_DEPTH) return yajl_gen_error;
|
182
|
+
|
159
183
|
#define APPENDED_ATOM \
|
160
184
|
switch (g->state[g->depth]) { \
|
161
185
|
case yajl_gen_map_start: \
|
@@ -180,7 +204,7 @@ yajl_gen_integer(yajl_gen g, long int number)
|
|
180
204
|
char i[32];
|
181
205
|
ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
|
182
206
|
sprintf(i, "%ld", number);
|
183
|
-
g->print(g->ctx, i, strlen(i));
|
207
|
+
g->print(g->ctx, i, (unsigned int)strlen(i));
|
184
208
|
APPENDED_ATOM;
|
185
209
|
FINAL_NEWLINE;
|
186
210
|
return yajl_gen_status_ok;
|
@@ -200,7 +224,7 @@ yajl_gen_double(yajl_gen g, double number)
|
|
200
224
|
if (isnan(number) || isinf(number)) return yajl_gen_invalid_number;
|
201
225
|
INSERT_SEP; INSERT_WHITESPACE;
|
202
226
|
sprintf(i, "%.20g", number);
|
203
|
-
g->print(g->ctx, i, strlen(i));
|
227
|
+
g->print(g->ctx, i, (unsigned int)strlen(i));
|
204
228
|
APPENDED_ATOM;
|
205
229
|
FINAL_NEWLINE;
|
206
230
|
return yajl_gen_status_ok;
|
@@ -245,7 +269,7 @@ yajl_gen_bool(yajl_gen g, int boolean)
|
|
245
269
|
const char * val = boolean ? "true" : "false";
|
246
270
|
|
247
271
|
ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
|
248
|
-
g->print(g->ctx, val, strlen(val));
|
272
|
+
g->print(g->ctx, val, (unsigned int)strlen(val));
|
249
273
|
APPENDED_ATOM;
|
250
274
|
FINAL_NEWLINE;
|
251
275
|
return yajl_gen_status_ok;
|
@@ -268,7 +292,8 @@ yajl_gen_status
|
|
268
292
|
yajl_gen_map_close(yajl_gen g)
|
269
293
|
{
|
270
294
|
ENSURE_VALID_STATE;
|
271
|
-
|
295
|
+
DECREMENT_DEPTH;
|
296
|
+
|
272
297
|
if (g->pretty) g->print(g->ctx, "\n", 1);
|
273
298
|
APPENDED_ATOM;
|
274
299
|
INSERT_WHITESPACE;
|
@@ -293,8 +318,8 @@ yajl_gen_status
|
|
293
318
|
yajl_gen_array_close(yajl_gen g)
|
294
319
|
{
|
295
320
|
ENSURE_VALID_STATE;
|
321
|
+
DECREMENT_DEPTH;
|
296
322
|
if (g->pretty) g->print(g->ctx, "\n", 1);
|
297
|
-
(g->depth)--;
|
298
323
|
APPENDED_ATOM;
|
299
324
|
INSERT_WHITESPACE;
|
300
325
|
g->print(g->ctx, "]", 1);
|
data/ext/yajl/yajl_parser.c
CHANGED
@@ -111,9 +111,9 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
|
|
111
111
|
text[i] = 0;
|
112
112
|
{
|
113
113
|
char * newStr = (char *)
|
114
|
-
YA_MALLOC(&(hand->alloc), (strlen((char *) str) +
|
115
|
-
|
116
|
-
|
114
|
+
YA_MALLOC(&(hand->alloc), (unsigned int)(strlen((char *) str) +
|
115
|
+
strlen((char *) text) +
|
116
|
+
strlen(arrow) + 1));
|
117
117
|
newStr[0] = 0;
|
118
118
|
strcat((char *) newStr, (char *) str);
|
119
119
|
strcat((char *) newStr, text);
|
data/lib/yajl/http_stream.rb
CHANGED
@@ -90,31 +90,42 @@ module Yajl
|
|
90
90
|
uri = URI.parse(uri)
|
91
91
|
end
|
92
92
|
|
93
|
-
|
93
|
+
default_headers = {
|
94
|
+
"User-Agent" => opts["User-Agent"] || "Yajl::HttpStream #{Yajl::VERSION}",
|
95
|
+
"Accept" => "*/*",
|
96
|
+
"Accept-Charset" => "utf-8"
|
97
|
+
}
|
98
|
+
|
94
99
|
if method == "POST" || method == "PUT"
|
95
|
-
|
100
|
+
default_headers["Content-Type"] = opts["Content-Type"] || "application/x-www-form-urlencoded"
|
96
101
|
body = opts.delete(:body)
|
97
102
|
if body.is_a?(Hash)
|
98
103
|
body = body.keys.collect {|param| "#{URI.escape(param.to_s)}=#{URI.escape(body[param].to_s)}"}.join('&')
|
99
104
|
end
|
105
|
+
default_headers["Content-Length"] = body.length
|
100
106
|
end
|
101
107
|
|
102
|
-
|
103
|
-
|
104
|
-
request << "Host: #{uri.host}\r\n"
|
105
|
-
request << "Authorization: Basic #{[uri.userinfo].pack('m').strip!}\r\n" unless uri.userinfo.nil?
|
106
|
-
request << "User-Agent: #{user_agent}\r\n"
|
107
|
-
request << "Accept: */*\r\n"
|
108
|
-
if method == "POST" || method == "PUT"
|
109
|
-
request << "Content-Length: #{body.length}\r\n"
|
110
|
-
request << "Content-Type: #{content_type}\r\n"
|
108
|
+
unless uri.userinfo.nil?
|
109
|
+
default_headers["Authorization"] = "Basic #{[uri.userinfo].pack('m').strip!}\r\n"
|
111
110
|
end
|
111
|
+
|
112
112
|
encodings = []
|
113
113
|
encodings << "bzip2" if defined?(Yajl::Bzip2)
|
114
114
|
encodings << "gzip" if defined?(Yajl::Gzip)
|
115
115
|
encodings << "deflate" if defined?(Yajl::Deflate)
|
116
|
-
|
117
|
-
|
116
|
+
if encodings.any?
|
117
|
+
default_headers["Accept-Encoding"] = "#{encodings.join(',')}\r\n"
|
118
|
+
end
|
119
|
+
|
120
|
+
headers = default_headers.merge(opts[:headers] || {})
|
121
|
+
|
122
|
+
socket = opts.delete(:socket) || TCPSocket.new(uri.host, uri.port)
|
123
|
+
request = "#{method} #{uri.path}#{uri.query ? "?"+uri.query : nil} HTTP/1.1\r\n"
|
124
|
+
request << "Host: #{uri.host}\r\n"
|
125
|
+
headers.each do |k, v|
|
126
|
+
request << "#{k}: #{v}\r\n"
|
127
|
+
end
|
128
|
+
request << "\r\n"
|
118
129
|
if method == "POST" || method == "PUT"
|
119
130
|
request << body
|
120
131
|
end
|
@@ -190,6 +201,8 @@ module Yajl
|
|
190
201
|
private
|
191
202
|
# Initialize socket and add it to the opts
|
192
203
|
def initialize_socket(uri, opts = {})
|
204
|
+
return if opts[:socket]
|
205
|
+
|
193
206
|
@socket = TCPSocket.new(uri.host, uri.port)
|
194
207
|
opts.merge!({:socket => @socket})
|
195
208
|
@intentional_termination = false
|
data/lib/yajl/version.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
|
3
|
+
require 'yajl/http_stream'
|
4
|
+
require 'socket'
|
5
|
+
|
6
|
+
describe "Passing options to HttpStream instance methods" do
|
7
|
+
before(:all) do
|
8
|
+
@stream = Yajl::HttpStream.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should not create a new socket it one is provided" do
|
12
|
+
TCPSocket.should_not_receive(:new)
|
13
|
+
options = {:socket => :my_provided_socket}
|
14
|
+
|
15
|
+
@stream.send(:initialize_socket, URI.parse("http://google.com"), options)
|
16
|
+
|
17
|
+
options[:socket].should == :my_provided_socket
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should create a new socket if one is not provided" do
|
21
|
+
TCPSocket.should_receive(:new).with("google.com", 80).and_return( :tcp_socket )
|
22
|
+
options = {}
|
23
|
+
|
24
|
+
@stream.send(:initialize_socket, URI.parse("http://google.com"), options)
|
25
|
+
|
26
|
+
options[:socket].should == :tcp_socket
|
27
|
+
end
|
28
|
+
end
|
@@ -40,10 +40,14 @@ describe "One-off JSON examples" do
|
|
40
40
|
Yajl::Parser.parse(io).should == {"key" => 1234}
|
41
41
|
end
|
42
42
|
|
43
|
-
it "should parse using it's class method, from
|
43
|
+
it "should parse using it's class method, from a string with symbolized keys" do
|
44
44
|
Yajl::Parser.parse('{"key": 1234}', :symbolize_keys => true).should == {:key => 1234}
|
45
45
|
end
|
46
46
|
|
47
|
+
it "should parse using it's class method, from a utf-8 string with multibyte characters, with symbolized keys" do
|
48
|
+
Yajl::Parser.parse('{"日本語": 1234}', :symbolize_keys => true).should == {:"日本語" => 1234}
|
49
|
+
end
|
50
|
+
|
47
51
|
it "should parse using it's class method, from a string" do
|
48
52
|
Yajl::Parser.parse('{"key": 1234}').should == {"key" => 1234}
|
49
53
|
end
|
@@ -78,4 +82,4 @@ describe "One-off JSON examples" do
|
|
78
82
|
Yajl::Parser.parse('{"key": "value"}').values.first.encoding.should eql(Encoding.default_internal)
|
79
83
|
end
|
80
84
|
end
|
81
|
-
end
|
85
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yajl-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 57
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 8
|
9
|
-
-
|
10
|
-
version: 0.8.
|
9
|
+
- 3
|
10
|
+
version: 0.8.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brian Lopez
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-
|
19
|
+
date: 2011-08-16 00:00:00 -07:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -168,6 +168,7 @@ files:
|
|
168
168
|
- spec/http/http_get_spec.rb
|
169
169
|
- spec/http/http_post_spec.rb
|
170
170
|
- spec/http/http_put_spec.rb
|
171
|
+
- spec/http/http_stream_options_spec.rb
|
171
172
|
- spec/json_gem_compatibility/compatibility_spec.rb
|
172
173
|
- spec/parsing/active_support_spec.rb
|
173
174
|
- spec/parsing/chunked_spec.rb
|
@@ -293,6 +294,7 @@ test_files:
|
|
293
294
|
- spec/http/http_get_spec.rb
|
294
295
|
- spec/http/http_post_spec.rb
|
295
296
|
- spec/http/http_put_spec.rb
|
297
|
+
- spec/http/http_stream_options_spec.rb
|
296
298
|
- spec/json_gem_compatibility/compatibility_spec.rb
|
297
299
|
- spec/parsing/active_support_spec.rb
|
298
300
|
- spec/parsing/chunked_spec.rb
|