Yodiwo / YodiwoPlegma
Committer:
mitsarionas
Date:
Tue Sep 15 10:21:40 2015 +0000
Revision:
3:96b08b5f998f
Parent:
2:855390040d43
Child:
4:073e23f6718c
manual version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mitsarionas 0:384a04dc912e 1
mitsarionas 0:384a04dc912e 2
mitsarionas 0:384a04dc912e 3 #include <stdio.h>
mitsarionas 0:384a04dc912e 4 #include <stdint.h>
mitsarionas 0:384a04dc912e 5 #include <stdbool.h>
mitsarionas 0:384a04dc912e 6 #include "jsmn.h"
mitsarionas 0:384a04dc912e 7 #include "yodiwo_api.h"
mitsarionas 0:384a04dc912e 8 #include "yodiwo_helpers.h"
mitsarionas 0:384a04dc912e 9
mitsarionas 0:384a04dc912e 10
mitsarionas 0:384a04dc912e 11 /* ======================================================================================================================= */
mitsarionas 0:384a04dc912e 12 /* FromJson Functions */
mitsarionas 0:384a04dc912e 13 /* ======================================================================================================================= */
mitsarionas 0:384a04dc912e 14
mitsarionas 0:384a04dc912e 15 Yodiwo_Plegma_Json_e HelperJsonParseExec(char*json, int jsonSize, ParseTable table[], size_t tableSize)
mitsarionas 0:384a04dc912e 16 {
mitsarionas 0:384a04dc912e 17 int i, tokIndex;
mitsarionas 0:384a04dc912e 18 int tokSize;
mitsarionas 0:384a04dc912e 19 jsmntok_t t[64]; /* We expect no more than 128 tokens */
mitsarionas 0:384a04dc912e 20 jsmn_parser p;
mitsarionas 0:384a04dc912e 21 jsmn_init(&p);
mitsarionas 0:384a04dc912e 22 if ((tokSize = jsmn_parse(&p, json, jsonSize, t, sizeof(t) / sizeof(t[0]))) < 0) return Yodiwo_JsonFailedToParse;
mitsarionas 0:384a04dc912e 23 if (tokSize < 1 || t[0].type != JSMN_OBJECT) return Yodiwo_JsonFailedObjectExpected;
mitsarionas 0:384a04dc912e 24
mitsarionas 0:384a04dc912e 25 /* Loop over all keys of the root object */
mitsarionas 0:384a04dc912e 26 for (tokIndex = 1; tokIndex < tokSize; tokIndex++) {
mitsarionas 0:384a04dc912e 27 jsmntok_t *tok = &t[tokIndex];
mitsarionas 0:384a04dc912e 28 printf("Type: %d \n", t[tokIndex + 1].type);
mitsarionas 0:384a04dc912e 29
mitsarionas 0:384a04dc912e 30 // Scan the match table
mitsarionas 0:384a04dc912e 31 for (i = 0; i < tableSize; i++) {
mitsarionas 0:384a04dc912e 32 // Try to find a match
mitsarionas 0:384a04dc912e 33 int l = (tok->end - tok->start);
mitsarionas 1:e204589f4229 34 if ((tok->type == JSMN_PRIMITIVE || tok->type == JSMN_STRING) &&
mitsarionas 0:384a04dc912e 35 (l == table[i].filedNameLength) &&
mitsarionas 0:384a04dc912e 36 (memcmp(&json[tok->start], table[i].fieldName, l) == 0))
mitsarionas 0:384a04dc912e 37 {
mitsarionas 0:384a04dc912e 38 if (table[i].parseFunc != NULL)
mitsarionas 0:384a04dc912e 39 {
mitsarionas 0:384a04dc912e 40 tokIndex += table[i].parseFunc(&t[tokIndex + 1], json, table[i].value);
mitsarionas 0:384a04dc912e 41 }
mitsarionas 0:384a04dc912e 42 else if (table[i].parseFuncSubStruct != NULL)
mitsarionas 0:384a04dc912e 43 {
mitsarionas 0:384a04dc912e 44 // We wait for object
mitsarionas 0:384a04dc912e 45 if (!((t[tokIndex + 1].type == JSMN_OBJECT) || (t[tokIndex + 1].type == JSMN_ARRAY)))
mitsarionas 0:384a04dc912e 46 break;
mitsarionas 0:384a04dc912e 47
mitsarionas 0:384a04dc912e 48 table[i].parseFuncSubStruct(&json[t[tokIndex + 1].start], t[tokIndex + 1].end - t[tokIndex + 1].start, table[i].value);
mitsarionas 0:384a04dc912e 49
mitsarionas 0:384a04dc912e 50 // Skip sub objects
mitsarionas 0:384a04dc912e 51 int blockEnd = t[tokIndex + 1].end;
mitsarionas 0:384a04dc912e 52 int j;
mitsarionas 0:384a04dc912e 53 for (j = tokIndex + 1; j < tokSize && t[j].end <= blockEnd; j++)
mitsarionas 0:384a04dc912e 54 tokIndex++;
mitsarionas 0:384a04dc912e 55 }
mitsarionas 0:384a04dc912e 56 break;
mitsarionas 0:384a04dc912e 57 }
mitsarionas 0:384a04dc912e 58 }
mitsarionas 0:384a04dc912e 59 }
mitsarionas 0:384a04dc912e 60 return Yodiwo_JsonSuccessParse;
mitsarionas 0:384a04dc912e 61 }
mitsarionas 0:384a04dc912e 62 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 63 static void *os_zmalloc(size_t size)
mitsarionas 0:384a04dc912e 64 {
mitsarionas 0:384a04dc912e 65 void *p = malloc(size);
mitsarionas 0:384a04dc912e 66 if (p != NULL)
mitsarionas 0:384a04dc912e 67 memset(p, 0, size);
mitsarionas 0:384a04dc912e 68 return p;
mitsarionas 0:384a04dc912e 69 }
mitsarionas 0:384a04dc912e 70 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 71 int Parse_String(jsmntok_t* t, char* json, void** result)
mitsarionas 0:384a04dc912e 72 {
mitsarionas 0:384a04dc912e 73 int s = t->end - t->start;
mitsarionas 3:96b08b5f998f 74 int escaped = count_escaped(&json[t->start], s);
mitsarionas 3:96b08b5f998f 75 printf("total: %d\n", s);
mitsarionas 3:96b08b5f998f 76 printf("escaped: %d\n", escaped);
mitsarionas 3:96b08b5f998f 77 *result = os_zmalloc(sizeof(char)*(s - escaped + 1));
mitsarionas 0:384a04dc912e 78 if (*result != NULL)
mitsarionas 3:96b08b5f998f 79 memcpy_unescaped(*result, &json[t->start], s);
mitsarionas 0:384a04dc912e 80 return 1;
mitsarionas 0:384a04dc912e 81 }
mitsarionas 0:384a04dc912e 82 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 83 int Parse_Double(jsmntok_t* t, char* json, void** result)
mitsarionas 0:384a04dc912e 84 {
mitsarionas 0:384a04dc912e 85 int s = t->end - t->start;
mitsarionas 0:384a04dc912e 86 char d[100]; memset(d, 0, s);
mitsarionas 0:384a04dc912e 87 memcpy(d, &json[t->start], s);
mitsarionas 0:384a04dc912e 88 *result = atof(d);
mitsarionas 0:384a04dc912e 89 return 1;
mitsarionas 0:384a04dc912e 90 }
mitsarionas 0:384a04dc912e 91 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 92 int Parse_Float(jsmntok_t* t, char* json, void** result)
mitsarionas 0:384a04dc912e 93 {
mitsarionas 0:384a04dc912e 94 int s = t->end - t->start;
mitsarionas 0:384a04dc912e 95 char d[100]; memset(d, 0, s);
mitsarionas 0:384a04dc912e 96 memcpy(d, &json[t->start], s);
mitsarionas 0:384a04dc912e 97 *result = atof(d);
mitsarionas 0:384a04dc912e 98 return 1;
mitsarionas 0:384a04dc912e 99 }
mitsarionas 0:384a04dc912e 100 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 101 int Parse_Int(jsmntok_t* t, char* json, void** result)
mitsarionas 0:384a04dc912e 102 {
mitsarionas 0:384a04dc912e 103 int s = t->end - t->start;
mitsarionas 0:384a04dc912e 104 char d[100]; memset(d, 0, s);
mitsarionas 0:384a04dc912e 105 memcpy(d, &json[t->start], s);
mitsarionas 0:384a04dc912e 106 *result = atoi(d);
mitsarionas 0:384a04dc912e 107 return 1;
mitsarionas 0:384a04dc912e 108 }
mitsarionas 0:384a04dc912e 109 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 110 int Parse_Bool(jsmntok_t* t, char* json, void** result)
mitsarionas 0:384a04dc912e 111 {
mitsarionas 0:384a04dc912e 112 int s = t->end - t->start;
mitsarionas 0:384a04dc912e 113 char d[100]; memset(d, 0, s);
mitsarionas 0:384a04dc912e 114 memcpy(d, &json[t->start], s);
mitsarionas 0:384a04dc912e 115 if (t->type == JSMN_STRING)
mitsarionas 0:384a04dc912e 116 {
mitsarionas 0:384a04dc912e 117 if (memcmp(d, "true", 4) == 0 ||
mitsarionas 0:384a04dc912e 118 memcmp(d, "True", 4) == 0 ||
mitsarionas 0:384a04dc912e 119 memcmp(d, "TRUE", 4) == 0)
mitsarionas 0:384a04dc912e 120 *result = true;
mitsarionas 0:384a04dc912e 121 else
mitsarionas 0:384a04dc912e 122 *result = false;
mitsarionas 0:384a04dc912e 123 }
mitsarionas 0:384a04dc912e 124 else
mitsarionas 0:384a04dc912e 125 {
mitsarionas 0:384a04dc912e 126 *result = atoi(d) > 0;
mitsarionas 0:384a04dc912e 127 }
mitsarionas 0:384a04dc912e 128 return 1;
mitsarionas 0:384a04dc912e 129 }
mitsarionas 0:384a04dc912e 130 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 131 // Parse array and find sub structs
mitsarionas 0:384a04dc912e 132 // NOTE: this replace the T with the sub elements !!!!
mitsarionas 0:384a04dc912e 133 int Helper_Json_ParseArray(jsmntok_t t[], int tokSize)
mitsarionas 0:384a04dc912e 134 {
mitsarionas 0:384a04dc912e 135 int i, n = 0, j;
mitsarionas 0:384a04dc912e 136 for (i = 1; i < tokSize; i++)
mitsarionas 0:384a04dc912e 137 {
mitsarionas 0:384a04dc912e 138 // We wait for object
mitsarionas 0:384a04dc912e 139 if (t[i].type != JSMN_OBJECT)
mitsarionas 0:384a04dc912e 140 break;
mitsarionas 0:384a04dc912e 141
mitsarionas 0:384a04dc912e 142 // store the element
mitsarionas 0:384a04dc912e 143 t[n] = t[i];
mitsarionas 0:384a04dc912e 144 n++;
mitsarionas 0:384a04dc912e 145
mitsarionas 0:384a04dc912e 146 // Skip sub objects
mitsarionas 0:384a04dc912e 147 int blockEnd = t[i].end;
mitsarionas 0:384a04dc912e 148 for (j = i + 1; j < tokSize && t[j].end <= blockEnd; j++)
mitsarionas 0:384a04dc912e 149 i++;
mitsarionas 0:384a04dc912e 150 }
mitsarionas 0:384a04dc912e 151 return n;
mitsarionas 0:384a04dc912e 152 }
mitsarionas 0:384a04dc912e 153 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 154 int Helper_Json_ParseArrayType(jsmntok_t t[], int tokSize, jsmntype_t type)
mitsarionas 0:384a04dc912e 155 {
mitsarionas 0:384a04dc912e 156 int i, n = 0, j;
mitsarionas 0:384a04dc912e 157 for (i = 1; i < tokSize; i++)
mitsarionas 0:384a04dc912e 158 {
mitsarionas 0:384a04dc912e 159 // We wait for object
mitsarionas 0:384a04dc912e 160 if (t[i].type != type)
mitsarionas 0:384a04dc912e 161 break;
mitsarionas 0:384a04dc912e 162
mitsarionas 0:384a04dc912e 163 // store the element
mitsarionas 0:384a04dc912e 164 t[n] = t[i];
mitsarionas 0:384a04dc912e 165 n++;
mitsarionas 0:384a04dc912e 166
mitsarionas 0:384a04dc912e 167 // Skip sub objects
mitsarionas 0:384a04dc912e 168 int blockEnd = t[i].end;
mitsarionas 0:384a04dc912e 169 for (j = i + 1; j < tokSize && t[j].end <= blockEnd; j++)
mitsarionas 0:384a04dc912e 170 i++;
mitsarionas 0:384a04dc912e 171 }
mitsarionas 0:384a04dc912e 172 return n;
mitsarionas 0:384a04dc912e 173 }
mitsarionas 0:384a04dc912e 174 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 175 // Primitive helperf ToJsonFunction
mitsarionas 0:384a04dc912e 176 int Array_string_ToJson(char* jsonStart, size_t jsonSize, Array_string *array)
mitsarionas 0:384a04dc912e 177 {
mitsarionas 0:384a04dc912e 178 int i = 0, len; char *json = jsonStart, *jsonEnd = json + jsonSize;
mitsarionas 0:384a04dc912e 179 *json = '['; json++;
mitsarionas 0:384a04dc912e 180 if (array != NULL) {
mitsarionas 0:384a04dc912e 181 for (i = 0; i < array->num && json < jsonEnd; i++) {
mitsarionas 0:384a04dc912e 182 if ((len = snprintf(json, jsonEnd - json - 2, "\"%s\"", array->elems[i])) < 0)
mitsarionas 0:384a04dc912e 183 return -1;
mitsarionas 0:384a04dc912e 184 else json += len;
mitsarionas 0:384a04dc912e 185 *json = ','; json++;
mitsarionas 0:384a04dc912e 186 }
mitsarionas 0:384a04dc912e 187 if (i > 0) json--; // remove last ,
mitsarionas 0:384a04dc912e 188 }
mitsarionas 0:384a04dc912e 189 *json = ']'; json++;
mitsarionas 0:384a04dc912e 190 *json = '\0'; json++;
mitsarionas 0:384a04dc912e 191 return json - jsonStart;
mitsarionas 0:384a04dc912e 192 }
mitsarionas 0:384a04dc912e 193 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 194 Yodiwo_Plegma_Json_e Array_string_FromJson(char* json, size_t jsonSize, Array_string *array)
mitsarionas 0:384a04dc912e 195 {
mitsarionas 0:384a04dc912e 196 int i = 0, r;
mitsarionas 0:384a04dc912e 197 Yodiwo_Plegma_Json_e res = Yodiwo_JsonSuccessParse;
mitsarionas 0:384a04dc912e 198 jsmntok_t t[64]; /* We expect no more than 64 tokens */
mitsarionas 0:384a04dc912e 199 jsmn_parser p;
mitsarionas 0:384a04dc912e 200 jsmn_init(&p);
mitsarionas 0:384a04dc912e 201 if ((r = jsmn_parse(&p, json, jsonSize, t, sizeof(t) / sizeof(t[0]))) < 0) return Yodiwo_JsonFailedToParse;
mitsarionas 0:384a04dc912e 202 if (r < 1 || t[0].type != JSMN_ARRAY) return Yodiwo_JsonFailedObjectExpected;
mitsarionas 0:384a04dc912e 203
mitsarionas 0:384a04dc912e 204 array->num = Helper_Json_ParseArrayType(t, r, JSMN_STRING);
mitsarionas 0:384a04dc912e 205 array->elems = (char**)os_zmalloc(array->num*sizeof(char*));
mitsarionas 0:384a04dc912e 206 for (i = 0; i < array->num; i++) {
mitsarionas 0:384a04dc912e 207 int size = t[i].end - t[i].start;
mitsarionas 0:384a04dc912e 208 array->elems[i] = (char*)os_zmalloc((size + 1)*sizeof(char)); // add and a zero lead
mitsarionas 0:384a04dc912e 209 if (array->elems[i] == NULL)
mitsarionas 0:384a04dc912e 210 break;
mitsarionas 0:384a04dc912e 211
mitsarionas 0:384a04dc912e 212 // copy the string
mitsarionas 0:384a04dc912e 213 memcpy(array->elems[i], &json[t[i].start], size);
mitsarionas 0:384a04dc912e 214 }
mitsarionas 0:384a04dc912e 215 if (i == array->num)
mitsarionas 0:384a04dc912e 216 return Yodiwo_JsonSuccessParse;
mitsarionas 0:384a04dc912e 217 return res;
mitsarionas 0:384a04dc912e 218 }
mitsarionas 2:855390040d43 219 // -----------------------------------------------------------------------------------------------------------------------