Skip to content

Commit b860495

Browse files
committed
Implement again the traversal used in cljib.c for the strintifying process
1 parent 0d40335 commit b860495

File tree

3 files changed

+39
-49
lines changed

3 files changed

+39
-49
lines changed

src/cjlib.c

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ static char *simple_key_value_paired_stringtify
812812
*/
813813
static inline int switch_from_incomplete_obj_str_data
814814
(struct incomplete_property_str *restrict dst, enum cjlib_json_datatypes type,
815-
cjlib_json_object *entry, bool init)
815+
cjlib_json_object *entry)
816816
{
817817
struct cjlib_json_data *examine_entry_data = CJLIB_DICT_NODE_DATA(entry);
818818
*dst = (struct incomplete_property_str) {
@@ -826,12 +826,8 @@ static inline int switch_from_incomplete_obj_str_data
826826

827827
cjlib_queue_init(dst->i_pending_data_q);
828828

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-
}
829+
if (CJLIB_OBJECT == type) dst->i_data.object = entry;
830+
else dst->i_data.array = examine_entry_data->c_value.c_arr;
835831

836832
return 0;
837833
}
@@ -899,9 +895,9 @@ const char *cjlib_json_object_stringtify(const cjlib_json_object *src)
899895
incomplete_property_str_init(&curr_incomp);
900896
cjlib_stack_init(&incomplete_st);
901897

902-
if (-1 == switch_from_incomplete_obj_str_data(&curr_incomp, CJLIB_OBJECT, (cjlib_json_object *) src, true)) return NULL;
898+
if (-1 == switch_from_incomplete_obj_str_data(&curr_incomp, CJLIB_OBJECT, (cjlib_json_object *) src)) return NULL;
903899

904-
if (-1 == cjlib_dict_postorder(curr_incomp.i_pending_data_q, curr_incomp.i_data.object)) return NULL;
900+
if (-1 == cjlib_dict_preorder(curr_incomp.i_pending_data_q, curr_incomp.i_data.object)) return NULL;
905901

906902
// Put a dummy entry in the stack to start the process.
907903
if (-1 == cjlib_stack_push((void *) &curr_incomp, sizeof(struct incomplete_property_str),
@@ -944,25 +940,10 @@ const char *cjlib_json_object_stringtify(const cjlib_json_object *src)
944940
cjlib_stack_push(&curr_incomp, sizeof(struct incomplete_property_str),
945941
&incomplete_st);
946942

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;
943+
if (CJLIB_ARRAY == curr_incomp.i_type) examine_entry = examine_entry_data->c_value.c_obj;
944+
if (-1 == switch_from_incomplete_obj_str_data(&curr_incomp, CJLIB_OBJECT, examine_entry)) return NULL;
964945

965-
if (-1 == cjlib_dict_postorder(curr_incomp.i_pending_data_q, curr_incomp.i_data.object)) return NULL;
946+
if (-1 == cjlib_dict_preorder(curr_incomp.i_pending_data_q, curr_incomp.i_data.object)) return NULL;
966947
break;
967948
case CJLIB_ARRAY:
968949
cjlib_stack_push(&curr_incomp, sizeof(struct incomplete_property_str), &incomplete_st);
@@ -999,6 +980,7 @@ const char *cjlib_json_object_stringtify(const cjlib_json_object *src)
999980
}
1000981

1001982
free(curr_incomp.i_key);
983+
1002984
// Return the now completed JSON.
1003985
return curr_incomp.i_state;
1004986
}

src/cjlib_dictionary.c

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "cjlib_dictionary.h"
3333
#include "cjlib.h"
3434
#include "cjlib_queue.h"
35+
#include "cjlib_stack.h"
3536

3637
// Those constants are used in the search/insert/delete functions.
3738
#define S_RETRIEVE_KEY_NODE (0x0)
@@ -99,37 +100,44 @@ enum rotation_after_left_deletion_type
99100
/**
100101
* Set every node of a AVL tree into a QEUEUE
101102
*/
102-
int cjlib_dict_postorder(struct cjlib_queue *restrict dst, const struct avl_bs_tree_node *src)
103+
int cjlib_dict_preorder(struct cjlib_queue *restrict dst, const struct avl_bs_tree_node *src)
103104
{
104-
struct cjlib_queue post_order_node_q; // The queue used for the post order traversal.
105-
struct cjlib_queue post_order_data_q;
106-
cjlib_queue_init(&post_order_node_q);
107-
cjlib_queue_init(&post_order_data_q);
105+
struct cjlib_stack pre_order_traversal_st; // The stack used for the preorder traversal.
106+
struct cjlib_queue pre_order_data_q;
107+
cjlib_stack_init(&pre_order_traversal_st);
108+
cjlib_queue_init(&pre_order_data_q);
108109

109110
struct avl_bs_tree_node *root = (struct avl_bs_tree_node *) src; // Set the root of the whole tree in the local variable.
110111

112+
// 1. PROCESS ROOT -> 2. VISIT LEFT SUBTREE -> 3. VISIT RIGHT SUBTREE -> GO TO (1.)
111113
do {
112114
if (NULL != root) {
113-
if (-1 == cjlib_queue_enqeue((void *) &root, sizeof(struct cjlib_json_data *), &post_order_data_q)) return -1;
114-
}
115-
116-
if (NULL != root && NULL != root->avl_left) {
117-
if (-1 == cjlib_queue_enqeue((void *) &root, sizeof(struct avl_bs_tree_node *), &post_order_node_q)) return -1;
118-
}
119-
120-
if (NULL != root->avl_right) {
121-
if (-1 == cjlib_queue_enqeue((void *) &root->avl_right, sizeof(struct avl_bs_tree_node *), &post_order_node_q)) return -1;
115+
// Process the current Root before left or right sub tree.
116+
// 1. Process.
117+
if (-1 == cjlib_queue_enqeue(&root, sizeof(struct avl_bs_tree_node *), &pre_order_data_q)) return -1;
122118
}
123119

124-
if (NULL != root->avl_left) {
125-
root = src->avl_left;
120+
// Check the next node to process is available.
121+
if (NULL == root) {
122+
// Check if this is the last node.
123+
if (cjlib_stack_is_empty(&pre_order_traversal_st)) break;
124+
125+
// Reached a leaf (either left or right), go to the parent node.
126+
// 3. VISIT RIGHT SUBTREE.
127+
if (-1 == cjlib_stack_pop(&root, sizeof(struct avl_bs_tree_node *), &pre_order_traversal_st)) return -1;
128+
129+
// After reaching a left leaf, then go to the right subtree of the leaf's parent.
130+
root = root->avl_right;
126131
} else {
127-
cjlib_queue_deqeue(&root, sizeof(struct avl_bs_tree_node *), &post_order_node_q);
128-
break;
132+
// 2. VISIT LEFT SUBTREE.
133+
if (-1 == cjlib_stack_push(&root, sizeof(struct avl_bs_tree_node *), &pre_order_traversal_st)) return -1;
134+
// Proceed to the next left tree, untill reaching a leaf (next left is null).
135+
root = root->avl_left;
129136
}
130-
} while(!cjlib_queue_is_empty(&post_order_node_q));
137+
138+
} while(!cjlib_stack_is_empty(&pre_order_traversal_st));
131139

132-
(void) memcpy(dst, &post_order_data_q, sizeof(struct cjlib_queue));
140+
(void) memcpy(dst, &pre_order_data_q, sizeof(struct cjlib_stack));
133141

134142
return 0;
135143
}

src/include/cjlib_dictionary.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ static inline cjlib_dict_t *cjlib_make_dict(void)
7272
}
7373

7474
/**
75-
* Travel through the whole tree using the POST-ORDER method. This function builds a
75+
* Travel through the whole tree using the PRE-ORDER method. This function builds a
7676
* queue that consists of all the available nodes in the dictionary of interest.
7777
*
7878
* @param dst A pointer pointing to the memory where the built queue is stored.
7979
* @param src A pointer to the dictionary (or object) of interest.
8080
* @return -1 in case an error occur, otherwise -1.
8181
*/
82-
extern int cjlib_dict_postorder(struct cjlib_queue *restrict dst, const cjlib_dict_t *src);
82+
extern int cjlib_dict_preorder(struct cjlib_queue *restrict dst, const cjlib_dict_t *src);
8383

8484
/**
8585
* Searches for an element in a dictionary based on its associated key.

0 commit comments

Comments
 (0)