132 lines
2.4 KiB
C
132 lines
2.4 KiB
C
|
|
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
|
|
#include "s8slice.h"
|
|
|
|
struct json {
|
|
struct json_value* root;
|
|
struct json_value** ctx;
|
|
S8Slice pending_key;
|
|
bool has_pending_key;
|
|
};
|
|
|
|
struct json_value {
|
|
S8Slice key;
|
|
struct json_value* next;
|
|
|
|
enum {
|
|
JSON_OBJECT,
|
|
JSON_ARRAY,
|
|
JSON_NUMBER,
|
|
JSON_STRING,
|
|
JSON_BOOL,
|
|
JSON_NULL,
|
|
} kind;
|
|
|
|
union {
|
|
double number;
|
|
S8Slice string;
|
|
bool boolean;
|
|
struct json_value* object_head;
|
|
struct json_value* array_head;
|
|
};
|
|
};
|
|
|
|
static struct json_value* new_value(struct json* j)
|
|
{
|
|
struct json_value* new = calloc(1, sizeof(struct json_value));
|
|
if (!new) {
|
|
perror("calloc");
|
|
abort();
|
|
}
|
|
return new;
|
|
}
|
|
|
|
void json_init(struct json* j)
|
|
{
|
|
j->ctx = &j->root;
|
|
}
|
|
|
|
void json_add_key(struct json* j, S8Slice key)
|
|
{
|
|
j->has_pending_key = true;
|
|
j->pending_key = key;
|
|
}
|
|
|
|
void json_add_value(struct json* j, struct json_value* new)
|
|
{
|
|
*j->ctx = new;
|
|
j->ctx = &new->next;
|
|
/*
|
|
if (j->has_pending_key) {
|
|
new->key = j->pending_key;
|
|
j->has_pending_key = false;
|
|
}
|
|
*/
|
|
}
|
|
|
|
void json_add_object(struct json* j)
|
|
{
|
|
struct json_value* new = new_value(j);
|
|
new->kind = JSON_OBJECT;
|
|
json_add_value(j, new);
|
|
j->ctx = &new->object_head;
|
|
}
|
|
|
|
void json_add_number(struct json* j, double n)
|
|
{
|
|
struct json_value* new = new_value(j);
|
|
new->kind = JSON_NUMBER;
|
|
new->number = n;
|
|
json_add_value(j, new);
|
|
}
|
|
|
|
void json_print_value(struct json_value* val, int depth)
|
|
{
|
|
if (!val) {
|
|
return;
|
|
}
|
|
for (int i = 0; i < depth; i++) {
|
|
printf(" ");
|
|
}
|
|
switch (val->kind) {
|
|
case JSON_NUMBER: {
|
|
printf("%lf,\n", val->number);
|
|
json_print_value(val->next, depth);
|
|
} break;
|
|
|
|
case JSON_OBJECT: {
|
|
json_print_value(val->object_head, depth+1);
|
|
} break;
|
|
|
|
default: {
|
|
fprintf(stderr, "not implemented");
|
|
abort();
|
|
} break;
|
|
}
|
|
}
|
|
|
|
void json_print(struct json* j)
|
|
{
|
|
json_print_value(j->root, 0);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
struct json j = {0};
|
|
json_init(&j);
|
|
|
|
json_add_number(&j, 53);
|
|
|
|
json_add_object(&j);
|
|
|
|
json_add_number(&j, 12);
|
|
|
|
json_print(&j);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|