From: Heng Li Date: Sat, 29 Nov 2014 17:59:10 +0000 (-0500) Subject: simplified API a bit X-Git-Url: http://www.kaiwu.me/postgresql/commit/static/gitweb.js?a=commitdiff_plain;h=d5c38b710f4332c8f63718c399c43adf917b45d4;p=klib.git simplified API a bit --- diff --git a/kson.c b/kson.c index 5524f07..38d1c15 100644 --- a/kson.c +++ b/kson.c @@ -4,23 +4,23 @@ #include #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 8cdace0..4e8664c 100644 --- 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 }