Library for Yodiwo's Plegma API

Committer:
mitsarionas
Date:
Mon Sep 28 08:53:12 2015 +0000
Revision:
8:710e7fa99666
Parent:
7:a121e995f5e1
fix: c linkage

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 6:4596aaa1a824 6 #include <string.h>
mitsarionas 7:a121e995f5e1 7 #include <stdlib.h>
mitsarionas 0:384a04dc912e 8 #include "jsmn.h"
mitsarionas 0:384a04dc912e 9 #include "yodiwo_api.h"
mitsarionas 0:384a04dc912e 10 #include "yodiwo_helpers.h"
mitsarionas 0:384a04dc912e 11
mitsarionas 0:384a04dc912e 12
mitsarionas 0:384a04dc912e 13 /* ======================================================================================================================= */
mitsarionas 0:384a04dc912e 14 /* FromJson Functions */
mitsarionas 0:384a04dc912e 15 /* ======================================================================================================================= */
mitsarionas 0:384a04dc912e 16
mitsarionas 0:384a04dc912e 17 Yodiwo_Plegma_Json_e HelperJsonParseExec(char*json, int jsonSize, ParseTable table[], size_t tableSize)
mitsarionas 0:384a04dc912e 18 {
mitsarionas 0:384a04dc912e 19 int i, tokIndex;
mitsarionas 0:384a04dc912e 20 int tokSize;
mitsarionas 0:384a04dc912e 21 jsmntok_t t[64]; /* We expect no more than 128 tokens */
mitsarionas 0:384a04dc912e 22 jsmn_parser p;
mitsarionas 0:384a04dc912e 23 jsmn_init(&p);
mitsarionas 0:384a04dc912e 24 if ((tokSize = jsmn_parse(&p, json, jsonSize, t, sizeof(t) / sizeof(t[0]))) < 0) return Yodiwo_JsonFailedToParse;
mitsarionas 0:384a04dc912e 25 if (tokSize < 1 || t[0].type != JSMN_OBJECT) return Yodiwo_JsonFailedObjectExpected;
mitsarionas 0:384a04dc912e 26
mitsarionas 0:384a04dc912e 27 /* Loop over all keys of the root object */
mitsarionas 0:384a04dc912e 28 for (tokIndex = 1; tokIndex < tokSize; tokIndex++) {
mitsarionas 0:384a04dc912e 29 jsmntok_t *tok = &t[tokIndex];
mitsarionas 4:073e23f6718c 30 // printf("Type: %d \n", t[tokIndex + 1].type);
mitsarionas 0:384a04dc912e 31
mitsarionas 0:384a04dc912e 32 // Scan the match table
mitsarionas 0:384a04dc912e 33 for (i = 0; i < tableSize; i++) {
mitsarionas 0:384a04dc912e 34 // Try to find a match
mitsarionas 0:384a04dc912e 35 int l = (tok->end - tok->start);
mitsarionas 1:e204589f4229 36 if ((tok->type == JSMN_PRIMITIVE || tok->type == JSMN_STRING) &&
mitsarionas 0:384a04dc912e 37 (l == table[i].filedNameLength) &&
mitsarionas 0:384a04dc912e 38 (memcmp(&json[tok->start], table[i].fieldName, l) == 0))
mitsarionas 0:384a04dc912e 39 {
mitsarionas 0:384a04dc912e 40 if (table[i].parseFunc != NULL)
mitsarionas 0:384a04dc912e 41 {
mitsarionas 0:384a04dc912e 42 tokIndex += table[i].parseFunc(&t[tokIndex + 1], json, table[i].value);
mitsarionas 0:384a04dc912e 43 }
mitsarionas 0:384a04dc912e 44 else if (table[i].parseFuncSubStruct != NULL)
mitsarionas 0:384a04dc912e 45 {
mitsarionas 0:384a04dc912e 46 // We wait for object
mitsarionas 0:384a04dc912e 47 if (!((t[tokIndex + 1].type == JSMN_OBJECT) || (t[tokIndex + 1].type == JSMN_ARRAY)))
mitsarionas 0:384a04dc912e 48 break;
mitsarionas 0:384a04dc912e 49
mitsarionas 0:384a04dc912e 50 table[i].parseFuncSubStruct(&json[t[tokIndex + 1].start], t[tokIndex + 1].end - t[tokIndex + 1].start, table[i].value);
mitsarionas 0:384a04dc912e 51
mitsarionas 0:384a04dc912e 52 // Skip sub objects
mitsarionas 0:384a04dc912e 53 int blockEnd = t[tokIndex + 1].end;
mitsarionas 0:384a04dc912e 54 int j;
mitsarionas 0:384a04dc912e 55 for (j = tokIndex + 1; j < tokSize && t[j].end <= blockEnd; j++)
mitsarionas 0:384a04dc912e 56 tokIndex++;
mitsarionas 0:384a04dc912e 57 }
mitsarionas 0:384a04dc912e 58 break;
mitsarionas 0:384a04dc912e 59 }
mitsarionas 0:384a04dc912e 60 }
mitsarionas 0:384a04dc912e 61 }
mitsarionas 0:384a04dc912e 62 return Yodiwo_JsonSuccessParse;
mitsarionas 0:384a04dc912e 63 }
mitsarionas 0:384a04dc912e 64 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 65 static void *os_zmalloc(size_t size)
mitsarionas 0:384a04dc912e 66 {
mitsarionas 0:384a04dc912e 67 void *p = malloc(size);
mitsarionas 0:384a04dc912e 68 if (p != NULL)
mitsarionas 0:384a04dc912e 69 memset(p, 0, size);
mitsarionas 0:384a04dc912e 70 return p;
mitsarionas 0:384a04dc912e 71 }
mitsarionas 0:384a04dc912e 72 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 73 int Parse_String(jsmntok_t* t, char* json, void** result)
mitsarionas 0:384a04dc912e 74 {
mitsarionas 0:384a04dc912e 75 int s = t->end - t->start;
mitsarionas 6:4596aaa1a824 76 //write NULL for empty strings
mitsarionas 6:4596aaa1a824 77 if (s == 0) {
mitsarionas 6:4596aaa1a824 78 *result = NULL;
mitsarionas 6:4596aaa1a824 79 return 1;
mitsarionas 6:4596aaa1a824 80 }
mitsarionas 3:96b08b5f998f 81 int escaped = count_escaped(&json[t->start], s);
mitsarionas 3:96b08b5f998f 82 *result = os_zmalloc(sizeof(char)*(s - escaped + 1));
mitsarionas 0:384a04dc912e 83 if (*result != NULL)
mitsarionas 3:96b08b5f998f 84 memcpy_unescaped(*result, &json[t->start], s);
mitsarionas 0:384a04dc912e 85 return 1;
mitsarionas 0:384a04dc912e 86 }
mitsarionas 0:384a04dc912e 87 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 88 int Parse_Double(jsmntok_t* t, char* json, void** result)
mitsarionas 0:384a04dc912e 89 {
mitsarionas 0:384a04dc912e 90 int s = t->end - t->start;
mitsarionas 0:384a04dc912e 91 char d[100]; memset(d, 0, s);
mitsarionas 0:384a04dc912e 92 memcpy(d, &json[t->start], s);
mitsarionas 6:4596aaa1a824 93 *(double *)result = atof(d);
mitsarionas 0:384a04dc912e 94 return 1;
mitsarionas 0:384a04dc912e 95 }
mitsarionas 0:384a04dc912e 96 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 97 int Parse_Float(jsmntok_t* t, char* json, void** result)
mitsarionas 0:384a04dc912e 98 {
mitsarionas 0:384a04dc912e 99 int s = t->end - t->start;
mitsarionas 0:384a04dc912e 100 char d[100]; memset(d, 0, s);
mitsarionas 0:384a04dc912e 101 memcpy(d, &json[t->start], s);
mitsarionas 6:4596aaa1a824 102 *(float *)result = atof(d);
mitsarionas 0:384a04dc912e 103 return 1;
mitsarionas 0:384a04dc912e 104 }
mitsarionas 0:384a04dc912e 105 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 106 int Parse_Int(jsmntok_t* t, char* json, void** result)
mitsarionas 0:384a04dc912e 107 {
mitsarionas 0:384a04dc912e 108 int s = t->end - t->start;
mitsarionas 0:384a04dc912e 109 char d[100]; memset(d, 0, s);
mitsarionas 0:384a04dc912e 110 memcpy(d, &json[t->start], s);
mitsarionas 6:4596aaa1a824 111 *(int32_t *)result = atoi(d);
mitsarionas 0:384a04dc912e 112 return 1;
mitsarionas 0:384a04dc912e 113 }
mitsarionas 0:384a04dc912e 114 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 115 int Parse_Bool(jsmntok_t* t, char* json, void** result)
mitsarionas 0:384a04dc912e 116 {
mitsarionas 0:384a04dc912e 117 int s = t->end - t->start;
mitsarionas 0:384a04dc912e 118 char d[100]; memset(d, 0, s);
mitsarionas 0:384a04dc912e 119 memcpy(d, &json[t->start], s);
mitsarionas 0:384a04dc912e 120 if (t->type == JSMN_STRING)
mitsarionas 0:384a04dc912e 121 {
mitsarionas 0:384a04dc912e 122 if (memcmp(d, "true", 4) == 0 ||
mitsarionas 0:384a04dc912e 123 memcmp(d, "True", 4) == 0 ||
mitsarionas 0:384a04dc912e 124 memcmp(d, "TRUE", 4) == 0)
mitsarionas 6:4596aaa1a824 125 *(bool *)result = true;
mitsarionas 0:384a04dc912e 126 else
mitsarionas 6:4596aaa1a824 127 *(bool *)result = false;
mitsarionas 0:384a04dc912e 128 }
mitsarionas 0:384a04dc912e 129 else
mitsarionas 0:384a04dc912e 130 {
mitsarionas 6:4596aaa1a824 131 *(bool *)result = atoi(d) > 0;
mitsarionas 0:384a04dc912e 132 }
mitsarionas 0:384a04dc912e 133 return 1;
mitsarionas 0:384a04dc912e 134 }
mitsarionas 0:384a04dc912e 135 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 136 // Parse array and find sub structs
mitsarionas 0:384a04dc912e 137 // NOTE: this replace the T with the sub elements !!!!
mitsarionas 0:384a04dc912e 138 int Helper_Json_ParseArray(jsmntok_t t[], int tokSize)
mitsarionas 0:384a04dc912e 139 {
mitsarionas 0:384a04dc912e 140 int i, n = 0, j;
mitsarionas 0:384a04dc912e 141 for (i = 1; i < tokSize; i++)
mitsarionas 0:384a04dc912e 142 {
mitsarionas 0:384a04dc912e 143 // We wait for object
mitsarionas 0:384a04dc912e 144 if (t[i].type != JSMN_OBJECT)
mitsarionas 0:384a04dc912e 145 break;
mitsarionas 0:384a04dc912e 146
mitsarionas 0:384a04dc912e 147 // store the element
mitsarionas 0:384a04dc912e 148 t[n] = t[i];
mitsarionas 0:384a04dc912e 149 n++;
mitsarionas 0:384a04dc912e 150
mitsarionas 0:384a04dc912e 151 // Skip sub objects
mitsarionas 0:384a04dc912e 152 int blockEnd = t[i].end;
mitsarionas 0:384a04dc912e 153 for (j = i + 1; j < tokSize && t[j].end <= blockEnd; j++)
mitsarionas 0:384a04dc912e 154 i++;
mitsarionas 0:384a04dc912e 155 }
mitsarionas 0:384a04dc912e 156 return n;
mitsarionas 0:384a04dc912e 157 }
mitsarionas 0:384a04dc912e 158 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 159 int Helper_Json_ParseArrayType(jsmntok_t t[], int tokSize, jsmntype_t type)
mitsarionas 0:384a04dc912e 160 {
mitsarionas 0:384a04dc912e 161 int i, n = 0, j;
mitsarionas 0:384a04dc912e 162 for (i = 1; i < tokSize; i++)
mitsarionas 0:384a04dc912e 163 {
mitsarionas 0:384a04dc912e 164 // We wait for object
mitsarionas 0:384a04dc912e 165 if (t[i].type != type)
mitsarionas 0:384a04dc912e 166 break;
mitsarionas 0:384a04dc912e 167
mitsarionas 0:384a04dc912e 168 // store the element
mitsarionas 0:384a04dc912e 169 t[n] = t[i];
mitsarionas 0:384a04dc912e 170 n++;
mitsarionas 0:384a04dc912e 171
mitsarionas 0:384a04dc912e 172 // Skip sub objects
mitsarionas 0:384a04dc912e 173 int blockEnd = t[i].end;
mitsarionas 0:384a04dc912e 174 for (j = i + 1; j < tokSize && t[j].end <= blockEnd; j++)
mitsarionas 0:384a04dc912e 175 i++;
mitsarionas 0:384a04dc912e 176 }
mitsarionas 0:384a04dc912e 177 return n;
mitsarionas 0:384a04dc912e 178 }
mitsarionas 0:384a04dc912e 179 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 180 // Primitive helperf ToJsonFunction
mitsarionas 0:384a04dc912e 181 int Array_string_ToJson(char* jsonStart, size_t jsonSize, Array_string *array)
mitsarionas 0:384a04dc912e 182 {
mitsarionas 0:384a04dc912e 183 int i = 0, len; char *json = jsonStart, *jsonEnd = json + jsonSize;
mitsarionas 0:384a04dc912e 184 *json = '['; json++;
mitsarionas 0:384a04dc912e 185 if (array != NULL) {
mitsarionas 0:384a04dc912e 186 for (i = 0; i < array->num && json < jsonEnd; i++) {
mitsarionas 0:384a04dc912e 187 if ((len = snprintf(json, jsonEnd - json - 2, "\"%s\"", array->elems[i])) < 0)
mitsarionas 0:384a04dc912e 188 return -1;
mitsarionas 0:384a04dc912e 189 else json += len;
mitsarionas 0:384a04dc912e 190 *json = ','; json++;
mitsarionas 0:384a04dc912e 191 }
mitsarionas 0:384a04dc912e 192 if (i > 0) json--; // remove last ,
mitsarionas 0:384a04dc912e 193 }
mitsarionas 0:384a04dc912e 194 *json = ']'; json++;
mitsarionas 0:384a04dc912e 195 *json = '\0'; json++;
mitsarionas 0:384a04dc912e 196 return json - jsonStart;
mitsarionas 0:384a04dc912e 197 }
mitsarionas 0:384a04dc912e 198 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 0:384a04dc912e 199 Yodiwo_Plegma_Json_e Array_string_FromJson(char* json, size_t jsonSize, Array_string *array)
mitsarionas 0:384a04dc912e 200 {
mitsarionas 0:384a04dc912e 201 int i = 0, r;
mitsarionas 0:384a04dc912e 202 Yodiwo_Plegma_Json_e res = Yodiwo_JsonSuccessParse;
mitsarionas 0:384a04dc912e 203 jsmntok_t t[64]; /* We expect no more than 64 tokens */
mitsarionas 0:384a04dc912e 204 jsmn_parser p;
mitsarionas 0:384a04dc912e 205 jsmn_init(&p);
mitsarionas 0:384a04dc912e 206 if ((r = jsmn_parse(&p, json, jsonSize, t, sizeof(t) / sizeof(t[0]))) < 0) return Yodiwo_JsonFailedToParse;
mitsarionas 0:384a04dc912e 207 if (r < 1 || t[0].type != JSMN_ARRAY) return Yodiwo_JsonFailedObjectExpected;
mitsarionas 0:384a04dc912e 208
mitsarionas 0:384a04dc912e 209 array->num = Helper_Json_ParseArrayType(t, r, JSMN_STRING);
mitsarionas 0:384a04dc912e 210 array->elems = (char**)os_zmalloc(array->num*sizeof(char*));
mitsarionas 0:384a04dc912e 211 for (i = 0; i < array->num; i++) {
mitsarionas 0:384a04dc912e 212 int size = t[i].end - t[i].start;
mitsarionas 0:384a04dc912e 213 array->elems[i] = (char*)os_zmalloc((size + 1)*sizeof(char)); // add and a zero lead
mitsarionas 0:384a04dc912e 214 if (array->elems[i] == NULL)
mitsarionas 0:384a04dc912e 215 break;
mitsarionas 0:384a04dc912e 216
mitsarionas 0:384a04dc912e 217 // copy the string
mitsarionas 0:384a04dc912e 218 memcpy(array->elems[i], &json[t[i].start], size);
mitsarionas 0:384a04dc912e 219 }
mitsarionas 0:384a04dc912e 220 if (i == array->num)
mitsarionas 0:384a04dc912e 221 return Yodiwo_JsonSuccessParse;
mitsarionas 0:384a04dc912e 222 return res;
mitsarionas 0:384a04dc912e 223 }
mitsarionas 2:855390040d43 224 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 6:4596aaa1a824 225
mitsarionas 6:4596aaa1a824 226 int lastIndexOf(char c, char *str)
mitsarionas 6:4596aaa1a824 227 {
mitsarionas 6:4596aaa1a824 228 int r = -1;
mitsarionas 6:4596aaa1a824 229 int i = 0;
mitsarionas 6:4596aaa1a824 230 for(r = -1, i = 0; str[i] != '\0'; i++) {
mitsarionas 6:4596aaa1a824 231 if (str[i] == c)
mitsarionas 6:4596aaa1a824 232 r = i;
mitsarionas 6:4596aaa1a824 233 }
mitsarionas 6:4596aaa1a824 234 return r;
mitsarionas 6:4596aaa1a824 235 }
mitsarionas 6:4596aaa1a824 236
mitsarionas 6:4596aaa1a824 237 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 6:4596aaa1a824 238 int NodeKey_FromString(Yodiwo_Plegma_NodeKey_t *nodeKey, char *str)
mitsarionas 6:4596aaa1a824 239 {
mitsarionas 6:4596aaa1a824 240 int len = lastIndexOf(KEY_SEPARATOR, str);
mitsarionas 6:4596aaa1a824 241 if (len <= 0)
mitsarionas 6:4596aaa1a824 242 return -1;
mitsarionas 6:4596aaa1a824 243 nodeKey->UserKey.UserID = (char *)malloc((len + 1) * sizeof(char));
mitsarionas 6:4596aaa1a824 244 memcpy(nodeKey->UserKey.UserID, str, len);
mitsarionas 6:4596aaa1a824 245 nodeKey->UserKey.UserID[len] = '\0';
mitsarionas 6:4596aaa1a824 246 nodeKey->NodeID = atoi(&(str[len + 1]));
mitsarionas 6:4596aaa1a824 247 return 0;
mitsarionas 6:4596aaa1a824 248 }
mitsarionas 6:4596aaa1a824 249
mitsarionas 6:4596aaa1a824 250 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 6:4596aaa1a824 251 char *make_nextKey_str(char *key, int nextId)
mitsarionas 6:4596aaa1a824 252 {
mitsarionas 6:4596aaa1a824 253 int idlen;
mitsarionas 6:4596aaa1a824 254 char id_str[10];
mitsarionas 6:4596aaa1a824 255 char *nextKey;
mitsarionas 6:4596aaa1a824 256 int r;
mitsarionas 6:4596aaa1a824 257
mitsarionas 6:4596aaa1a824 258 idlen = sprintf(id_str, "%d", nextId);
mitsarionas 6:4596aaa1a824 259
mitsarionas 6:4596aaa1a824 260 if (nextId < 0 || idlen < 0)
mitsarionas 6:4596aaa1a824 261 return NULL;
mitsarionas 6:4596aaa1a824 262 r = strlen(key) + idlen + 1 + 1; //separator + null terminationportlen;
mitsarionas 6:4596aaa1a824 263 nextKey = (char *)malloc(r * sizeof(char) + 2);
mitsarionas 6:4596aaa1a824 264 if (nextKey == NULL)
mitsarionas 6:4596aaa1a824 265 return NULL;
mitsarionas 6:4596aaa1a824 266 r = sprintf(nextKey, "%s-%s", key, id_str);
mitsarionas 6:4596aaa1a824 267 if (r < 0) {
mitsarionas 6:4596aaa1a824 268 free(nextKey);
mitsarionas 6:4596aaa1a824 269 return NULL;
mitsarionas 6:4596aaa1a824 270 }
mitsarionas 6:4596aaa1a824 271 return nextKey;
mitsarionas 6:4596aaa1a824 272 }
mitsarionas 6:4596aaa1a824 273
mitsarionas 6:4596aaa1a824 274 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 6:4596aaa1a824 275 int fill_PortKey(Yodiwo_Plegma_Port_t *port, char *thingKey, int portId)
mitsarionas 6:4596aaa1a824 276 {
mitsarionas 6:4596aaa1a824 277 port->PortKey = make_nextKey_str(thingKey, portId);
mitsarionas 6:4596aaa1a824 278 return (port->PortKey != NULL) ? 0 : -1;
mitsarionas 6:4596aaa1a824 279 }
mitsarionas 6:4596aaa1a824 280
mitsarionas 6:4596aaa1a824 281 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 6:4596aaa1a824 282 int fill_ThingKey(Yodiwo_Plegma_Thing_t *thing, char *nodeKey, int thingId)
mitsarionas 6:4596aaa1a824 283 {
mitsarionas 6:4596aaa1a824 284 thing->ThingKey = make_nextKey_str(nodeKey, thingId);
mitsarionas 6:4596aaa1a824 285 return (thing->ThingKey != NULL) ? 0 : -1;
mitsarionas 6:4596aaa1a824 286 }
mitsarionas 6:4596aaa1a824 287
mitsarionas 6:4596aaa1a824 288 // -----------------------------------------------------------------------------------------------------------------------
mitsarionas 6:4596aaa1a824 289 int fill_Thing_Keys(Yodiwo_Plegma_Thing_t *thing, char *nodeKey, int thingId)
mitsarionas 6:4596aaa1a824 290 {
mitsarionas 6:4596aaa1a824 291 int i;
mitsarionas 6:4596aaa1a824 292 int r;
mitsarionas 6:4596aaa1a824 293 r = fill_ThingKey(thing, nodeKey, thingId);
mitsarionas 6:4596aaa1a824 294 if (r < 0)
mitsarionas 6:4596aaa1a824 295 return -1;
mitsarionas 6:4596aaa1a824 296 for (i = 0; i < thing->Ports.num; i++) {
mitsarionas 6:4596aaa1a824 297 r = fill_PortKey(&thing->Ports.elems[i], thing->ThingKey, i + 1);
mitsarionas 6:4596aaa1a824 298 if (r < 0)
mitsarionas 6:4596aaa1a824 299 return -1;
mitsarionas 6:4596aaa1a824 300 }
mitsarionas 6:4596aaa1a824 301 return 0;
mitsarionas 6:4596aaa1a824 302 }
mitsarionas 6:4596aaa1a824 303