99
1010/* ruby api and some helpers */
1111
12- enum duplicate_key_action {
13- JSON_DEPRECATED = 0 ,
14- JSON_IGNORE ,
15- JSON_RAISE ,
16- };
17-
1812typedef struct JSON_Generator_StateStruct {
1913 VALUE indent ;
2014 VALUE space ;
@@ -27,8 +21,7 @@ typedef struct JSON_Generator_StateStruct {
2721 long depth ;
2822 long buffer_initial_length ;
2923
30- enum duplicate_key_action on_duplicate_key ;
31-
24+ bool allow_duplicate_key ;
3225 bool as_json_single_arg ;
3326 bool allow_nan ;
3427 bool ascii_only ;
@@ -41,7 +34,7 @@ static VALUE mJSON, cState, cFragment, eGeneratorError, eNestingError, Encoding_
4134
4235static ID i_to_s , i_to_json , i_new , i_encode ;
4336static VALUE sym_indent , sym_space , sym_space_before , sym_object_nl , sym_array_nl , sym_max_nesting , sym_allow_nan , sym_allow_duplicate_key ,
44- sym_ascii_only , sym_depth , sym_buffer_initial_length , sym_script_safe , sym_escape_slash , sym_strict , sym_as_json , sym_sort_keys ;
37+ sym_ascii_only , sym_depth , sym_buffer_initial_length , sym_script_safe , sym_strict , sym_as_json , sym_sort_keys ;
4538
4639
4740#define GET_STATE_TO (self , state ) \
@@ -956,9 +949,8 @@ json_inspect_hash_with_mixed_keys(struct hash_foreach_arg *arg)
956949 arg -> mixed_keys_encountered = true;
957950
958951 JSON_Generator_State * state = arg -> data -> state ;
959- if (state -> on_duplicate_key != JSON_IGNORE ) {
960- VALUE do_raise = state -> on_duplicate_key == JSON_RAISE ? Qtrue : Qfalse ;
961- rb_funcall (mJSON , rb_intern ("on_mixed_keys_hash" ), 2 , arg -> hash , do_raise );
952+ if (!state -> allow_duplicate_key ) {
953+ rb_funcall (mJSON , rb_intern ("on_mixed_keys_hash" ), 1 , arg -> hash );
962954 }
963955}
964956
@@ -1784,14 +1776,7 @@ static VALUE cState_sort_keys_set(VALUE self, VALUE value)
17841776static VALUE cState_allow_duplicate_key_p (VALUE self )
17851777{
17861778 GET_STATE (self );
1787- switch (state -> on_duplicate_key ) {
1788- case JSON_IGNORE :
1789- return Qtrue ;
1790- case JSON_DEPRECATED :
1791- return Qnil ;
1792- default :
1793- return Qfalse ;
1794- }
1779+ return state -> allow_duplicate_key ? Qtrue : Qfalse ;
17951780}
17961781
17971782/*
@@ -1856,6 +1841,7 @@ static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_l
18561841struct configure_state_data {
18571842 JSON_Generator_State * state ;
18581843 VALUE vstate ; // Ruby object that owns the state, or Qfalse if stack-allocated
1844+ VALUE unknown_keywords ;
18591845};
18601846
18611847static inline void state_write_value (struct configure_state_data * data , VALUE * field , VALUE value )
@@ -1883,9 +1869,8 @@ static int configure_state_i(VALUE key, VALUE val, VALUE _arg)
18831869 else if (key == sym_depth ) { state -> depth = depth_config (val ); }
18841870 else if (key == sym_buffer_initial_length ) { buffer_initial_length_set (state , val ); }
18851871 else if (key == sym_script_safe ) { state -> script_safe = RTEST (val ); }
1886- else if (key == sym_escape_slash ) { state -> script_safe = RTEST (val ); }
18871872 else if (key == sym_strict ) { state -> strict = RTEST (val ); }
1888- else if (key == sym_allow_duplicate_key ) { state -> on_duplicate_key = RTEST (val ) ? JSON_IGNORE : JSON_RAISE ; }
1873+ else if (key == sym_allow_duplicate_key ) { state -> allow_duplicate_key = RTEST (val ); }
18891874 else if (key == sym_as_json ) {
18901875 VALUE proc = RTEST (val ) ? rb_convert_type (val , T_DATA , "Proc" , "to_proc" ) : Qfalse ;
18911876 state -> as_json_single_arg = proc && rb_proc_arity (proc ) == 1 ;
@@ -1894,6 +1879,12 @@ static int configure_state_i(VALUE key, VALUE val, VALUE _arg)
18941879 else if (key == sym_sort_keys ) {
18951880 state_write_value (data , & state -> sort_keys , normalize_sort_keys (val ));
18961881 }
1882+ else {
1883+ if (!data -> unknown_keywords ) {
1884+ data -> unknown_keywords = rb_obj_hide (rb_ary_new ());
1885+ }
1886+ rb_ary_push (data -> unknown_keywords , key );
1887+ }
18971888 return ST_CONTINUE ;
18981889}
18991890
@@ -1907,12 +1898,15 @@ static void configure_state(JSON_Generator_State *state, VALUE vstate, VALUE con
19071898
19081899 struct configure_state_data data = {
19091900 .state = state ,
1910- .vstate = vstate
1901+ .vstate = vstate ,
1902+ .unknown_keywords = Qfalse ,
19111903 };
19121904
19131905 // We assume in most cases few keys are set so it's faster to go over
19141906 // the provided keys than to check all possible keys.
19151907 rb_hash_foreach (config , configure_state_i , (VALUE )& data );
1908+
1909+ raise_argument_error_on_unknown_keywords (data .unknown_keywords );
19161910}
19171911
19181912static VALUE cState_configure (VALUE self , VALUE opts )
@@ -2006,9 +2000,6 @@ void Init_generator(void)
20062000 rb_define_method (cState , "script_safe" , cState_script_safe , 0 );
20072001 rb_define_method (cState , "script_safe?" , cState_script_safe , 0 );
20082002 rb_define_method (cState , "script_safe=" , cState_script_safe_set , 1 );
2009- rb_define_alias (cState , "escape_slash" , "script_safe" );
2010- rb_define_alias (cState , "escape_slash?" , "script_safe?" );
2011- rb_define_alias (cState , "escape_slash=" , "script_safe=" );
20122003 rb_define_method (cState , "strict" , cState_strict , 0 );
20132004 rb_define_method (cState , "strict?" , cState_strict , 0 );
20142005 rb_define_method (cState , "strict=" , cState_strict_set , 1 );
@@ -2050,7 +2041,6 @@ void Init_generator(void)
20502041 sym_depth = ID2SYM (rb_intern ("depth" ));
20512042 sym_buffer_initial_length = ID2SYM (rb_intern ("buffer_initial_length" ));
20522043 sym_script_safe = ID2SYM (rb_intern ("script_safe" ));
2053- sym_escape_slash = ID2SYM (rb_intern ("escape_slash" ));
20542044 sym_strict = ID2SYM (rb_intern ("strict" ));
20552045 sym_as_json = ID2SYM (rb_intern ("as_json" ));
20562046 sym_allow_duplicate_key = ID2SYM (rb_intern ("allow_duplicate_key" ));
0 commit comments