4747
4848#define ROOT_PROPERTY_NAME ("") // A name used to represent the beginning of the JSON. !NO OTHER PROPERTY MUST OBTAIN THIS NAME EXCEPT ROOT~
4949
50- #define OBJECT_STR_STATE_INIT_LEN 1000 // The initial length of the state string (see strintify function)
51-
5250
5351// Indicated whether the currently incomplete attribute is an object.
5452#define BUILDING_OBJECT (COMP ) (CURLY_BRACKETS_CLOSE == COMP)
@@ -107,7 +105,8 @@ static inline char *incomplete_property_str_expand_state
107105(const char * state , const char * data , const char * key )
108106{
109107 size_t key_size = (NULL == key )? 0 : strlen (key );
110- char * new_state = (char * ) malloc (strlen (state ) + strlen (data ) + key_size + 1 );
108+ size_t colon_len = 1 ;
109+ char * new_state = (char * ) malloc (strlen (state ) + strlen (data ) + key_size + colon_len + 1 );
111110 if (NULL == new_state ) return NULL ;
112111
113112 if (NULL == key ) {
@@ -618,7 +617,6 @@ int cjlib_json_read(struct cjlib_json *restrict dst)
618617
619618 if (NULL == curr_incomplete_data .i_name ) goto read_err ;
620619
621-
622620 // Push the first incomplete object into the stack.
623621 if (-1 == cjlib_stack_push ((void * ) & curr_incomplete_data , sizeof (struct incomplete_property ),
624622 & incomplate_data_stc ))
@@ -812,9 +810,9 @@ static char *simple_key_value_paired_stringtify
812810 * @param entry The incomplete object/array.
813811 * @param entry_key The key of the key:pair combination for the incomplete object/array.
814812 */
815- static inline int switch_incomplete_str_data
813+ static inline int switch_from_incomplete_obj_str_data
816814(struct incomplete_property_str * restrict dst , enum cjlib_json_datatypes type ,
817- cjlib_json_object * entry )
815+ cjlib_json_object * entry , bool init )
818816{
819817 struct cjlib_json_data * examine_entry_data = CJLIB_DICT_NODE_DATA (entry );
820818 * dst = (struct incomplete_property_str ) {
@@ -828,12 +826,37 @@ static inline int switch_incomplete_str_data
828826
829827 cjlib_queue_init (dst -> i_pending_data_q );
830828
831- if (CJLIB_OBJECT == type ) dst -> i_data .object = entry ;
832- else dst -> i_data .array = examine_entry_data -> c_value .c_arr ;
829+ if (init ) {
830+ if (CJLIB_OBJECT == type ) dst -> i_data .object = entry ;
831+ } else {
832+ if (CJLIB_OBJECT == type ) dst -> i_data .object = examine_entry_data -> c_value .c_obj ;
833+ else dst -> i_data .array = examine_entry_data -> c_value .c_arr ;
834+ }
833835
834836 return 0 ;
835837}
836838
839+ static inline int switch_from_incomplete_arr_str_data
840+ (struct incomplete_property_str * restrict dst , enum cjlib_json_datatypes type ,
841+ struct cjlib_json_data * entry_data , const char * key )
842+ {
843+ struct cjlib_json_data * examine_entry_data = entry_data ;
844+ * dst = (struct incomplete_property_str ) {
845+ .i_key = strdup (key ),
846+ .i_type = type ,
847+ .i_state = strdup ("" ),
848+ .i_pending_data_q = (struct cjlib_queue * ) malloc (sizeof (struct cjlib_queue ))
849+ };
850+
851+ if (NULL == dst -> i_pending_data_q ) return -1 ;
852+
853+ cjlib_queue_init (dst -> i_pending_data_q );
854+
855+ if (CJLIB_OBJECT == type ) dst -> i_data .object = examine_entry_data -> c_value .c_obj ;
856+ else dst -> i_data .array = examine_entry_data -> c_value .c_arr ;
857+
858+ return 0 ;
859+ }
837860/**
838861 * Convert the provided @src list into a queue.
839862 *
@@ -852,7 +875,7 @@ static int convert_list_to_queue(struct cjlib_queue *restrict dst, const struct
852875
853876 CJLIB_LIST_FOR_EACH_PTR (item , src , struct cjlib_json_data ) {
854877 // Store the pointers of each element in the list into the @dst
855- if ( -1 == cjlib_queue_enqeue ((void * ) & item , sizeof (struct cjlib_json_data * ), dst )) {
878+ if (-1 == cjlib_queue_enqeue ((void * ) & item , sizeof (struct cjlib_json_data * ), dst )) {
856879 return -1 ;
857880 }
858881 }
@@ -876,7 +899,7 @@ const char *cjlib_json_object_stringtify(const cjlib_json_object *src)
876899 incomplete_property_str_init (& curr_incomp );
877900 cjlib_stack_init (& incomplete_st );
878901
879- if (-1 == switch_incomplete_str_data (& curr_incomp , CJLIB_OBJECT , (cjlib_json_object * ) src )) return NULL ;
902+ if (-1 == switch_from_incomplete_obj_str_data (& curr_incomp , CJLIB_OBJECT , (cjlib_json_object * ) src , true )) return NULL ;
880903
881904 if (-1 == cjlib_dict_postorder (curr_incomp .i_pending_data_q , curr_incomp .i_data .object )) return NULL ;
882905
@@ -888,45 +911,63 @@ const char *cjlib_json_object_stringtify(const cjlib_json_object *src)
888911 if (-1 == cjlib_stack_pop ((void * ) & curr_incomp , sizeof (struct incomplete_property_str ),
889912 & incomplete_st )) return NULL ;
890913
891- tmp_state = curr_incomp .i_state ;
892- if (CJLIB_OBJECT == curr_incomp .i_type ) {
893- curr_incomp .i_state = incomplete_property_str_expand_state (curr_incomp .i_state , value_str , tmp_key );
894- free (tmp_key );
895- tmp_key = NULL ;
896- } else {
897- curr_incomp .i_state = incomplete_property_str_expand_state (curr_incomp .i_state , value_str , NULL );
898- }
914+ // If the value_str is NULL, then, the nested while have not run yet.
915+ if (NULL != value_str ) {
916+ tmp_state = curr_incomp .i_state ;
917+ if (CJLIB_OBJECT == curr_incomp .i_type ) {
918+ curr_incomp .i_state = incomplete_property_str_expand_state (curr_incomp .i_state , value_str , tmp_key );
919+ free (tmp_key );
920+ tmp_key = NULL ;
921+ } else {
922+ curr_incomp .i_state = incomplete_property_str_expand_state (curr_incomp .i_state , value_str , NULL );
923+ }
899924
900- free (value_str );
901- free (tmp_state );
902- tmp_state = NULL ;
903- value_str = NULL ;
925+ free (value_str );
926+ free (tmp_state );
927+ tmp_state = NULL ;
928+ value_str = NULL ;
929+ }
904930
905931 while (!cjlib_queue_is_empty (curr_incomp .i_pending_data_q )) {
906932 // Get the entry to strintify.
907-
908933 if (CJLIB_OBJECT == curr_incomp .i_type ) {
909934 // The queue of an incomplete object consists of NODES of avl binary tree.
910935 cjlib_queue_deqeue ((void * ) & examine_entry , sizeof (cjlib_dict_node_t * ), curr_incomp .i_pending_data_q );
911936 examine_entry_data = CJLIB_DICT_NODE_DATA (examine_entry );
912937 } else {
913938 // The queue of an incomplete array consists of NODES of a linked list.
914- cjlib_queue_deqeue ((void * ) & examine_entry_data , sizeof (struct cjlib_json_data ), curr_incomp .i_pending_data_q );
939+ cjlib_queue_deqeue ((void * ) & examine_entry_data , sizeof (struct cjlib_json_data * ), curr_incomp .i_pending_data_q );
915940 }
916941
917942 switch (examine_entry_data -> c_datatype ) {
918943 case CJLIB_OBJECT :
919944 cjlib_stack_push (& curr_incomp , sizeof (struct incomplete_property_str ),
920945 & incomplete_st );
921946
922- if (-1 == switch_incomplete_str_data (& curr_incomp , CJLIB_OBJECT , examine_entry )) return NULL ;
947+ /**
948+ * (gdb) print(*examine_entry_data)
949+ $23 = {c_value = {c_str = 0x40a640 "\200\231@", c_num = 2.0932889485015272e-317, c_boolean = 64, c_obj = 0x40a640,
950+ c_null = 0x40a640, c_arr = 0x40a640}, c_datatype = CJLIB_OBJECT}
951+
952+ (gdb) print(*examine_entry_data.c_value.c_obj)
953+ $24 = {avl_data = 0x409980, avl_key = 0x4098c0 "request", avl_left = 0x409dd0, avl_right = 0x409c90}
954+ (gdb) n
955+ cjlib_stack_push(&curr_incomp, sizeof(struct incomplete_property_str),
956+ (gdb) n
957+ <----- HERE IS THE BUG ----- > TODO - When switching from array, DO NOT pass the examine entry.
958+ if (-1 == switch_from_incomplete_obj_str_data(&curr_incomp, CJLIB_OBJECT, examine_entry, false)) return NULL;
959+ (gdb)
960+ if (-1 == cjlib_dict_postorder(curr_incomp.i_pending_data_q, curr_incomp.i_data.object)) return NULL;
961+ */
962+
963+ if (-1 == switch_from_incomplete_obj_str_data (& curr_incomp , CJLIB_OBJECT , examine_entry , false)) return NULL ;
923964
924965 if (-1 == cjlib_dict_postorder (curr_incomp .i_pending_data_q , curr_incomp .i_data .object )) return NULL ;
925966 break ;
926967 case CJLIB_ARRAY :
927968 cjlib_stack_push (& curr_incomp , sizeof (struct incomplete_property_str ), & incomplete_st );
928969
929- if (-1 == switch_incomplete_str_data (& curr_incomp , CJLIB_ARRAY , examine_entry )) return NULL ;
970+ if (-1 == switch_from_incomplete_arr_str_data (& curr_incomp , CJLIB_ARRAY , examine_entry_data , curr_incomp . i_key )) return NULL ;
930971
931972 convert_list_to_queue (curr_incomp .i_pending_data_q , curr_incomp .i_data .array );
932973 break ;
0 commit comments