yajl-ruby 0.8.2 → 0.8.3
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.
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
|