scout 5.1.2 → 5.1.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.
- data/CHANGELOG +5 -0
- data/lib/scout.rb +1 -1
- data/lib/scout/server.rb +4 -1
- data/vendor/json_pure/CHANGES +43 -0
- data/vendor/json_pure/{RUBY → COPYING} +1 -1
- data/vendor/json_pure/GPL +7 -7
- data/vendor/json_pure/README +319 -39
- data/vendor/json_pure/Rakefile +69 -47
- data/vendor/json_pure/VERSION +1 -1
- data/vendor/json_pure/benchmarks/generator2_benchmark.rb +222 -0
- data/vendor/json_pure/benchmarks/generator_benchmark.rb +64 -5
- data/vendor/json_pure/benchmarks/ohai.json +1216 -0
- data/vendor/json_pure/benchmarks/ohai.ruby +1 -0
- data/vendor/json_pure/benchmarks/parser2_benchmark.rb +251 -0
- data/vendor/json_pure/benchmarks/parser_benchmark.rb +67 -5
- data/vendor/json_pure/ext/json/ext/generator/extconf.rb +9 -4
- data/vendor/json_pure/ext/json/ext/generator/generator.c +831 -409
- data/vendor/json_pure/ext/json/ext/generator/generator.h +170 -0
- data/vendor/json_pure/ext/json/ext/parser/extconf.rb +8 -4
- data/vendor/json_pure/ext/json/ext/parser/parser.c +292 -186
- data/vendor/json_pure/ext/json/ext/parser/parser.h +71 -0
- data/vendor/json_pure/ext/json/ext/parser/parser.rl +218 -112
- data/vendor/json_pure/lib/json/add/core.rb +20 -7
- data/vendor/json_pure/lib/json/add/rails.rb +2 -2
- data/vendor/json_pure/lib/json/common.rb +85 -42
- data/vendor/json_pure/lib/json/pure.rb +3 -3
- data/vendor/json_pure/lib/json/pure/generator.rb +112 -90
- data/vendor/json_pure/lib/json/pure/parser.rb +42 -4
- data/vendor/json_pure/lib/json/version.rb +1 -1
- data/vendor/json_pure/tests/test_json.rb +46 -18
- data/vendor/json_pure/tests/test_json_addition.rb +4 -6
- data/vendor/json_pure/tests/test_json_encoding.rb +68 -0
- data/vendor/json_pure/tests/test_json_generate.rb +30 -14
- data/vendor/json_pure/tests/test_json_rails.rb +5 -7
- data/vendor/json_pure/tests/test_json_unicode.rb +20 -6
- metadata +26 -15
- data/vendor/json_pure/doc-templates/main.txt +0 -283
- data/vendor/json_pure/ext/json/ext/generator/unicode.c +0 -182
- data/vendor/json_pure/ext/json/ext/generator/unicode.h +0 -53
- data/vendor/json_pure/ext/json/ext/parser/unicode.c +0 -154
- data/vendor/json_pure/ext/json/ext/parser/unicode.h +0 -58
@@ -0,0 +1,71 @@
|
|
1
|
+
#ifndef _PARSER_H_
|
2
|
+
#define _PARSER_H_
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
|
6
|
+
#if HAVE_RE_H
|
7
|
+
#include "re.h"
|
8
|
+
#endif
|
9
|
+
|
10
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
11
|
+
#include "ruby/encoding.h"
|
12
|
+
#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
|
13
|
+
#else
|
14
|
+
#define FORCE_UTF8(obj)
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
|
18
|
+
|
19
|
+
/* unicode */
|
20
|
+
|
21
|
+
typedef unsigned long UTF32; /* at least 32 bits */
|
22
|
+
typedef unsigned short UTF16; /* at least 16 bits */
|
23
|
+
typedef unsigned char UTF8; /* typically 8 bits */
|
24
|
+
|
25
|
+
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
|
26
|
+
#define UNI_SUR_HIGH_START (UTF32)0xD800
|
27
|
+
#define UNI_SUR_HIGH_END (UTF32)0xDBFF
|
28
|
+
#define UNI_SUR_LOW_START (UTF32)0xDC00
|
29
|
+
#define UNI_SUR_LOW_END (UTF32)0xDFFF
|
30
|
+
|
31
|
+
typedef struct JSON_ParserStruct {
|
32
|
+
VALUE Vsource;
|
33
|
+
char *source;
|
34
|
+
long len;
|
35
|
+
char *memo;
|
36
|
+
VALUE create_id;
|
37
|
+
int max_nesting;
|
38
|
+
int current_nesting;
|
39
|
+
int allow_nan;
|
40
|
+
int parsing_name;
|
41
|
+
int symbolize_names;
|
42
|
+
VALUE object_class;
|
43
|
+
VALUE array_class;
|
44
|
+
} JSON_Parser;
|
45
|
+
|
46
|
+
#define GET_PARSER \
|
47
|
+
JSON_Parser *json; \
|
48
|
+
Data_Get_Struct(self, JSON_Parser, json)
|
49
|
+
|
50
|
+
#define MinusInfinity "-Infinity"
|
51
|
+
#define EVIL 0x666
|
52
|
+
|
53
|
+
static UTF32 unescape_unicode(const unsigned char *p);
|
54
|
+
static int convert_UTF32_to_UTF8(char *buf, UTF32 ch);
|
55
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
56
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
57
|
+
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
58
|
+
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
59
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
60
|
+
static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd);
|
61
|
+
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
62
|
+
static VALUE convert_encoding(VALUE source);
|
63
|
+
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self);
|
64
|
+
static VALUE cParser_parse(VALUE self);
|
65
|
+
static JSON_Parser *JSON_allocate();
|
66
|
+
static void JSON_mark(JSON_Parser *json);
|
67
|
+
static void JSON_free(JSON_Parser *json);
|
68
|
+
static VALUE cJSON_parser_s_allocate(VALUE klass);
|
69
|
+
static VALUE cParser_source(VALUE self);
|
70
|
+
|
71
|
+
#endif
|
@@ -1,59 +1,83 @@
|
|
1
|
-
#include "
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
#include "parser.h"
|
2
|
+
|
3
|
+
/* unicode */
|
4
|
+
|
5
|
+
static const char digit_values[256] = {
|
6
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
7
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
8
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
|
9
|
+
-1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
|
10
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
11
|
+
10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
12
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
13
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
14
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
15
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
16
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
17
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
18
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
19
|
+
-1, -1, -1, -1, -1, -1, -1
|
20
|
+
};
|
21
|
+
|
22
|
+
static UTF32 unescape_unicode(const unsigned char *p)
|
23
|
+
{
|
24
|
+
char b;
|
25
|
+
UTF32 result = 0;
|
26
|
+
b = digit_values[p[0]];
|
27
|
+
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
28
|
+
result = (result << 4) | b;
|
29
|
+
b = digit_values[p[1]];
|
30
|
+
result = (result << 4) | b;
|
31
|
+
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
32
|
+
b = digit_values[p[2]];
|
33
|
+
result = (result << 4) | b;
|
34
|
+
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
35
|
+
b = digit_values[p[3]];
|
36
|
+
result = (result << 4) | b;
|
37
|
+
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
38
|
+
return result;
|
39
|
+
}
|
14
40
|
|
15
|
-
|
16
|
-
|
17
|
-
|
41
|
+
static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
42
|
+
{
|
43
|
+
int len = 1;
|
44
|
+
if (ch <= 0x7F) {
|
45
|
+
buf[0] = (char) ch;
|
46
|
+
} else if (ch <= 0x07FF) {
|
47
|
+
buf[0] = (char) ((ch >> 6) | 0xC0);
|
48
|
+
buf[1] = (char) ((ch & 0x3F) | 0x80);
|
49
|
+
len++;
|
50
|
+
} else if (ch <= 0xFFFF) {
|
51
|
+
buf[0] = (char) ((ch >> 12) | 0xE0);
|
52
|
+
buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
|
53
|
+
buf[2] = (char) ((ch & 0x3F) | 0x80);
|
54
|
+
len += 2;
|
55
|
+
} else if (ch <= 0x1fffff) {
|
56
|
+
buf[0] =(char) ((ch >> 18) | 0xF0);
|
57
|
+
buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
|
58
|
+
buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
|
59
|
+
buf[3] =(char) ((ch & 0x3F) | 0x80);
|
60
|
+
len += 3;
|
61
|
+
} else {
|
62
|
+
buf[0] = '?';
|
63
|
+
}
|
64
|
+
return len;
|
65
|
+
}
|
18
66
|
|
19
67
|
#ifdef HAVE_RUBY_ENCODING_H
|
20
|
-
|
21
|
-
|
68
|
+
static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
|
69
|
+
CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
|
70
|
+
static ID i_encoding, i_encode, i_encode_bang, i_force_encoding;
|
22
71
|
#else
|
23
|
-
|
72
|
+
static ID i_iconv;
|
24
73
|
#endif
|
25
74
|
|
26
75
|
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
27
76
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
28
77
|
|
29
78
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
30
|
-
i_chr, i_max_nesting, i_allow_nan, i_object_class,
|
31
|
-
|
32
|
-
#define MinusInfinity "-Infinity"
|
33
|
-
|
34
|
-
typedef struct JSON_ParserStruct {
|
35
|
-
VALUE Vsource;
|
36
|
-
char *source;
|
37
|
-
long len;
|
38
|
-
char *memo;
|
39
|
-
VALUE create_id;
|
40
|
-
int max_nesting;
|
41
|
-
int current_nesting;
|
42
|
-
int allow_nan;
|
43
|
-
VALUE object_class;
|
44
|
-
VALUE array_class;
|
45
|
-
} JSON_Parser;
|
46
|
-
|
47
|
-
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
48
|
-
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
49
|
-
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
50
|
-
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
51
|
-
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
52
|
-
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
53
|
-
|
54
|
-
#define GET_STRUCT \
|
55
|
-
JSON_Parser *json; \
|
56
|
-
Data_Get_Struct(self, JSON_Parser, json);
|
79
|
+
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
|
80
|
+
i_array_class, i_key_p, i_deep_const_get;
|
57
81
|
|
58
82
|
%%{
|
59
83
|
machine JSON_common;
|
@@ -101,7 +125,10 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
101
125
|
}
|
102
126
|
|
103
127
|
action parse_name {
|
104
|
-
char *np
|
128
|
+
char *np;
|
129
|
+
json->parsing_name = 1;
|
130
|
+
np = JSON_parse_string(json, fpc, pe, &last_name);
|
131
|
+
json->parsing_name = 0;
|
105
132
|
if (np == NULL) { fhold; fbreak; } else fexec np;
|
106
133
|
}
|
107
134
|
|
@@ -123,7 +150,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
123
150
|
VALUE object_class = json->object_class;
|
124
151
|
|
125
152
|
if (json->max_nesting && json->current_nesting > json->max_nesting) {
|
126
|
-
rb_raise(eNestingError, "nesting of %d is
|
153
|
+
rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
|
127
154
|
}
|
128
155
|
|
129
156
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
@@ -135,7 +162,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
135
162
|
if (RTEST(json->create_id)) {
|
136
163
|
VALUE klassname = rb_hash_aref(*result, json->create_id);
|
137
164
|
if (!NIL_P(klassname)) {
|
138
|
-
VALUE klass =
|
165
|
+
VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
|
139
166
|
if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) {
|
140
167
|
*result = rb_funcall(klass, i_json_create, 1, *result);
|
141
168
|
}
|
@@ -336,7 +363,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
336
363
|
VALUE array_class = json->array_class;
|
337
364
|
|
338
365
|
if (json->max_nesting && json->current_nesting > json->max_nesting) {
|
339
|
-
rb_raise(eNestingError, "nesting of %d is
|
366
|
+
rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
|
340
367
|
}
|
341
368
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
342
369
|
|
@@ -347,62 +374,77 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
347
374
|
return p + 1;
|
348
375
|
} else {
|
349
376
|
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
377
|
+
return NULL;
|
350
378
|
}
|
351
379
|
}
|
352
380
|
|
353
|
-
static VALUE json_string_unescape(char *
|
381
|
+
static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
354
382
|
{
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
383
|
+
char *p = string, *pe = string, *unescape;
|
384
|
+
int unescape_len;
|
385
|
+
|
386
|
+
while (pe < stringEnd) {
|
387
|
+
if (*pe == '\\') {
|
388
|
+
unescape = (char *) "?";
|
389
|
+
unescape_len = 1;
|
390
|
+
if (pe > p) rb_str_buf_cat(result, p, pe - p);
|
391
|
+
switch (*++pe) {
|
392
|
+
case 'n':
|
393
|
+
unescape = (char *) "\n";
|
394
|
+
break;
|
395
|
+
case 'r':
|
396
|
+
unescape = (char *) "\r";
|
397
|
+
break;
|
398
|
+
case 't':
|
399
|
+
unescape = (char *) "\t";
|
400
|
+
break;
|
362
401
|
case '"':
|
402
|
+
unescape = (char *) "\"";
|
403
|
+
break;
|
363
404
|
case '\\':
|
364
|
-
|
365
|
-
p++;
|
405
|
+
unescape = (char *) "\\";
|
366
406
|
break;
|
367
407
|
case 'b':
|
368
|
-
|
369
|
-
p++;
|
408
|
+
unescape = (char *) "\b";
|
370
409
|
break;
|
371
410
|
case 'f':
|
372
|
-
|
373
|
-
p++;
|
374
|
-
break;
|
375
|
-
case 'n':
|
376
|
-
rb_str_buf_cat2(result, "\n");
|
377
|
-
p++;
|
378
|
-
break;
|
379
|
-
case 'r':
|
380
|
-
rb_str_buf_cat2(result, "\r");
|
381
|
-
p++;
|
382
|
-
break;
|
383
|
-
case 't':
|
384
|
-
rb_str_buf_cat2(result, "\t");
|
385
|
-
p++;
|
411
|
+
unescape = (char *) "\f";
|
386
412
|
break;
|
387
413
|
case 'u':
|
388
|
-
if (
|
414
|
+
if (pe > stringEnd - 4) {
|
389
415
|
return Qnil;
|
390
416
|
} else {
|
391
|
-
|
417
|
+
char buf[4];
|
418
|
+
UTF32 ch = unescape_unicode((unsigned char *) ++pe);
|
419
|
+
pe += 3;
|
420
|
+
if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
|
421
|
+
pe++;
|
422
|
+
if (pe > stringEnd - 6) return Qnil;
|
423
|
+
if (pe[0] == '\\' && pe[1] == 'u') {
|
424
|
+
UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
|
425
|
+
ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
|
426
|
+
| (sur & 0x3FF));
|
427
|
+
pe += 5;
|
428
|
+
} else {
|
429
|
+
unescape = (char *) "?";
|
430
|
+
break;
|
431
|
+
}
|
432
|
+
}
|
433
|
+
unescape_len = convert_UTF32_to_UTF8(buf, ch);
|
434
|
+
unescape = buf;
|
392
435
|
}
|
393
436
|
break;
|
394
437
|
default:
|
395
|
-
|
396
|
-
|
397
|
-
break;
|
438
|
+
p = pe;
|
439
|
+
continue;
|
398
440
|
}
|
441
|
+
rb_str_buf_cat(result, unescape, unescape_len);
|
442
|
+
p = ++pe;
|
399
443
|
} else {
|
400
|
-
|
401
|
-
while (*q != '\\' && q < pe) q++;
|
402
|
-
rb_str_buf_cat(result, p, q - p);
|
403
|
-
p = q;
|
444
|
+
pe++;
|
404
445
|
}
|
405
446
|
}
|
447
|
+
rb_str_buf_cat(result, p, pe - p);
|
406
448
|
return result;
|
407
449
|
}
|
408
450
|
|
@@ -413,7 +455,7 @@ static VALUE json_string_unescape(char *p, char *pe)
|
|
413
455
|
write data;
|
414
456
|
|
415
457
|
action parse_string {
|
416
|
-
*result = json_string_unescape(json->memo + 1, p);
|
458
|
+
*result = json_string_unescape(*result, json->memo + 1, p);
|
417
459
|
if (NIL_P(*result)) {
|
418
460
|
fhold;
|
419
461
|
fbreak;
|
@@ -432,11 +474,14 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
432
474
|
{
|
433
475
|
int cs = EVIL;
|
434
476
|
|
435
|
-
*result =
|
477
|
+
*result = rb_str_buf_new(0);
|
436
478
|
%% write init;
|
437
479
|
json->memo = p;
|
438
480
|
%% write exec;
|
439
481
|
|
482
|
+
if (json->symbolize_names && json->parsing_name) {
|
483
|
+
*result = rb_str_intern(*result);
|
484
|
+
}
|
440
485
|
if (cs >= JSON_string_first_final) {
|
441
486
|
return p + 1;
|
442
487
|
} else {
|
@@ -484,6 +529,54 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
484
529
|
*
|
485
530
|
*/
|
486
531
|
|
532
|
+
static VALUE convert_encoding(VALUE source)
|
533
|
+
{
|
534
|
+
char *ptr = RSTRING_PTR(source);
|
535
|
+
long len = RSTRING_LEN(source);
|
536
|
+
if (len < 2) {
|
537
|
+
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
538
|
+
}
|
539
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
540
|
+
{
|
541
|
+
VALUE encoding = rb_funcall(source, i_encoding, 0);
|
542
|
+
if (encoding == CEncoding_ASCII_8BIT) {
|
543
|
+
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
544
|
+
source = rb_str_dup(source);
|
545
|
+
rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32BE);
|
546
|
+
source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
|
547
|
+
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
548
|
+
source = rb_str_dup(source);
|
549
|
+
rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16BE);
|
550
|
+
source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
|
551
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
552
|
+
source = rb_str_dup(source);
|
553
|
+
rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32LE);
|
554
|
+
source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
|
555
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
556
|
+
source = rb_str_dup(source);
|
557
|
+
rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16LE);
|
558
|
+
source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
|
559
|
+
} else {
|
560
|
+
FORCE_UTF8(source);
|
561
|
+
}
|
562
|
+
} else {
|
563
|
+
source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
|
564
|
+
}
|
565
|
+
}
|
566
|
+
#else
|
567
|
+
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
568
|
+
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
|
569
|
+
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
570
|
+
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
|
571
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
572
|
+
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
|
573
|
+
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
574
|
+
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
|
575
|
+
}
|
576
|
+
#endif
|
577
|
+
return source;
|
578
|
+
}
|
579
|
+
|
487
580
|
/*
|
488
581
|
* call-seq: new(source, opts => {})
|
489
582
|
*
|
@@ -501,6 +594,9 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
501
594
|
* * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
|
502
595
|
* defiance of RFC 4627 to be parsed by the Parser. This option defaults to
|
503
596
|
* false.
|
597
|
+
* * *symbolize_names*: If set to true, returns symbols for the names
|
598
|
+
* (keys) in a JSON object. Otherwise strings are returned, which is also
|
599
|
+
* the default.
|
504
600
|
* * *create_additions*: If set to false, the Parser doesn't create
|
505
601
|
* additions even if a matchin class and create_id was found. This option
|
506
602
|
* defaults to true.
|
@@ -512,21 +608,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
512
608
|
char *ptr;
|
513
609
|
long len;
|
514
610
|
VALUE source, opts;
|
515
|
-
|
611
|
+
GET_PARSER;
|
516
612
|
rb_scan_args(argc, argv, "11", &source, &opts);
|
517
|
-
source = StringValue(source);
|
613
|
+
source = convert_encoding(StringValue(source));
|
518
614
|
ptr = RSTRING_PTR(source);
|
519
615
|
len = RSTRING_LEN(source);
|
520
|
-
if (len < 2) {
|
521
|
-
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
522
|
-
}
|
523
616
|
if (!NIL_P(opts)) {
|
524
617
|
opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
|
525
618
|
if (NIL_P(opts)) {
|
526
619
|
rb_raise(rb_eArgError, "opts needs to be like a hash");
|
527
620
|
} else {
|
528
621
|
VALUE tmp = ID2SYM(i_max_nesting);
|
529
|
-
if (
|
622
|
+
if (option_given_p(opts, tmp)) {
|
530
623
|
VALUE max_nesting = rb_hash_aref(opts, tmp);
|
531
624
|
if (RTEST(max_nesting)) {
|
532
625
|
Check_Type(max_nesting, T_FIXNUM);
|
@@ -538,14 +631,21 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
538
631
|
json->max_nesting = 19;
|
539
632
|
}
|
540
633
|
tmp = ID2SYM(i_allow_nan);
|
541
|
-
if (
|
634
|
+
if (option_given_p(opts, tmp)) {
|
542
635
|
VALUE allow_nan = rb_hash_aref(opts, tmp);
|
543
636
|
json->allow_nan = RTEST(allow_nan) ? 1 : 0;
|
544
637
|
} else {
|
545
638
|
json->allow_nan = 0;
|
546
639
|
}
|
640
|
+
tmp = ID2SYM(i_symbolize_names);
|
641
|
+
if (option_given_p(opts, tmp)) {
|
642
|
+
VALUE symbolize_names = rb_hash_aref(opts, tmp);
|
643
|
+
json->symbolize_names = RTEST(symbolize_names) ? 1 : 0;
|
644
|
+
} else {
|
645
|
+
json->symbolize_names = 0;
|
646
|
+
}
|
547
647
|
tmp = ID2SYM(i_create_additions);
|
548
|
-
if (
|
648
|
+
if (option_given_p(opts, tmp)) {
|
549
649
|
VALUE create_additions = rb_hash_aref(opts, tmp);
|
550
650
|
if (RTEST(create_additions)) {
|
551
651
|
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
@@ -556,13 +656,13 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
556
656
|
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
557
657
|
}
|
558
658
|
tmp = ID2SYM(i_object_class);
|
559
|
-
if (
|
659
|
+
if (option_given_p(opts, tmp)) {
|
560
660
|
json->object_class = rb_hash_aref(opts, tmp);
|
561
661
|
} else {
|
562
662
|
json->object_class = Qnil;
|
563
663
|
}
|
564
664
|
tmp = ID2SYM(i_array_class);
|
565
|
-
if (
|
665
|
+
if (option_given_p(opts, tmp)) {
|
566
666
|
json->array_class = rb_hash_aref(opts, tmp);
|
567
667
|
} else {
|
568
668
|
json->array_class = Qnil;
|
@@ -576,18 +676,6 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
576
676
|
json->array_class = Qnil;
|
577
677
|
}
|
578
678
|
json->current_nesting = 0;
|
579
|
-
/*
|
580
|
-
Convert these?
|
581
|
-
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
582
|
-
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
583
|
-
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
584
|
-
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
585
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
586
|
-
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
587
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
588
|
-
rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
|
589
|
-
}
|
590
|
-
*/
|
591
679
|
json->len = len;
|
592
680
|
json->source = ptr;
|
593
681
|
json->Vsource = source;
|
@@ -605,7 +693,7 @@ static VALUE cParser_parse(VALUE self)
|
|
605
693
|
char *p, *pe;
|
606
694
|
int cs = EVIL;
|
607
695
|
VALUE result = Qnil;
|
608
|
-
|
696
|
+
GET_PARSER;
|
609
697
|
|
610
698
|
%% write init;
|
611
699
|
p = json->source;
|
@@ -616,10 +704,11 @@ static VALUE cParser_parse(VALUE self)
|
|
616
704
|
return result;
|
617
705
|
} else {
|
618
706
|
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
707
|
+
return Qnil;
|
619
708
|
}
|
620
709
|
}
|
621
710
|
|
622
|
-
|
711
|
+
static JSON_Parser *JSON_allocate()
|
623
712
|
{
|
624
713
|
JSON_Parser *json = ALLOC(JSON_Parser);
|
625
714
|
MEMZERO(json, JSON_Parser, 1);
|
@@ -653,7 +742,7 @@ static VALUE cJSON_parser_s_allocate(VALUE klass)
|
|
653
742
|
*/
|
654
743
|
static VALUE cParser_source(VALUE self)
|
655
744
|
{
|
656
|
-
|
745
|
+
GET_PARSER;
|
657
746
|
return rb_str_dup(json->Vsource);
|
658
747
|
}
|
659
748
|
|
@@ -681,6 +770,23 @@ void Init_parser()
|
|
681
770
|
i_chr = rb_intern("chr");
|
682
771
|
i_max_nesting = rb_intern("max_nesting");
|
683
772
|
i_allow_nan = rb_intern("allow_nan");
|
773
|
+
i_symbolize_names = rb_intern("symbolize_names");
|
684
774
|
i_object_class = rb_intern("object_class");
|
685
775
|
i_array_class = rb_intern("array_class");
|
776
|
+
i_key_p = rb_intern("key?");
|
777
|
+
i_deep_const_get = rb_intern("deep_const_get");
|
778
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
779
|
+
CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
|
780
|
+
CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
|
781
|
+
CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
|
782
|
+
CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
|
783
|
+
CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
|
784
|
+
CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
|
785
|
+
i_encoding = rb_intern("encoding");
|
786
|
+
i_encode = rb_intern("encode");
|
787
|
+
i_encode_bang = rb_intern("encode!");
|
788
|
+
i_force_encoding = rb_intern("force_encoding");
|
789
|
+
#else
|
790
|
+
i_iconv = rb_intern("iconv");
|
791
|
+
#endif
|
686
792
|
}
|