Add JSON serialization and tests

- Encourage use of opaque reference rather than internal struct
This commit is contained in:
Aaron Culliney 2016-02-27 13:46:02 -08:00
parent b87273e742
commit 01b25527fe
7 changed files with 467 additions and 98 deletions

View File

@ -4,8 +4,8 @@
#include <stddef.h>
// APPLE2IX : define these ...
#define JSMN_PARENT_LINKS
#define JSMN_STRICT
#define JSMN_PARENT_LINKS 1
#define JSMN_STRICT 1
#ifdef __cplusplus
extern "C" {

View File

@ -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);
}

View File

@ -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

18
src/json_parse_private.h Normal file
View File

@ -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;

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);