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"));