@@ -412,6 +412,7 @@ typedef struct JSON_ParserStruct {
412412 VALUE object_class ;
413413 VALUE array_class ;
414414 VALUE decimal_class ;
415+ ID decimal_method_id ;
415416 VALUE match_string ;
416417 int max_nesting ;
417418 bool allow_nan ;
@@ -746,45 +747,14 @@ static VALUE json_decode_large_float(const char *start, long len)
746747 RB_ALLOCV_END (buffer_v );
747748 return number ;
748749}
749-
750+
750751static VALUE json_decode_float (JSON_ParserConfig * config , const char * start , const char * end )
751752{
752- VALUE mod = Qnil ;
753- ID method_id = 0 ;
754- if (RB_UNLIKELY (config -> decimal_class )) {
755- // TODO: we should move this to the constructor
756- if (rb_respond_to (config -> decimal_class , i_try_convert )) {
757- mod = config -> decimal_class ;
758- method_id = i_try_convert ;
759- } else if (rb_respond_to (config -> decimal_class , i_new )) {
760- mod = config -> decimal_class ;
761- method_id = i_new ;
762- } else if (RB_TYPE_P (config -> decimal_class , T_CLASS )) {
763- VALUE name = rb_class_name (config -> decimal_class );
764- const char * name_cstr = RSTRING_PTR (name );
765- const char * last_colon = strrchr (name_cstr , ':' );
766- if (last_colon ) {
767- const char * mod_path_end = last_colon - 1 ;
768- VALUE mod_path = rb_str_substr (name , 0 , mod_path_end - name_cstr );
769- mod = rb_path_to_class (mod_path );
770-
771- const char * method_name_beg = last_colon + 1 ;
772- long before_len = method_name_beg - name_cstr ;
773- long len = RSTRING_LEN (name ) - before_len ;
774- VALUE method_name = rb_str_substr (name , before_len , len );
775- method_id = SYM2ID (rb_str_intern (method_name ));
776- } else {
777- mod = rb_mKernel ;
778- method_id = SYM2ID (rb_str_intern (name ));
779- }
780- }
781- }
782-
783753 long len = end - start ;
784754
785- if (RB_UNLIKELY (method_id )) {
755+ if (RB_UNLIKELY (config -> decimal_class )) {
786756 VALUE text = rb_str_new (start , len );
787- return rb_funcallv (mod , method_id , 1 , & text );
757+ return rb_funcallv (config -> decimal_class , config -> decimal_method_id , 1 , & text );
788758 } else if (RB_LIKELY (len < 64 )) {
789759 char buffer [64 ];
790760 MEMCPY (buffer , start , char , len );
@@ -1240,8 +1210,36 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
12401210 else if (key == sym_create_id ) { config -> create_id = RTEST (val ) ? val : Qfalse ; }
12411211 else if (key == sym_object_class ) { config -> object_class = RTEST (val ) ? val : Qfalse ; }
12421212 else if (key == sym_array_class ) { config -> array_class = RTEST (val ) ? val : Qfalse ; }
1243- else if (key == sym_decimal_class ) { config -> decimal_class = RTEST (val ) ? val : Qfalse ; }
12441213 else if (key == sym_match_string ) { config -> match_string = RTEST (val ) ? val : Qfalse ; }
1214+ else if (key == sym_decimal_class ) {
1215+ if (RTEST (val )) {
1216+ if (rb_respond_to (val , i_try_convert )) {
1217+ config -> decimal_class = val ;
1218+ config -> decimal_method_id = i_try_convert ;
1219+ } else if (rb_respond_to (val , i_new )) {
1220+ config -> decimal_class = val ;
1221+ config -> decimal_method_id = i_new ;
1222+ } else if (RB_TYPE_P (val , T_CLASS )) {
1223+ VALUE name = rb_class_name (val );
1224+ const char * name_cstr = RSTRING_PTR (name );
1225+ const char * last_colon = strrchr (name_cstr , ':' );
1226+ if (last_colon ) {
1227+ const char * mod_path_end = last_colon - 1 ;
1228+ VALUE mod_path = rb_str_substr (name , 0 , mod_path_end - name_cstr );
1229+ config -> decimal_class = rb_path_to_class (mod_path );
1230+
1231+ const char * method_name_beg = last_colon + 1 ;
1232+ long before_len = method_name_beg - name_cstr ;
1233+ long len = RSTRING_LEN (name ) - before_len ;
1234+ VALUE method_name = rb_str_substr (name , before_len , len );
1235+ config -> decimal_method_id = SYM2ID (rb_str_intern (method_name ));
1236+ } else {
1237+ config -> decimal_class = rb_mKernel ;
1238+ config -> decimal_method_id = SYM2ID (rb_str_intern (name ));
1239+ }
1240+ }
1241+ }
1242+ }
12451243 else if (key == sym_create_additions ) {
12461244 if (NIL_P (val )) {
12471245 config -> create_additions = true;
0 commit comments