diff --git a/externals/jsmn/jsmn.h b/externals/jsmn/jsmn.h index 05338ec3..9fa482be 100644 --- a/externals/jsmn/jsmn.h +++ b/externals/jsmn/jsmn.h @@ -4,8 +4,8 @@ #include // APPLE2IX : define these ... -#define JSMN_PARENT_LINKS -#define JSMN_STRICT +#define JSMN_PARENT_LINKS 1 +#define JSMN_STRICT 1 #ifdef __cplusplus extern "C" { diff --git a/src/json_parse.c b/src/json_parse.c index 475c764a..45e1cf8a 100644 --- a/src/json_parse.c +++ b/src/json_parse.c @@ -5,21 +5,174 @@ * version 3 or later (your choice) as published by the Free Software * Foundation. * - * Copyright 2013-2015 Aaron Culliney + * Copyright 2015-2016 Aaron Culliney * */ -#include "json_parse.h" +#include "common.h" +#include "json_parse_private.h" #define JSON_LENGTH 16 #define DEFAULT_NUMTOK 16 +#define MAX_INDENT 16 -static int _json_createFromString(const char *jsonString, INOUT JSON_s *parsedData, ssize_t jsonLen) { + +static bool _json_write(const char *jsonString, size_t buflen, int fd) { + ssize_t idx = 0; + size_t chunk = buflen; + do { + ssize_t outlen = 0; + TEMP_FAILURE_RETRY(outlen = write(fd, jsonString+idx, chunk)); + if (outlen <= 0) { + break; + } + idx += outlen; + chunk -= outlen; + } while (idx < buflen); + return idx == buflen; +} + +// recursive +static bool _json_prettyPrint(JSON_s *parsedData, int start, int end, const unsigned int indent, int fd) { + + char indentBuf[MAX_INDENT+1]; + indentBuf[MAX_INDENT] = '\0'; + + bool success = false; + do { + if (indent > MAX_INDENT) { + break; + } + memset(indentBuf, '\t', indent); + + jsmntok_t parent = { -1 }; + int idx = start; + if (idx < end) { + jsmntok_t tok = parsedData->jsonTokens[idx]; + if (tok.parent >= 0) { + parent = parsedData->jsonTokens[tok.parent]; + } + } + + bool isKey = true; + + while (idx < end) { + + jsmntok_t tok = parsedData->jsonTokens[idx]; + bool isFirst = (idx == start); + + // print finishing ", \n" stuff ... + if (parent.type == JSMN_OBJECT) { + if (!isKey) { + if (!_json_write(" : ", 3, fd)) { + break; + } + } else { + if (!isFirst) { + if (!_json_write(",\n", 2, fd)) { + break; + } + } + if (!_json_write(indentBuf, indent, fd)) { + break; + } + } + } else if (parent.type == JSMN_ARRAY) { + if (!isFirst) { + if (!_json_write(", ", 2, fd)) { + break; + } + } + } + + jsmntype_t type = parsedData->jsonTokens[idx].type; + + if (type == JSMN_PRIMITIVE) { + char lastChar = parsedData->jsonString[tok.end]; + parsedData->jsonString[tok.end] = '\0'; + if (!_json_write(&parsedData->jsonString[tok.start], tok.end-tok.start, fd)) { + break; + } + parsedData->jsonString[tok.end] = lastChar; + ++idx; + } else if (type == JSMN_STRING) { + char lastChar = parsedData->jsonString[tok.end]; + parsedData->jsonString[tok.end] = '\0'; + if (!_json_write("\"", 1, fd)) { + break; + } + if (!_json_write(&parsedData->jsonString[tok.start], tok.end-tok.start, fd)) { + break; + } + if (!_json_write("\"", 1, fd)) { + break; + } + parsedData->jsonString[tok.end] = lastChar; + ++idx; + } else if (type == JSMN_OBJECT) { + if (!_json_write("{\n", 2, fd)) { + break; + } + if (!_json_prettyPrint(parsedData, idx+1, idx+tok.skip, indent+1, fd)) { + break; + } + if (!_json_write(indentBuf, indent, fd)) { + break; + } + if (!_json_write("}", 1, fd)) { + break; + } + idx += tok.skip; + } else if (type == JSMN_ARRAY) { + if (!_json_write("[ ", 2, fd)) { + break; + } + if (!_json_prettyPrint(parsedData, idx+1, idx+tok.skip, indent+1, fd)) { + break; + } + if (!_json_write(" ]", 2, fd)) { + break; + } + idx += tok.skip; + } else { + assert(false); + } + + isKey = !isKey; + } + + if (idx != end) { + break; + } + + if (parent.type != JSMN_ARRAY) { + if (!_json_write("\n", 1, fd)) { + break; + } + } + + success = true; + } while (0); + + return success; +} + +static int _json_createFromString(const char *jsonString, INOUT JSON_ref *jsonRef, ssize_t jsonLen) { jsmnerr_t errCount = JSMN_ERROR_NOMEM; do { jsmn_parser parser = { 0 }; + if (!jsonRef) { + break; + } + + JSON_s *parsedData = MALLOC(sizeof(*parsedData)); + if (!parsedData) { + break; + } + *jsonRef = parsedData; + if (!parsedData) { break; } @@ -73,38 +226,29 @@ static int _json_createFromString(const char *jsonString, INOUT JSON_s *parsedDa } parsedData->numTokens = errCount; + parsedData->jsonLen = jsonLen; } while (0); if (errCount < 0) { - if (parsedData) { - json_destroy(parsedData); + if (*jsonRef) { + json_destroy(jsonRef); } } return errCount; } -int json_createFromFile(const char *filePath, INOUT JSON_s *parsedData) { +int json_createFromFD(int fd, INOUT JSON_ref *jsonRef) { - int fd = -1; ssize_t jsonIdx = 0; ssize_t jsonLen = 0; char *jsonString = NULL; + jsmnerr_t errCount = JSMN_ERROR_NOMEM; do { - if (!filePath) { - break; - } - - if (!parsedData) { - break; - } - - TEMP_FAILURE_RETRY(fd = open(filePath, O_RDONLY)); - if (fd < 0) { - ERRLOG("Error opening file : %s", strerror(errno)); + if (!jsonRef) { break; } @@ -136,7 +280,6 @@ int json_createFromFile(const char *filePath, INOUT JSON_s *parsedData) { jsonString = newString; } } - } while (bytesRead); if (bytesRead < 0) { @@ -144,13 +287,37 @@ int json_createFromFile(const char *filePath, INOUT JSON_s *parsedData) { } jsonLen = jsonIdx; - TEMP_FAILURE_RETRY(close(fd)); - fd = -1; - // now parse the string - jsmnerr_t errCount = _json_createFromString(jsonString, parsedData, jsonLen); + errCount = _json_createFromString(jsonString, jsonRef, jsonLen); + + } while (0); + + if (jsonString) { FREE(jsonString); - return errCount; + } + + return errCount; +} + +int json_createFromFile(const char *filePath, INOUT JSON_ref *jsonRef) { + + int fd = -1; + jsmnerr_t errCount = JSMN_ERROR_NOMEM; + do { + if (!filePath) { + break; + } + if (!jsonRef) { + break; + } + + TEMP_FAILURE_RETRY(fd = open(filePath, O_RDONLY)); + if (fd < 0) { + ERRLOG("Error opening file : %s", strerror(errno)); + break; + } + + errCount = json_createFromFD(fd, jsonRef); } while (0); @@ -159,15 +326,11 @@ int json_createFromFile(const char *filePath, INOUT JSON_s *parsedData) { fd = -1; } - if (jsonString) { - FREE(jsonString); - } - - return JSMN_ERROR_NOMEM; + return errCount; } -int json_createFromString(const char *jsonString, INOUT JSON_s *parsedData) { - return _json_createFromString(jsonString, parsedData, strlen(jsonString)); +int json_createFromString(const char *jsonString, INOUT JSON_ref *jsonRef) { + return _json_createFromString(jsonString, jsonRef, strlen(jsonString)); } static bool _json_mapGetStringValue(const JSON_s *map, const char *key, INOUT char **val, INOUT int *len) { @@ -236,7 +399,8 @@ static bool _json_mapGetStringValue(const JSON_s *map, const char *key, INOUT ch return foundMatch; } -bool json_mapCopyStringValue(const JSON_s *map, const char *key, INOUT char **val) { +bool json_mapCopyStringValue(const JSON_ref jsonRef, const char *key, INOUT char **val) { + JSON_s *map = (JSON_s *)jsonRef; int len = 0; bool foundMatch = _json_mapGetStringValue(map, key, val, &len); if (foundMatch) { @@ -245,7 +409,8 @@ bool json_mapCopyStringValue(const JSON_s *map, const char *key, INOUT char **va return foundMatch; } -bool json_mapParseLongValue(const JSON_s *map, const char *key, INOUT long *val, const long base) { +bool json_mapParseLongValue(const JSON_ref jsonRef, const char *key, INOUT long *val, const long base) { + JSON_s *map = (JSON_s *)jsonRef; bool foundMatch = false; do { @@ -267,7 +432,8 @@ bool json_mapParseLongValue(const JSON_s *map, const char *key, INOUT long *val, return foundMatch; } -bool json_mapParseFloatValue(const JSON_s *map, const char *key, INOUT float *val) { +bool json_mapParseFloatValue(const JSON_ref jsonRef, const char *key, INOUT float *val) { + JSON_s *map = (JSON_s *)jsonRef; bool foundMatch = false; do { @@ -289,8 +455,23 @@ bool json_mapParseFloatValue(const JSON_s *map, const char *key, INOUT float *va return foundMatch; } -void json_destroy(JSON_s *parsedData) { - FREE(parsedData->jsonString); - FREE(parsedData->jsonTokens); +bool json_serialize(JSON_ref jsonRef, int fd, bool pretty) { + JSON_s *parsedData = (JSON_s *)jsonRef; + if (pretty) { + return _json_prettyPrint(parsedData, /*start:*/0, /*end:*/parsedData->numTokens, /*indent:*/0, fd); + } else { + return _json_write(parsedData->jsonString, strlen(parsedData->jsonString), fd); + } +} + +void json_destroy(JSON_ref *jsonRef) { + if (!jsonRef) { + return; + } + + JSON_s *parsedData = (JSON_s *)*jsonRef; + FREE(parsedData->jsonString); + FREE(parsedData->jsonTokens); + FREE(*jsonRef); } diff --git a/src/json_parse.h b/src/json_parse.h index 510929cf..11fae2b1 100644 --- a/src/json_parse.h +++ b/src/json_parse.h @@ -5,7 +5,7 @@ * version 3 or later (your choice) as published by the Free Software * Foundation. * - * Copyright 2013-2015 Aaron Culliney + * Copyright 2015-2016 Aaron Culliney * */ @@ -15,39 +15,43 @@ #include "common.h" #include "../externals/jsmn/jsmn.h" -typedef struct JSON_s { - char *jsonString; - int numTokens; - jsmntok_t *jsonTokens; -} JSON_s; +// opaque type +typedef const struct JSON_s *JSON_ref; // parses string into tokens. returns positive token count or negative jsmnerr_t error code. -int json_createFromString(const char *jsonString, INOUT JSON_s *parsedData); +int json_createFromString(const char *jsonString, INOUT JSON_ref *jsonRef); // parses file into string and tokens. returns positive token count or negative jsmnerr_t error code. -int json_createFromFile(const char *filePath, INOUT JSON_s *parsedData); +int json_createFromFile(const char *filePath, INOUT JSON_ref *jsonRef); + +// parses FD into string and tokens. returns positive token count or negative jsmnerr_t error code. +int json_createFromFD(int fd, INOUT JSON_ref *jsonRef); // ---------------------------------------------------------------------------- // map functions // get string value for key in map JSON, returns true upon success and strdup()'d value in *val -bool json_mapCopyStringValue(const JSON_s *map, const char *key, INOUT char **val); +bool json_mapCopyStringValue(const JSON_ref map, const char *key, INOUT char **val); // get long value for key in map JSON, returns true upon success -bool json_mapParseLongValue(const JSON_s *dict, const char *key, INOUT long *val, const long base); +bool json_mapParseLongValue(const JSON_ref map, const char *key, INOUT long *val, const long base); // get float value for key in map JSON, returns true upon success -bool json_mapParseFloatValue(const JSON_s *dict, const char *key, INOUT float *val); +bool json_mapParseFloatValue(const JSON_ref map, const char *key, INOUT float *val); // ---------------------------------------------------------------------------- // array functions -//bool json_arrayCopyStringValueAtIndex(const JSON_s *array, unsigned long index, INOUT const char **val); -//bool json_arrayParseLongValueAtIndex(const JSON_s *array, unsigned long index, INOUT const long *val); -//bool json_arrayParseFloatValueAtIndex(const JSON_s *array, unsigned long index, INOUT const float *val); +//bool json_arrayCopyStringValueAtIndex(const JSON_ref array, unsigned long index, INOUT const char **val); +//bool json_arrayParseLongValueAtIndex(const JSON_ref array, unsigned long index, INOUT const long *val, const long base); +//bool json_arrayParseFloatValueAtIndex(const JSON_ref array, unsigned long index, INOUT const float *val); + +// ---------------------------------------------------------------------------- +// serialization +bool json_serialize(JSON_ref json, int fd, bool pretty); // ---------------------------------------------------------------------------- // destroys internal allocated memory (if any) -void json_destroy(JSON_s *parsedData); +void json_destroy(JSON_ref *jsonRef); #endif diff --git a/src/json_parse_private.h b/src/json_parse_private.h new file mode 100644 index 00000000..fb5ac6aa --- /dev/null +++ b/src/json_parse_private.h @@ -0,0 +1,18 @@ +/* + * Apple // emulator for *ix + * + * This software package is subject to the GNU General Public License + * version 3 or later (your choice) as published by the Free Software + * Foundation. + * + * Copyright 2015-2016 Aaron Culliney + * + */ + +typedef struct JSON_s { + size_t jsonLen; + char *jsonString; + int numTokens; + jsmntok_t *jsonTokens; +} JSON_s; + diff --git a/src/test/testprefs.c b/src/test/testprefs.c index e5d0cecf..1ccf4fe8 100644 --- a/src/test/testprefs.c +++ b/src/test/testprefs.c @@ -10,6 +10,7 @@ */ #include "testcommon.h" +#include "json_parse_private.h" static bool test_thread_running = false; @@ -49,12 +50,8 @@ static const char *get_default_preferences(void) { ; } -// ---------------------------------------------------------------------------- -// JSON/prefs tests ... - -TEST test_json_map_1() { - - const char *testMapStr0 = +static const char *get_sample_json_1(void) { + return " { " " \"key0\" : \"a value zero\", " " \"key1\" : \" \", " @@ -82,94 +79,258 @@ TEST test_json_map_1() { " \"floatKey3\" : -3.1e2 " " } " ; +} - JSON_s parsedData = { 0 }; - int tokCount = json_createFromString(testMapStr0, &parsedData); - if (tokCount < 0) { - return 1; - } +// ---------------------------------------------------------------------------- +// JSON/prefs tests ... + +TEST test_json_map_0(JSON_ref parsedData) { long lVal; float fVal; char *val; - json_mapParseLongValue(&parsedData, "intKey2", &lVal, 10); + json_mapParseLongValue(parsedData, "intKey2", &lVal, 10); ASSERT(lVal == 0); - json_mapCopyStringValue(&parsedData, "key0", &val); + json_mapCopyStringValue(parsedData, "key0", &val); ASSERT(strcmp(val, "a value zero") == 0); FREE(val); - json_mapCopyStringValue(&parsedData, "key1", &val); + json_mapCopyStringValue(parsedData, "key1", &val); ASSERT(strcmp(val, " \t ") == 0); FREE(val); - json_mapCopyStringValue(&parsedData, "key2", &val); + json_mapCopyStringValue(parsedData, "key2", &val); ASSERT(strcmp(val, "{ \t \n}") == 0); FREE(val); - json_mapCopyStringValue(&parsedData, "key3", &val); + json_mapCopyStringValue(parsedData, "key3", &val); ASSERT(strcmp(val, "{ \t \n \"subkey0\" : \"subval0\", \"subkey1\" : { \"moar\" : \"recursion\" } , \"subkey2\" : \"line0 \n \tline1 \tline2\" \n}") == 0); - { - JSON_s parsedSubData = { 0 }; + do { + JSON_ref parsedSubData = NULL; int tokSubCount = json_createFromString(val, &parsedSubData); - if (tokSubCount < 0) { - return 1; - } + ASSERT(tokSubCount > 0); char *subval; - json_mapCopyStringValue(&parsedSubData, "subkey0", &subval); + json_mapCopyStringValue(parsedSubData, "subkey0", &subval); ASSERT(strcmp(subval, "subval0") == 0); FREE(subval); - json_mapCopyStringValue(&parsedSubData, "subkey1", &subval); + json_mapCopyStringValue(parsedSubData, "subkey1", &subval); ASSERT(strcmp(subval, "{ \"moar\" : \"recursion\" }") == 0); FREE(subval); - json_mapCopyStringValue(&parsedSubData, "subkey2", &subval); + json_mapCopyStringValue(parsedSubData, "subkey2", &subval); ASSERT(strcmp(subval, "line0 \n \tline1 \tline2") == 0); FREE(subval); - } + + json_destroy(&parsedSubData); + } while (0); FREE(val); - json_mapCopyStringValue(&parsedData, "key4", &val); + json_mapCopyStringValue(parsedData, "key4", &val); ASSERT(strcmp(val, "[ \"Q\", \"W\", \"E\", \"R\", \"T\", \"Y\", \"U\", \"I\", \"O\", \"P\", { \"x\" : [ 22, 4, \"ab\" ] } ]") == 0); // TODO : subarray checks FREE(val); - json_mapCopyStringValue(&parsedData, "key5", &val); + json_mapCopyStringValue(parsedData, "key5", &val); ASSERT(strcmp(val, "") == 0); FREE(val); - json_mapParseLongValue(&parsedData, "intKey0", &lVal, 10); + json_mapParseLongValue(parsedData, "intKey0", &lVal, 10); ASSERT(lVal == 42); - json_mapParseLongValue(&parsedData, "intKey1", &lVal, 10); + json_mapParseLongValue(parsedData, "intKey1", &lVal, 10); ASSERT(lVal == -101); - json_mapParseLongValue(&parsedData, "intKey3", &lVal, 16); + json_mapParseLongValue(parsedData, "intKey3", &lVal, 16); ASSERT(lVal == 0x2400); - json_mapParseLongValue(&parsedData, "intKey4", &lVal, 2); + json_mapParseLongValue(parsedData, "intKey4", &lVal, 2); ASSERT(lVal == 191); - json_mapParseLongValue(&parsedData, "intKey4", &lVal, 10); + json_mapParseLongValue(parsedData, "intKey4", &lVal, 10); ASSERT(lVal == 10111111); - json_mapParseFloatValue(&parsedData, "floatKey0", &fVal); + json_mapParseFloatValue(parsedData, "floatKey0", &fVal); ASSERT(fVal == 0.f); - json_mapParseFloatValue(&parsedData, "floatKey1", &fVal); + json_mapParseFloatValue(parsedData, "floatKey1", &fVal); ASSERT(fVal == -.0001220703125); - json_mapParseFloatValue(&parsedData, "floatKey2", &fVal); + json_mapParseFloatValue(parsedData, "floatKey2", &fVal); ASSERT((long)(fVal*10000000) == 31415928); - json_mapParseFloatValue(&parsedData, "floatKey3", &fVal); + json_mapParseFloatValue(parsedData, "floatKey3", &fVal); ASSERT((long)fVal == -310); - json_destroy(&parsedData); + PASS(); +} +TEST test_json_map_1() { + + const char *testMapStr0 = get_sample_json_1(); + + JSON_ref parsedData = NULL; + int tokCount = json_createFromString(testMapStr0, &parsedData); + ASSERT(tokCount > 0); + + test_json_map_0(parsedData); + + json_destroy(&parsedData); + PASS(); +} + +TEST test_json_serialization() { + + const char *testMapStr0 = get_sample_json_1(); + + JSON_ref parsedData = NULL; + int tokCount = json_createFromString(testMapStr0, &parsedData); + ASSERT(tokCount > 0); + + char *str = STRDUP("/tmp/json-XXXXXX"); + int fd = mkstemp(str); + ASSERT(fd > 0); + FREE(str); + + json_serialize(parsedData, fd, /*pretty:*/false); + json_destroy(&parsedData); + lseek(fd, 0, SEEK_SET); + json_createFromFD(fd, &parsedData); + + test_json_map_0(parsedData); + + TEMP_FAILURE_RETRY(close(fd)); + + json_destroy(&parsedData); + PASS(); +} + +TEST test_json_serialization_pretty() { + + const char *testMapStr0 = get_sample_json_1(); + + JSON_ref parsedData = NULL; + int tokCount = json_createFromString(testMapStr0, &parsedData); + ASSERT(tokCount > 0); + + char *str = STRDUP("/tmp/json-pretty-XXXXXX"); + int fd = mkstemp(str); + ASSERT(fd > 0); + FREE(str); + + json_serialize(parsedData, fd, /*pretty:*/true); + json_destroy(&parsedData); + lseek(fd, 0, SEEK_SET); + json_createFromFD(fd, &parsedData); + + do { + long lVal; + float fVal; + char *val; + + json_mapParseLongValue(parsedData, "intKey2", &lVal, 10); + ASSERT(lVal == 0); + + json_mapCopyStringValue(parsedData, "key0", &val); + ASSERT(strcmp(val, "a value zero") == 0); + FREE(val); + + json_mapCopyStringValue(parsedData, "key1", &val); + ASSERT(strcmp(val, " \t ") == 0); + FREE(val); + + json_mapCopyStringValue(parsedData, "key2", &val); + do { + JSON_ref parsedSubData = NULL; + int tokSubCount = json_createFromString(val, &parsedSubData); + ASSERT(tokSubCount == 1); + ASSERT(((JSON_s *)parsedSubData)->jsonTokens[0].type == JSMN_OBJECT); + json_destroy(&parsedSubData); + } while (0); + FREE(val); + + json_mapCopyStringValue(parsedData, "key3", &val); + do { + JSON_ref parsedSubData = NULL; + int tokSubCount = json_createFromString(val, &parsedSubData); + ASSERT(tokSubCount == 9); + + char *subval; + json_mapCopyStringValue(parsedSubData, "subkey0", &subval); + ASSERT(strcmp(subval, "subval0") == 0); + FREE(subval); + + json_mapCopyStringValue(parsedSubData, "subkey1", &subval); + do { + JSON_ref parsedSubSubData = NULL; + int tokSubSubCount = json_createFromString(subval, &parsedSubSubData); + ASSERT(tokSubSubCount == 3); + + char *subsubval; + json_mapCopyStringValue(parsedSubSubData, "moar", &subsubval); + ASSERT(strcmp(subsubval, "recursion") == 0); + FREE(subsubval); + + json_destroy(&parsedSubSubData); + } while (0); + FREE(subval); + + json_mapCopyStringValue(parsedSubData, "subkey2", &subval); + ASSERT(strcmp(subval, "line0 \n \tline1 \tline2") == 0); + FREE(subval); + + json_destroy(&parsedSubData); + } while (0); + FREE(val); + + json_mapCopyStringValue(parsedData, "key4", &val); + do { + JSON_ref parsedSubData = NULL; + int tokSubCount = json_createFromString(val, &parsedSubData); + ASSERT(tokSubCount == 17); + // TODO : subarray checks + json_destroy(&parsedSubData); + } while (0); + FREE(val); + + json_mapCopyStringValue(parsedData, "key5", &val); + ASSERT(strcmp(val, "") == 0); + FREE(val); + + json_mapParseLongValue(parsedData, "intKey0", &lVal, 10); + ASSERT(lVal == 42); + + json_mapParseLongValue(parsedData, "intKey1", &lVal, 10); + ASSERT(lVal == -101); + + json_mapParseLongValue(parsedData, "intKey3", &lVal, 16); + ASSERT(lVal == 0x2400); + + json_mapParseLongValue(parsedData, "intKey4", &lVal, 2); + ASSERT(lVal == 191); + + json_mapParseLongValue(parsedData, "intKey4", &lVal, 10); + ASSERT(lVal == 10111111); + + json_mapParseFloatValue(parsedData, "floatKey0", &fVal); + ASSERT(fVal == 0.f); + + json_mapParseFloatValue(parsedData, "floatKey1", &fVal); + ASSERT(fVal == -.0001220703125); + + json_mapParseFloatValue(parsedData, "floatKey2", &fVal); + ASSERT((long)(fVal*10000000) == 31415928); + + json_mapParseFloatValue(parsedData, "floatKey3", &fVal); + ASSERT((long)fVal == -310); + } while (0); + + TEMP_FAILURE_RETRY(close(fd)); + + json_destroy(&parsedData); PASS(); } @@ -194,6 +355,9 @@ GREATEST_SUITE(test_suite_prefs) { RUN_TESTp(test_json_map_1); + RUN_TESTp(test_json_serialization); + RUN_TESTp(test_json_serialization_pretty); + // -------------------------------- pthread_mutex_unlock(&interface_mutex); } diff --git a/src/video/gltouchkbd.c b/src/video/gltouchkbd.c index d24d2ec1..f6241e55 100644 --- a/src/video/gltouchkbd.c +++ b/src/video/gltouchkbd.c @@ -11,6 +11,7 @@ #include "video/glhudmodel.h" #include "video/glnode.h" +#include "json_parse_private.h" #if !INTERFACE_TOUCH #error this is a touch interface module, possibly you mean to not compile this at all? @@ -623,7 +624,7 @@ static void gltouchkbd_reshape(int w, int h, bool landscape) { } static void gltouchkbd_setData(const char *jsonData) { - JSON_s parsedData = { 0 }; + JSON_ref parsedData = NULL; int tokCount = json_createFromString(jsonData, &parsedData); do { @@ -631,8 +632,8 @@ static void gltouchkbd_setData(const char *jsonData) { break; } - json_mapParseFloatValue(&parsedData, PREF_PORTRAIT_HEIGHT_SCALE, &kbd.portraitHeightScale); - json_mapParseFloatValue(&parsedData, PREF_PORTRAIT_POSITION_SCALE, &kbd.portraitPositionScale); + json_mapParseFloatValue(parsedData, PREF_PORTRAIT_HEIGHT_SCALE, &kbd.portraitHeightScale); + json_mapParseFloatValue(parsedData, PREF_PORTRAIT_POSITION_SCALE, &kbd.portraitPositionScale); gltouchkbd_reshape(touchport.rawWidth, touchport.rawHeight, touchport.isLandscape); } while (0); @@ -776,8 +777,9 @@ static void gltouchkbd_endCalibration(void) { } static void gltouchkbd_loadAltKbd(const char *kbdPath) { - JSON_s parsedData = { 0 }; - int tokCount = json_createFromFile(kbdPath, &parsedData); + JSON_ref jsonRef = NULL; + int tokCount = json_createFromFile(kbdPath, &jsonRef); + JSON_s parsedData = (JSON_s)parsedData; do { if (tokCount < 0) { diff --git a/src/video/glvideo.c b/src/video/glvideo.c index 07d4255d..6619f68d 100644 --- a/src/video/glvideo.c +++ b/src/video/glvideo.c @@ -425,7 +425,7 @@ static void glvideo_reshape(int w, int h, bool landscape) { #if INTERFACE_TOUCH static void glvideo_setData(const char *jsonData) { - JSON_s parsedData = { 0 }; + JSON_ref parsedData = NULL; int tokCount = json_createFromString(jsonData, &parsedData); do { @@ -433,7 +433,7 @@ static void glvideo_setData(const char *jsonData) { break; } - json_mapParseFloatValue(&parsedData, PREF_PORTRAIT_POSITION_SCALE, &portraitPositionScale); + json_mapParseFloatValue(parsedData, PREF_PORTRAIT_POSITION_SCALE, &portraitPositionScale); glvideo_reshape(rawWidth, rawHeight, isLandscape); } while (0);