]> git.kaiwu.me - klib.git/commitdiff
simplified API a bit
authorHeng Li <lh3@me.com>
Sat, 29 Nov 2014 17:59:10 +0000 (12:59 -0500)
committerHeng Li <lh3@me.com>
Sat, 29 Nov 2014 17:59:10 +0000 (12:59 -0500)
kson.c
kson.h

diff --git a/kson.c b/kson.c
index 5524f079338179d5cfb8bba3a1840de8c5e0016b..38d1c154d1ceea71da633a19c23fe3919c572306 100644 (file)
--- a/kson.c
+++ b/kson.c
@@ -4,23 +4,23 @@
 #include <stdio.h>
 #include "kson.h"
 
-kson_node_t *kson_parse(const char *json, int *_n, int *error, int *parsed_len)
+kson_node_t *kson_parse_core(const char *json, long *_n, int *error, long *parsed_len)
 {
-       int *stack = 0, top = 0, max = 0, n_a = 0, m_a = 0;
+       long *stack = 0, top = 0, max = 0, n_a = 0, m_a = 0;
        kson_node_t *a = 0, *u;
        const char *p, *q;
 
 #define __push_back(y) do { \
                if (top == max) { \
                        max = max? max<<1 : 4; \
-                       stack = (int*)realloc(stack, sizeof(int) * max); \
+                       stack = (long*)realloc(stack, sizeof(long) * max); \
                } \
                stack[top++] = (y); \
        } while (0)
 
 #define __new_node(z) do { \
                if (n_a == m_a) { \
-                       int old_m = m_a; \
+                       long old_m = m_a; \
                        m_a = m_a? m_a<<1 : 4; \
                        a = (kson_node_t*)realloc(a, sizeof(kson_node_t) * m_a); \
                        memset(a + old_m, 0, sizeof(kson_node_t) * (m_a - old_m)); \
@@ -28,6 +28,7 @@ kson_node_t *kson_parse(const char *json, int *_n, int *error, int *parsed_len)
                *(z) = &a[n_a++]; \
        } while (0)
 
+       *error = KSON_OK;
        for (p = json; *p; ++p) {
                while (*p && isblank(*p)) ++p;
                if (*p == 0) break;
@@ -40,7 +41,7 @@ kson_node_t *kson_parse(const char *json, int *_n, int *error, int *parsed_len)
                                __push_back(t);
                        } else stack[top-1] = t; // named internal node
                } else if (*p == ']' || *p == '}') {
-                       int i, start, t = *p == ']'? -1 : -2;
+                       long i, start, t = *p == ']'? -1 : -2;
                        for (i = top - 1; i >= 0 && stack[i] != t; --i);
                        if (i < 0) { // error: an extra right bracket
                                *error = KSON_ERR_EXTRA_RIGHT;
@@ -50,7 +51,7 @@ kson_node_t *kson_parse(const char *json, int *_n, int *error, int *parsed_len)
                        u = &a[stack[start-1]];
                        u->key = u->v.str;
                        u->n = top - 1 - start;
-                       u->v.child = (int*)malloc(u->n * sizeof(int));
+                       u->v.child = (long*)malloc(u->n * sizeof(long));
                        for (i = start + 1; i < top; ++i)
                                u->v.child[i - start - 1] = stack[i];
                        u->type = *p == ']'? KSON_TYPE_BRACKET : KSON_TYPE_BRACE;
@@ -94,13 +95,27 @@ kson_node_t *kson_parse(const char *json, int *_n, int *error, int *parsed_len)
        return a;
 }
 
-void kson_destroy(int n_nodes, kson_node_t *nodes)
+void kson_destroy(kson_t *kson)
 {
-       int i;
-       for (i = 0; i < n_nodes; ++i) {
-               free(nodes[i].key); free(nodes[i].v.str);
+       if (kson) {
+               long i;
+               for (i = 0; i < kson->n_nodes; ++i) {
+                       free(kson->nodes[i].key); free(kson->nodes[i].v.str);
+               }
+               free(kson->nodes); free(kson);
+       }
+}
+
+kson_t *kson_parse(const char *json, int *error)
+{
+       kson_t *ks;
+       ks = (kson_t*)calloc(1, sizeof(kson_t));
+       ks->nodes = kson_parse_core(json, &ks->n_nodes, error, 0);
+       if (*error) {
+               kson_destroy(ks);
+               return 0;
        }
-       free(nodes);
+       return ks;
 }
 
 void kson_print_recur(kson_node_t *nodes, kson_node_t *p)
@@ -110,9 +125,9 @@ void kson_print_recur(kson_node_t *nodes, kson_node_t *p)
                if (p->v.str) putchar(':');
        }
        if (p->type == KSON_TYPE_BRACKET || p->type == KSON_TYPE_BRACE) {
-               int i;
+               long i;
                putchar(p->type == KSON_TYPE_BRACKET? '[' : '{');
-               for (i = 0; i < p->n; ++i) {
+               for (i = 0; i < (long)p->n; ++i) {
                        if (i) putchar(',');
                        kson_print_recur(nodes, &nodes[p->v.child[i]]);
                }
@@ -126,19 +141,24 @@ void kson_print_recur(kson_node_t *nodes, kson_node_t *p)
        }
 }
 
+void kson_print(kson_t *kson)
+{
+       kson_print_recur(kson->nodes, kson->nodes);
+}
+
 #ifdef KSON_MAIN
 int main(int argc, char *argv[])
 {
-       kson_node_t *nodes;
-       int n_nodes, error, parsed_len;
-       nodes = kson_parse("{'a' : 1, 'b':[0,'isn\\'t',true],'d':[{}]}", &n_nodes, &error, &parsed_len);
+       kson_t *kson;
+       int error;
+       kson = kson_parse("{'a' : 1, 'b':[0,'isn\\'t',true],'d':[{}]}", &error);
        if (error == 0) {
-               kson_print_recur(nodes, &nodes[0]);
+               kson_print(kson);
                putchar('\n');
        } else {
                printf("Error code: %d\n", error);
        }
-       kson_destroy(n_nodes, nodes);
+       kson_destroy(kson);
        return 0;
 }
 #endif
diff --git a/kson.h b/kson.h
index 8cdace0ff9af7808b9e967fe2555f9a408a74a29..4e8664c25a35241dcd47c64d7eec8e9637b4e089 100644 (file)
--- a/kson.h
+++ b/kson.h
@@ -18,17 +18,22 @@ typedef struct {
        uint64_t type:3, n:61;
        char *key;
        union {
-               int *child;
+               long *child;
                char *str;
        } v;
 } kson_node_t;
 
+typedef struct {
+       long n_nodes;
+       kson_node_t *nodes;
+} kson_t;
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
        /**
-        * Parse a JSON string
+        * Parse a JSON string into nodes
         *
         * @param json        JSON string
         * @param n_nodes     number of nodes
@@ -37,11 +42,13 @@ extern "C" {
         *
         * @return An array of size $n_nodes keeping parsed nodes
         */
-       kson_node_t *kson_parse(const char *json, int *n_nodes, int *error, int *parsed_len);
+       kson_node_t *kson_parse_core(const char *json, long *n_nodes, int *error, long *parsed_len);
 
-       void kson_destroy(int n_nodes, kson_node_t *nodes);
+       // Equivalent to: { kson->nodes = kson_parse_core(json, &kson->n_nodes, &error, 0); return *error? 0 : kson; } 
+       kson_t *kson_parse(const char *json, int *error);
 
-       void kson_print_recur(kson_node_t *nodes, kson_node_t *root);
+       void kson_destroy(kson_t *ks);
+       void kson_print(kson_t *kson);
 
 #ifdef __cplusplus
 }