WIP
This commit is contained in:
131
json.c
Normal file
131
json.c
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user