ext/json/ext/parser/parser.rl in json_pure-1.2.0 vs ext/json/ext/parser/parser.rl in json_pure-1.2.1
- old
+ new
@@ -29,11 +29,12 @@
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
static VALUE CNaN, CInfinity, CMinusInfinity;
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
- i_chr, i_max_nesting, i_allow_nan, i_object_class, i_array_class;
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
+ i_array_class;
#define MinusInfinity "-Infinity"
typedef struct JSON_ParserStruct {
VALUE Vsource;
@@ -42,10 +43,12 @@
char *memo;
VALUE create_id;
int max_nesting;
int current_nesting;
int allow_nan;
+ int parsing_name;
+ int symbolize_names;
VALUE object_class;
VALUE array_class;
} JSON_Parser;
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
@@ -103,11 +106,13 @@
fexec np;
}
}
action parse_name {
+ json->parsing_name = 1;
char *np = JSON_parse_string(json, fpc, pe, &last_name);
+ json->parsing_name = 0;
if (np == NULL) { fhold; fbreak; } else fexec np;
}
action exit { fhold; fbreak; }
@@ -415,19 +420,19 @@
include JSON_common;
write data;
action parse_string {
- *result = json_string_unescape(json->memo + 1, p);
- if (NIL_P(*result)) {
- fhold;
- fbreak;
- } else {
- FORCE_UTF8(*result);
- fexec p + 1;
- }
- }
+ *result = json_string_unescape(json->memo + 1, p);
+ if (NIL_P(*result)) {
+ fhold;
+ fbreak;
+ } else {
+ FORCE_UTF8(*result);
+ fexec p + 1;
+ }
+ }
action exit { fhold; fbreak; }
main := '"' ((^(["\\] | 0..0x1f) | '\\'["\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^(["\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
}%%
@@ -439,10 +444,13 @@
*result = rb_str_new("", 0);
%% write init;
json->memo = p;
%% write exec;
+ if (json->symbolize_names && json->parsing_name) {
+ *result = rb_str_intern(*result);
+ }
if (cs >= JSON_string_first_final) {
return p + 1;
} else {
return NULL;
}
@@ -551,10 +559,13 @@
* structures. Disable depth checking with :max_nesting => false|nil|0, it
* defaults to 19.
* * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
* defiance of RFC 4627 to be parsed by the Parser. This option defaults to
* false.
+ * * *symbolize_names*: If set to true, returns symbols for the names
+ * (keys) in a JSON object. Otherwise strings are returned, which is also
+ * the default.
* * *create_additions*: If set to false, the Parser doesn't create
* additions even if a matchin class and create_id was found. This option
* defaults to true.
* * *object_class*: Defaults to Hash
* * *array_class*: Defaults to Array
@@ -591,10 +602,17 @@
VALUE allow_nan = rb_hash_aref(opts, tmp);
json->allow_nan = RTEST(allow_nan) ? 1 : 0;
} else {
json->allow_nan = 0;
}
+ tmp = ID2SYM(i_symbolize_names);
+ if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
+ VALUE symbolize_names = rb_hash_aref(opts, tmp);
+ json->symbolize_names = RTEST(symbolize_names) ? 1 : 0;
+ } else {
+ json->symbolize_names = 0;
+ }
tmp = ID2SYM(i_create_additions);
if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
VALUE create_additions = rb_hash_aref(opts, tmp);
if (RTEST(create_additions)) {
json->create_id = rb_funcall(mJSON, i_create_id, 0);
@@ -716,9 +734,10 @@
i_create_id = rb_intern("create_id");
i_create_additions = rb_intern("create_additions");
i_chr = rb_intern("chr");
i_max_nesting = rb_intern("max_nesting");
i_allow_nan = rb_intern("allow_nan");
+ i_symbolize_names = rb_intern("symbolize_names");
i_object_class = rb_intern("object_class");
i_array_class = rb_intern("array_class");
#ifdef HAVE_RUBY_ENCODING_H
mEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
mEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));