aboutsummaryrefslogtreecommitdiff
path: root/lib/dtree_utils.c
blob: 082ece3d87bb3d4ce25c1c9b11c350fc5ce6e7ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <dtree/dtree.h>
#include <stdio.h>
#include <stdlib.h>

void pk_string_trim(char *src, char *dst);

dt_err dtree_decode_json(dtree *(*data), const char *json_data)
{
    enum parse_state {
        VALUE, HASH, LIST, WAITING
    };

#define BUF_SIZE 256

    /* Save some space for a token */
    const char *delims = ",:";

    char *parse;
    char curr_key[BUF_SIZE];
    char curr_val[BUF_SIZE];
    dtree *root, *curr_root;
    enum parse_state state = WAITING;

    /* Prepare environment for parsing */
    char json_buf[REAL_STRLEN(json_data)];
    strcpy(json_buf, json_data);

    /* Setup root dtree node */
    dtree_malloc(&root);
    curr_root = root;

    /* Read in the first token */
    parse = strtok(json_buf, delims);

    while(parse != NULL) {

        char tok[strlen(parse) + 1];
        memset(tok, 0, strlen(parse) + 1);

        pk_string_trim(parse, tok);

        /* Open a new hash context */
        if(tok[0] == '{') {

            dtree *new_root;
            dtree_addlist(curr_root, &new_root);

            curr_root = new_root;

            printf("Creating new hash context...\n");
            state = HASH;
        }

        /* Open a new list context - finishing a PAIR - Back to waiting */
        if(tok[0] == '[') {
            printf("Creating new hash context...\n");
            state = LIST;
        }

        /* If we're in a hash & waiting for a key */
        if(state == HASH) {
            if(tok[0] == '{')   strcpy(curr_key, tok + 1);
            else                strcpy(curr_key, tok);

            printf("Current Key: %s\n", curr_key);
            state = VALUE;
            goto END;
        }

        /* We already had a key - finishing up the pair */
        if(state == VALUE) {
            strcpy(curr_val, tok);
            printf("Current Val: %s\n", curr_val);

            /* Copy pair into dtree structure */
            dtree *parent, *key, *val;
            dtree_addlist(curr_root, &parent);

            /* Make the "parent" node into the pair parent */
            dtree_addpair(parent, &key, &val);
            dtree_addliteral(key, curr_key);
            dtree_addliteral(val, curr_val);

            /* Add the parent */

            /* Blank current pair data */
            memset(curr_key, 0, BUF_SIZE);
            memset(curr_val, 0, BUF_SIZE);

            state = HASH;
            goto END;
        }

        if(state == LIST) {
            dtree *child;
            dtree_addlist(curr_root, &child);
            dtree_addliteral(child, tok);

            size_t chs = strlen(tok);
            dtree *parent;

            dtree_parent(root, curr_root, &parent);
            if(tok[chs] == ']') {
                curr_root = parent;
                state = HASH;
            }
        }

        printf("      Recognised token: %s\n", tok);
    END:
        parse = strtok(NULL, delims);
    }

    return SUCCESS;
}


/************************************************************/

void pk_string_trim(char *src, char *dst)
{
    int s, d=0;
    for (s=0; src[s] != 0; s++)
        if (src[s] != ' ') {
            dst[d] = src[s];
            d++;
        }
    dst[d] = 0;
}