diff --git a/gaiji.c b/gaiji.c index 0fb76e9..451133e 100644 --- a/gaiji.c +++ b/gaiji.c @@ -21,6 +21,8 @@ #include #include +#include "jansson/include/jansson.h" + #include "util.h" #include "gaiji.h" @@ -117,6 +119,67 @@ static void encode_sequence(char output[], int size, const char utf8[]) { strncat(output, "}", size); } +static void parse_entry(Gaiji_Entry* entry, const json_t* entry_json) { + entry->code = json_integer_value(json_array_get(entry_json, 0)); + const char* utf8 = json_string_value(json_array_get(entry_json, 1)); + if (utf8 == NULL) { + *entry->utf8 = 0; + } + else { + strncpy(entry->utf8, utf8, ARRSIZE(entry->utf8)); + entry->utf8[ARRSIZE(entry->utf8) - 1] = 0; + } +} + +static void parse_entries(Gaiji_Entry** entries, int* count, const json_t* entry_array_json) { + *count = json_array_size(entry_array_json); + if (*count == 0) { + *entries = NULL; + } + else { + *entries = malloc(sizeof(Gaiji_Entry) * *count); + for (int i = 0; i < *count; ++i) { + parse_entry(*entries + i, json_array_get(entry_array_json, i)); + } + } +} + +static void parse_table(Gaiji_Table* table, const json_t* table_json) { + const char* name = json_string_value(json_object_get(table_json, "name")); + if (name == NULL) { + *table->name = 0; + } + else { + strncpy(table->name, name, ARRSIZE(table->name)); + table->name[ARRSIZE(table->name) - 1] = 0; + } + + parse_entries( + (Gaiji_Entry**)&table->table_wide, + &table->count_wide, + json_object_get(table_json, "wide") + ); + + parse_entries( + (Gaiji_Entry**)&table->table_narrow, + &table->count_narrow, + json_object_get(table_json, "narrow") + ); +} + +static void parse_table_array(Gaiji_Context* context, const json_t* table_array_json) { + context->count = json_array_size(table_array_json); + if (context->count == 0) { + context->tables = NULL; + } + else { + context->tables = malloc(sizeof(Gaiji_Table) * context->count); + for (int i = 0; i < context->count; ++i) { + parse_table(context->tables + i, json_array_get(table_array_json, i)); + } + } +} + /* * Exported functions */ @@ -210,13 +273,25 @@ void gaiji_stub_decode(char output[], int size, const char input[]) { } bool gaiji_context_init(Gaiji_Context* context, const char path[]) { - (void)path; - context->count = 0; - context->tables = NULL; + json_t* table_array_json = json_load_file(path, 0, NULL); + if (table_array_json == NULL) { + context->count = 0; + context->tables = NULL; + return false; + } + + parse_table_array(context, table_array_json); + json_decref(table_array_json); return true; } void gaiji_context_destroy(Gaiji_Context* context) { + for (int i = 0; i < context->count; ++i) { + Gaiji_Table* table = context->tables + i; + free((Gaiji_Entry*)table->table_wide); + free((Gaiji_Entry*)table->table_narrow); + } + free(context->tables); context->tables = NULL; context->count = 0; diff --git a/gaiji.h b/gaiji.h index 668f1ea..4bde9e7 100644 --- a/gaiji.h +++ b/gaiji.h @@ -25,9 +25,8 @@ * Constants */ -#define MAX_UTF8_BYTES 9 +#define MAX_UTF8_BYTES 10 #define MAX_STUB_BYTES 32 -#define MAX_TABLE_NAME 256 /* * Types @@ -39,7 +38,7 @@ typedef struct { } Gaiji_Entry; typedef struct { - char name[MAX_TABLE_NAME]; + char name[256]; const Gaiji_Entry* table_wide; int count_wide; const Gaiji_Entry* table_narrow;