195 lines
3.9 KiB
C
195 lines
3.9 KiB
C
#include "json/json_entities.h"
|
|
#include "aliases.h"
|
|
#include "json/dstring.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
void print_json(const jentity_t *entity, u32 indent) {
|
|
PERSISTENT i32 indentation = 0;
|
|
|
|
dstr_t *key = NULL;
|
|
const jval_t *value = NULL;
|
|
|
|
if (entity->type == JENTITY_SINGLE) {
|
|
value = &(entity->value);
|
|
} else {
|
|
key = entity->pair.key;
|
|
value = &(entity->pair.value);
|
|
}
|
|
|
|
if (key) {
|
|
printf("%*s\"%s\": ", indentation * indent, "", dstr_to_cstr(key));
|
|
}
|
|
|
|
switch (value->type) {
|
|
case JVAL_COLLECTION: {
|
|
const char *open = "";
|
|
const char *close = "";
|
|
|
|
if (value->collection->type == JCOLL_OBJECT) {
|
|
open = "{";
|
|
close = "}";
|
|
} else {
|
|
open = "[";
|
|
close = "]";
|
|
}
|
|
|
|
if (key) {
|
|
printf("%s\n", open);
|
|
} else {
|
|
printf("%*s%s\n", indentation * indent, "", open);
|
|
}
|
|
|
|
++indentation;
|
|
|
|
if (value->collection->begin) {
|
|
print_json(value->collection->begin, indent);
|
|
}
|
|
|
|
--indentation;
|
|
|
|
printf("\n%*s%s", indentation * indent, "", close);
|
|
|
|
break;
|
|
}
|
|
case JVAL_STRING:
|
|
if (key) {
|
|
printf("\"%s\"", dstr_to_cstr(value->string));
|
|
} else {
|
|
printf("%*s\"%s\"", indentation * indent, "",
|
|
dstr_to_cstr(value->string));
|
|
}
|
|
|
|
break;
|
|
case JVAL_INTEGER:
|
|
if (key) {
|
|
printf("%llu", (unsigned long long)value->num_int);
|
|
} else {
|
|
printf("%*s%llu", indentation * indent, "",
|
|
(unsigned long long)value->num_int);
|
|
}
|
|
|
|
break;
|
|
case JVAL_DOUBLE:
|
|
if (key) {
|
|
printf("%f", value->num_dbl);
|
|
} else {
|
|
printf("%*s%f", indentation * indent, "", value->num_dbl);
|
|
}
|
|
|
|
break;
|
|
case JVAL_BOOLEAN:
|
|
if (key) {
|
|
printf("%s", value->boolean ? "true" : "false");
|
|
} else {
|
|
printf("%*s%s", indentation * indent, "",
|
|
value->boolean ? "true" : "false");
|
|
}
|
|
|
|
break;
|
|
case JVAL_NULL:
|
|
if (key) {
|
|
printf("%s", "null");
|
|
} else {
|
|
printf("%*s%s", indentation * indent, "", "null");
|
|
}
|
|
|
|
break;
|
|
case JVAL_EMPTY:
|
|
break;
|
|
}
|
|
|
|
if (entity->next) {
|
|
printf(",\n");
|
|
print_json(entity->next, indent);
|
|
}
|
|
|
|
// Add newline after printing the entire json tree
|
|
if (indentation == 0 && entity->parent == NULL && entity->next == NULL) {
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
void free_json(jentity_t **entity) {
|
|
if (!(*entity)) {
|
|
return;
|
|
}
|
|
|
|
jentity_t *entt_ptr = *entity;
|
|
|
|
dstr_t *key = NULL;
|
|
const jval_t *value = NULL;
|
|
|
|
if (entt_ptr->type == JENTITY_SINGLE) {
|
|
value = &(entt_ptr->value);
|
|
} else {
|
|
key = entt_ptr->pair.key;
|
|
value = &(entt_ptr->pair.value);
|
|
}
|
|
|
|
if (key) {
|
|
dstr_free(&(entt_ptr->pair.key));
|
|
}
|
|
|
|
switch (value->type) {
|
|
case JVAL_COLLECTION:
|
|
if (value->collection->begin) {
|
|
free_json(&(value->collection->begin));
|
|
}
|
|
|
|
free(value->collection);
|
|
|
|
break;
|
|
case JVAL_STRING:
|
|
dstr_free(&(entt_ptr->pair.value.string));
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (entt_ptr->next) {
|
|
free_json(&(entt_ptr->next));
|
|
}
|
|
|
|
free(*entity);
|
|
*entity = NULL;
|
|
}
|
|
|
|
jcoll_t *get_collection_from_entity(const jentity_t *entity) {
|
|
return entity->type == JENTITY_SINGLE ? entity->value.collection
|
|
: entity->pair.value.collection;
|
|
}
|
|
|
|
jentity_t *create_new_single_entity(const jval_t value, jentity_t *parent) {
|
|
jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t));
|
|
|
|
if (!entity) {
|
|
return NULL;
|
|
}
|
|
|
|
entity->type = JENTITY_SINGLE;
|
|
entity->value = value;
|
|
entity->parent = parent;
|
|
entity->next = NULL;
|
|
|
|
return entity;
|
|
}
|
|
|
|
jentity_t *create_new_pair_entity(dstr_t *key, const jval_t value,
|
|
jentity_t *parent) {
|
|
jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t));
|
|
|
|
if (!entity) {
|
|
return NULL;
|
|
}
|
|
|
|
entity->type = JENTITY_PAIR;
|
|
entity->pair.key = key;
|
|
entity->pair.value = value;
|
|
entity->parent = parent;
|
|
entity->next = NULL;
|
|
|
|
return entity;
|
|
}
|