performance-aware-programming/haversine_02/src/json/json_entities.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;
}