summaryrefslogtreecommitdiff
path: root/src/text.c
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2019-08-03 12:10:09 +0300
committerOxore <oxore@protonmail.com>2019-08-03 22:14:38 +0300
commit9144dbb427f8f71b1ef146c7fdb42b2570f94cb6 (patch)
tree83992871ca9fc3875559b47df9003bdd883e1e79 /src/text.c
parent6161ec503292d00e83674ee8bba179e5e8ea0b4b (diff)
Implement json parser for texts
Diffstat (limited to 'src/text.c')
-rw-r--r--src/text.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/text.c b/src/text.c
index 9bace21..4674a7e 100644
--- a/src/text.c
+++ b/src/text.c
@@ -1,13 +1,149 @@
#include <f8.h>
#include <stdio.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <yaml.h>
+#include <cJSON.h>
#include "idlist.h"
#include "vector.h"
#include "text.h"
+static char *load_data_from_file(const char *filename)
+{
+ int ret = 0;
+ FILE *file = NULL;
+ char *data = NULL;
+
+ file = fopen(filename, "rb");
+ if (file == NULL) {
+ perror(filename);
+ return NULL;
+ }
+
+ ret |= fseek(file, 0, SEEK_END);
+ long file_size = ftell(file);
+ ret |= fseek(file, 0, SEEK_SET);
+ if (ret == -1 || file_size == -1) {
+ perror("fseek/ftell");
+ goto cleanup_close;
+ }
+
+ data = calloc(file_size + 1, sizeof(char));
+ if (data == NULL) {
+ perror("calloc");
+ goto cleanup_close;
+ }
+
+ size_t nbyte = fread(data, sizeof(char), file_size, file);
+ if (nbyte == 0) {
+ perror("fread");
+ goto cleanup_free;
+ }
+
+ goto cleanup_close;
+
+cleanup_free:
+ free(data);
+ data = NULL;
+
+cleanup_close:
+ fclose(file);
+ return data;
+}
+
+static char *texts_cjson_get_string(cJSON *object, const char *key)
+{
+ char *string = NULL;
+ cJSON *item = cJSON_GetObjectItem(object, key);
+ if (cJSON_IsString(item)) {
+ char *value = cJSON_GetStringValue(item);
+ if (value != NULL) {
+ size_t size = strlen(value) + 1;
+ string = calloc(size, sizeof(char));
+ if (string != NULL)
+ strncpy(string, value, size);
+ }
+ }
+ return string;
+}
+
+static wchar_t *texts_cjson_get_string_utf32(cJSON *object, const char *key)
+{
+ wchar_t *string = NULL;
+ cJSON *item = cJSON_GetObjectItem(object, key);
+ if (cJSON_IsString(item)) {
+ char *value = cJSON_GetStringValue(item);
+ if (value != NULL) {
+ size_t size = utf8_strlen(value) + 1;
+ string = calloc(size, sizeof(wchar_t));
+ if (string != NULL)
+ utf8to32_strcpy(string, value);
+ }
+ }
+ return string;
+}
+
+static int texts_cjson_get_int(cJSON *object, const char *key)
+{
+ int value = 0;
+ cJSON *item = cJSON_GetObjectItem(object, key);
+ if (cJSON_IsNumber(item))
+ value = item->valueint;
+ return value;
+}
+
+struct idlist *load_texts_from_json(const char *filename)
+{
+ struct cJSON_Hooks hooks = (struct cJSON_Hooks){
+ .malloc_fn = malloc,
+ .free_fn = free,
+ };
+ cJSON_InitHooks(&hooks);
+
+ char *data = load_data_from_file(filename);
+ if (data == NULL) {
+ return NULL;
+ }
+
+ struct idlist *texts = NULL;
+ struct idlist *texts_node = texts;
+
+ cJSON *json_data = cJSON_Parse(data);
+ if (cJSON_IsArray(json_data)) {
+ size_t array_size = cJSON_GetArraySize(json_data);
+ for (size_t i = 0; i < array_size; i++) {
+ cJSON *item = cJSON_GetArrayItem(json_data, i);
+ if (cJSON_IsObject(item)) {
+
+ /* Allocate texts node to be filled */
+
+ if (!texts) {
+ texts_node = texts = list_new();
+ } else {
+ texts_node = list_append(texts);
+ }
+ texts_node->obj = calloc(1, sizeof(struct text));
+ struct text *text = texts_node->obj;
+
+ /* Fill the node */
+
+ text->type = texts_cjson_get_string(item, "type");
+ text->scene = texts_cjson_get_string(item, "scene");
+ text->text = texts_cjson_get_string_utf32(item, "text");
+ text->font = texts_cjson_get_string(item, "font");
+ text->size = texts_cjson_get_int(item, "size");
+ text->pos.x = texts_cjson_get_int(item, "x");
+ text->pos.y = texts_cjson_get_int(item, "y");
+ }
+ }
+ }
+ free(data);
+ cJSON_Delete(json_data);
+ return texts;
+}
+
static FILE *openFile(char *filename)
{
FILE *file;