From 8689c95b687552282ac57d5dbd6a19db9770da86 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Mon, 25 Jul 2022 22:56:14 -0400 Subject: [PATCH] Begin work on Json library. Have a working JsonEncode() --- src/Json.c | 345 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 src/Json.c diff --git a/src/Json.c b/src/Json.c new file mode 100644 index 0000000..bcf0278 --- /dev/null +++ b/src/Json.c @@ -0,0 +1,345 @@ +#include + +#include +#include +#include + +struct JsonValue +{ + JsonType type; + union + { + HashMap *object; + Array *array; + char *string; + int64_t integer; + double floating; + int boolean:1; + } as; +}; + +JsonType +JsonValueType(JsonValue * value) +{ + if (!value) + { + return JSON_NULL; + } + + return value->type; +} + +static JsonValue * +JsonValueAllocate(void) +{ + return malloc(sizeof(JsonValue)); +} + +JsonValue * +JsonValueObject(HashMap * object) +{ + JsonValue *value; + + if (!object) + { + return NULL; + } + + value = JsonValueAllocate(); + if (!value) + { + return NULL; + } + + value->type = JSON_OBJECT; + value->as.object = object; + + return value; +} + +HashMap * +JsonValueAsObject(JsonValue * value) +{ + if (!value || value->type != JSON_OBJECT) + { + return NULL; + } + + return value->as.object; +} + + +JsonValue * +JsonValueArray(Array * array) +{ + JsonValue *value; + + if (!array) + { + return NULL; + } + + value = JsonValueAllocate(); + if (!value) + { + return NULL; + } + + value->type = JSON_ARRAY; + value->as.array = array; + + return value; +} + +Array * +JsonValueAsArray(JsonValue * value) +{ + if (!value || value->type != JSON_ARRAY) + { + return NULL; + } + + return value->as.array; +} + + +JsonValue * +JsonValueString(char *string) +{ + JsonValue *value; + + if (!string) + { + return NULL; + } + + value = JsonValueAllocate(); + if (!value) + { + return NULL; + } + + value->type = JSON_STRING; + value->as.string = string; + + return value; +} + +char * +JsonValueAsString(JsonValue * value) +{ + if (!value || value->type != JSON_STRING) + { + return NULL; + } + + return value->as.string; +} + +JsonValue * +JsonValueInteger(int64_t integer) +{ + JsonValue *value; + + value = JsonValueAllocate(); + if (!value) + { + return 0; + } + + value->type = JSON_INTEGER; + value->as.integer = integer; + + return value; +} + +int64_t +JsonValueAsInteger(JsonValue * value) +{ + if (!value || value->type != JSON_INTEGER) + { + return 0; + } + + return value->as.integer; +} + + +JsonValue * +JsonValueFloat(double floating) +{ + JsonValue *value; + + value = JsonValueAllocate(); + if (!value) + { + return NULL; + } + + value->type = JSON_FLOAT; + value->as.floating = floating; + + return value; +} + +double +JsonValueAsFloat(JsonValue * value) +{ + if (!value || value->type != JSON_FLOAT) + { + return 0; + } + + return value->as.floating; +} + +JsonValue * +JsonValueBoolean(int boolean) +{ + JsonValue *value; + + value = JsonValueAllocate(); + if (!value) + { + return NULL; + } + + value->type = JSON_BOOLEAN; + value->as.boolean = boolean; + + return value; +} + +int +JsonValueAsBoolean(JsonValue * value) +{ + if (!value || value->type != JSON_BOOLEAN) + { + return 0; + } + + return value->as.boolean; +} + +JsonValue * +JsonValueNull(void) +{ + JsonValue *value; + + value = JsonValueAllocate(); + if (!value) + { + return NULL; + } + + value->type = JSON_NULL; + + return value; +} + +void +JsonValueFree(JsonValue * value) +{ + if (!value) + { + return; + } + + free(value); +} + +static void +JsonEncodeValue(JsonValue * value, FILE * out) +{ + size_t i; + size_t len; + Array *arr; + + switch (value->type) + { + case JSON_OBJECT: + JsonEncode(value->as.object, out); + break; + case JSON_ARRAY: + arr = value->as.array; + len = ArraySize(arr); + + fputc('[', out); + + for (i = 0; i < len; i++) + { + JsonEncodeValue(ArrayGet(arr, i), out); + if (i < len - 1) + { + fputc(',', out); + } + } + + fputc(']', out); + break; + case JSON_STRING: + fprintf(out, "\"%s\"", value->as.string); + break; + case JSON_INTEGER: + fprintf(out, "%lld", value->as.integer); + break; + case JSON_FLOAT: + fprintf(out, "%f", value->as.floating); + break; + case JSON_BOOLEAN: + if (value->as.boolean) + { + fputs("true", out); + } + else + { + fputs("false", out); + } + break; + case JSON_NULL: + fputs("null", out); + break; + default: + return; + } +} + +int +JsonEncode(HashMap * object, FILE * out) +{ + size_t index; + size_t count; + char *key; + JsonValue *value; + + if (!object || !out) + { + return 0; + } + + count = 0; + while (HashMapIterate(object, &key, (void **) &value)) + { + count++; + } + + fputc('{', out); + + index = 0; + while (HashMapIterate(object, &key, (void **) &value)) + { + fprintf(out, "\"%s\":", key); + JsonEncodeValue(value, out); + + if (index < count - 1) + { + fputc(',', out); + } + + index++; + } + + fputc('}', out); + + return 1; +}