Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
yodiwo_helpers.c
- Committer:
- mitsarionas
- Date:
- 2015-09-15
- Revision:
- 4:073e23f6718c
- Parent:
- 3:96b08b5f998f
- Child:
- 6:4596aaa1a824
File content as of revision 4:073e23f6718c:
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "jsmn.h"
#include "yodiwo_api.h"
#include "yodiwo_helpers.h"
/* ======================================================================================================================= */
/* FromJson Functions */
/* ======================================================================================================================= */
Yodiwo_Plegma_Json_e HelperJsonParseExec(char*json, int jsonSize, ParseTable table[], size_t tableSize)
{
int i, tokIndex;
int tokSize;
jsmntok_t t[64]; /* We expect no more than 128 tokens */
jsmn_parser p;
jsmn_init(&p);
if ((tokSize = jsmn_parse(&p, json, jsonSize, t, sizeof(t) / sizeof(t[0]))) < 0) return Yodiwo_JsonFailedToParse;
if (tokSize < 1 || t[0].type != JSMN_OBJECT) return Yodiwo_JsonFailedObjectExpected;
/* Loop over all keys of the root object */
for (tokIndex = 1; tokIndex < tokSize; tokIndex++) {
jsmntok_t *tok = &t[tokIndex];
// printf("Type: %d \n", t[tokIndex + 1].type);
// Scan the match table
for (i = 0; i < tableSize; i++) {
// Try to find a match
int l = (tok->end - tok->start);
if ((tok->type == JSMN_PRIMITIVE || tok->type == JSMN_STRING) &&
(l == table[i].filedNameLength) &&
(memcmp(&json[tok->start], table[i].fieldName, l) == 0))
{
if (table[i].parseFunc != NULL)
{
tokIndex += table[i].parseFunc(&t[tokIndex + 1], json, table[i].value);
}
else if (table[i].parseFuncSubStruct != NULL)
{
// We wait for object
if (!((t[tokIndex + 1].type == JSMN_OBJECT) || (t[tokIndex + 1].type == JSMN_ARRAY)))
break;
table[i].parseFuncSubStruct(&json[t[tokIndex + 1].start], t[tokIndex + 1].end - t[tokIndex + 1].start, table[i].value);
// Skip sub objects
int blockEnd = t[tokIndex + 1].end;
int j;
for (j = tokIndex + 1; j < tokSize && t[j].end <= blockEnd; j++)
tokIndex++;
}
break;
}
}
}
return Yodiwo_JsonSuccessParse;
}
// -----------------------------------------------------------------------------------------------------------------------
static void *os_zmalloc(size_t size)
{
void *p = malloc(size);
if (p != NULL)
memset(p, 0, size);
return p;
}
// -----------------------------------------------------------------------------------------------------------------------
int Parse_String(jsmntok_t* t, char* json, void** result)
{
int s = t->end - t->start;
int escaped = count_escaped(&json[t->start], s);
*result = os_zmalloc(sizeof(char)*(s - escaped + 1));
if (*result != NULL)
memcpy_unescaped(*result, &json[t->start], s);
return 1;
}
// -----------------------------------------------------------------------------------------------------------------------
int Parse_Double(jsmntok_t* t, char* json, void** result)
{
int s = t->end - t->start;
char d[100]; memset(d, 0, s);
memcpy(d, &json[t->start], s);
*result = atof(d);
return 1;
}
// -----------------------------------------------------------------------------------------------------------------------
int Parse_Float(jsmntok_t* t, char* json, void** result)
{
int s = t->end - t->start;
char d[100]; memset(d, 0, s);
memcpy(d, &json[t->start], s);
*result = atof(d);
return 1;
}
// -----------------------------------------------------------------------------------------------------------------------
int Parse_Int(jsmntok_t* t, char* json, void** result)
{
int s = t->end - t->start;
char d[100]; memset(d, 0, s);
memcpy(d, &json[t->start], s);
*result = atoi(d);
return 1;
}
// -----------------------------------------------------------------------------------------------------------------------
int Parse_Bool(jsmntok_t* t, char* json, void** result)
{
int s = t->end - t->start;
char d[100]; memset(d, 0, s);
memcpy(d, &json[t->start], s);
if (t->type == JSMN_STRING)
{
if (memcmp(d, "true", 4) == 0 ||
memcmp(d, "True", 4) == 0 ||
memcmp(d, "TRUE", 4) == 0)
*result = true;
else
*result = false;
}
else
{
*result = atoi(d) > 0;
}
return 1;
}
// -----------------------------------------------------------------------------------------------------------------------
// Parse array and find sub structs
// NOTE: this replace the T with the sub elements !!!!
int Helper_Json_ParseArray(jsmntok_t t[], int tokSize)
{
int i, n = 0, j;
for (i = 1; i < tokSize; i++)
{
// We wait for object
if (t[i].type != JSMN_OBJECT)
break;
// store the element
t[n] = t[i];
n++;
// Skip sub objects
int blockEnd = t[i].end;
for (j = i + 1; j < tokSize && t[j].end <= blockEnd; j++)
i++;
}
return n;
}
// -----------------------------------------------------------------------------------------------------------------------
int Helper_Json_ParseArrayType(jsmntok_t t[], int tokSize, jsmntype_t type)
{
int i, n = 0, j;
for (i = 1; i < tokSize; i++)
{
// We wait for object
if (t[i].type != type)
break;
// store the element
t[n] = t[i];
n++;
// Skip sub objects
int blockEnd = t[i].end;
for (j = i + 1; j < tokSize && t[j].end <= blockEnd; j++)
i++;
}
return n;
}
// -----------------------------------------------------------------------------------------------------------------------
// Primitive helperf ToJsonFunction
int Array_string_ToJson(char* jsonStart, size_t jsonSize, Array_string *array)
{
int i = 0, len; char *json = jsonStart, *jsonEnd = json + jsonSize;
*json = '['; json++;
if (array != NULL) {
for (i = 0; i < array->num && json < jsonEnd; i++) {
if ((len = snprintf(json, jsonEnd - json - 2, "\"%s\"", array->elems[i])) < 0)
return -1;
else json += len;
*json = ','; json++;
}
if (i > 0) json--; // remove last ,
}
*json = ']'; json++;
*json = '\0'; json++;
return json - jsonStart;
}
// -----------------------------------------------------------------------------------------------------------------------
Yodiwo_Plegma_Json_e Array_string_FromJson(char* json, size_t jsonSize, Array_string *array)
{
int i = 0, r;
Yodiwo_Plegma_Json_e res = Yodiwo_JsonSuccessParse;
jsmntok_t t[64]; /* We expect no more than 64 tokens */
jsmn_parser p;
jsmn_init(&p);
if ((r = jsmn_parse(&p, json, jsonSize, t, sizeof(t) / sizeof(t[0]))) < 0) return Yodiwo_JsonFailedToParse;
if (r < 1 || t[0].type != JSMN_ARRAY) return Yodiwo_JsonFailedObjectExpected;
array->num = Helper_Json_ParseArrayType(t, r, JSMN_STRING);
array->elems = (char**)os_zmalloc(array->num*sizeof(char*));
for (i = 0; i < array->num; i++) {
int size = t[i].end - t[i].start;
array->elems[i] = (char*)os_zmalloc((size + 1)*sizeof(char)); // add and a zero lead
if (array->elems[i] == NULL)
break;
// copy the string
memcpy(array->elems[i], &json[t[i].start], size);
}
if (i == array->num)
return Yodiwo_JsonSuccessParse;
return res;
}
// -----------------------------------------------------------------------------------------------------------------------