Changes to enabled on-line compiler

Committer:
JMF
Date:
Wed May 30 20:59:51 2018 +0000
Revision:
0:082731ede69f
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 0:082731ede69f 1 /*
JMF 0:082731ede69f 2 * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
JMF 0:082731ede69f 3 *
JMF 0:082731ede69f 4 * Licensed under the Apache License, Version 2.0 (the "License").
JMF 0:082731ede69f 5 * You may not use this file except in compliance with the License.
JMF 0:082731ede69f 6 * A copy of the License is located at
JMF 0:082731ede69f 7 *
JMF 0:082731ede69f 8 * http://aws.amazon.com/apache2.0
JMF 0:082731ede69f 9 *
JMF 0:082731ede69f 10 * or in the "license" file accompanying this file. This file is distributed
JMF 0:082731ede69f 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
JMF 0:082731ede69f 12 * express or implied. See the License for the specific language governing
JMF 0:082731ede69f 13 * permissions and limitations under the License.
JMF 0:082731ede69f 14 */
JMF 0:082731ede69f 15
JMF 0:082731ede69f 16 /**
JMF 0:082731ede69f 17 * @file aws_json_utils.c
JMF 0:082731ede69f 18 * @brief Utilities for manipulating JSON
JMF 0:082731ede69f 19 *
JMF 0:082731ede69f 20 * json_utils provides JSON parsing utilities for use with the IoT SDK.
JMF 0:082731ede69f 21 * Underlying JSON parsing relies on the Jasmine JSON parser.
JMF 0:082731ede69f 22 *
JMF 0:082731ede69f 23 */
JMF 0:082731ede69f 24
JMF 0:082731ede69f 25 #ifdef __cplusplus
JMF 0:082731ede69f 26 extern "C" {
JMF 0:082731ede69f 27 #endif
JMF 0:082731ede69f 28
JMF 0:082731ede69f 29 #include "aws_iot_json_utils.h"
JMF 0:082731ede69f 30
JMF 0:082731ede69f 31 #include <stdio.h>
JMF 0:082731ede69f 32 #include <stdint.h>
JMF 0:082731ede69f 33 #include <string.h>
JMF 0:082731ede69f 34
JMF 0:082731ede69f 35 #include "aws_iot_log.h"
JMF 0:082731ede69f 36
JMF 0:082731ede69f 37 int8_t jsoneq(const char *json, jsmntok_t *tok, const char *s) {
JMF 0:082731ede69f 38 if(tok->type == JSMN_STRING) {
JMF 0:082731ede69f 39 if((int) strlen(s) == tok->end - tok->start) {
JMF 0:082731ede69f 40 if(strncmp(json + tok->start, s, (size_t) (tok->end - tok->start)) == 0) {
JMF 0:082731ede69f 41 return 0;
JMF 0:082731ede69f 42 }
JMF 0:082731ede69f 43 }
JMF 0:082731ede69f 44 }
JMF 0:082731ede69f 45 return -1;
JMF 0:082731ede69f 46 }
JMF 0:082731ede69f 47
JMF 0:082731ede69f 48 IoT_Error_t parseUnsignedInteger32Value(uint32_t *i, const char *jsonString, jsmntok_t *token) {
JMF 0:082731ede69f 49 if(token->type != JSMN_PRIMITIVE) {
JMF 0:082731ede69f 50 IOT_WARN("Token was not an integer");
JMF 0:082731ede69f 51 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 52 }
JMF 0:082731ede69f 53
JMF 0:082731ede69f 54 if(('-' == (char) (jsonString[token->start])) || (1 != sscanf(jsonString + token->start, "%lu", i))) {
JMF 0:082731ede69f 55 IOT_WARN("Token was not an unsigned integer.");
JMF 0:082731ede69f 56 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 57 }
JMF 0:082731ede69f 58
JMF 0:082731ede69f 59 return AWS_SUCCESS;
JMF 0:082731ede69f 60 }
JMF 0:082731ede69f 61
JMF 0:082731ede69f 62 IoT_Error_t parseUnsignedInteger16Value(uint16_t *i, const char *jsonString, jsmntok_t *token) {
JMF 0:082731ede69f 63 if(token->type != JSMN_PRIMITIVE) {
JMF 0:082731ede69f 64 IOT_WARN("Token was not an integer");
JMF 0:082731ede69f 65 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 66 }
JMF 0:082731ede69f 67
JMF 0:082731ede69f 68 if(('-' == (char) (jsonString[token->start])) || (1 != sscanf(jsonString + token->start, "%hu", i))) {
JMF 0:082731ede69f 69 IOT_WARN("Token was not an unsigned integer.");
JMF 0:082731ede69f 70 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 71 }
JMF 0:082731ede69f 72
JMF 0:082731ede69f 73 return AWS_SUCCESS;
JMF 0:082731ede69f 74 }
JMF 0:082731ede69f 75
JMF 0:082731ede69f 76 IoT_Error_t parseUnsignedInteger8Value(uint8_t *i, const char *jsonString, jsmntok_t *token) {
JMF 0:082731ede69f 77 if(token->type != JSMN_PRIMITIVE) {
JMF 0:082731ede69f 78 IOT_WARN("Token was not an integer");
JMF 0:082731ede69f 79 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 80 }
JMF 0:082731ede69f 81
JMF 0:082731ede69f 82 if(('-' == (char) (jsonString[token->start])) || (1 != sscanf(jsonString + token->start, "%hhu", i))) {
JMF 0:082731ede69f 83 IOT_WARN("Token was not an unsigned integer.");
JMF 0:082731ede69f 84 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 85 }
JMF 0:082731ede69f 86
JMF 0:082731ede69f 87 return AWS_SUCCESS;
JMF 0:082731ede69f 88 }
JMF 0:082731ede69f 89
JMF 0:082731ede69f 90 IoT_Error_t parseInteger32Value(int32_t *i, const char *jsonString, jsmntok_t *token) {
JMF 0:082731ede69f 91 if(token->type != JSMN_PRIMITIVE) {
JMF 0:082731ede69f 92 IOT_WARN("Token was not an integer");
JMF 0:082731ede69f 93 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 94 }
JMF 0:082731ede69f 95
JMF 0:082731ede69f 96 if(1 != sscanf(jsonString + token->start, "%li", i)) {
JMF 0:082731ede69f 97 IOT_WARN("Token was not an integer.");
JMF 0:082731ede69f 98 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 99 }
JMF 0:082731ede69f 100
JMF 0:082731ede69f 101 return AWS_SUCCESS;
JMF 0:082731ede69f 102 }
JMF 0:082731ede69f 103
JMF 0:082731ede69f 104 IoT_Error_t parseInteger16Value(int16_t *i, const char *jsonString, jsmntok_t *token) {
JMF 0:082731ede69f 105 if(token->type != JSMN_PRIMITIVE) {
JMF 0:082731ede69f 106 IOT_WARN("Token was not an integer");
JMF 0:082731ede69f 107 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 108 }
JMF 0:082731ede69f 109
JMF 0:082731ede69f 110 if(1 != sscanf(jsonString + token->start, "%hi", i)) {
JMF 0:082731ede69f 111 IOT_WARN("Token was not an integer.");
JMF 0:082731ede69f 112 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 113 }
JMF 0:082731ede69f 114
JMF 0:082731ede69f 115 return AWS_SUCCESS;
JMF 0:082731ede69f 116 }
JMF 0:082731ede69f 117
JMF 0:082731ede69f 118 IoT_Error_t parseInteger8Value(int8_t *i, const char *jsonString, jsmntok_t *token) {
JMF 0:082731ede69f 119 if(token->type != JSMN_PRIMITIVE) {
JMF 0:082731ede69f 120 IOT_WARN("Token was not an integer");
JMF 0:082731ede69f 121 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 122 }
JMF 0:082731ede69f 123
JMF 0:082731ede69f 124 if(1 != sscanf(jsonString + token->start, "%hhi", i)) {
JMF 0:082731ede69f 125 IOT_WARN("Token was not an integer.");
JMF 0:082731ede69f 126 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 127 }
JMF 0:082731ede69f 128
JMF 0:082731ede69f 129 return AWS_SUCCESS;
JMF 0:082731ede69f 130 }
JMF 0:082731ede69f 131
JMF 0:082731ede69f 132 IoT_Error_t parseFloatValue(float *f, const char *jsonString, jsmntok_t *token) {
JMF 0:082731ede69f 133 if(token->type != JSMN_PRIMITIVE) {
JMF 0:082731ede69f 134 IOT_WARN("Token was not a float.");
JMF 0:082731ede69f 135 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 136 }
JMF 0:082731ede69f 137
JMF 0:082731ede69f 138 if(1 != sscanf(jsonString + token->start, "%f", f)) {
JMF 0:082731ede69f 139 IOT_WARN("Token was not a float.");
JMF 0:082731ede69f 140 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 141 }
JMF 0:082731ede69f 142
JMF 0:082731ede69f 143 return AWS_SUCCESS;
JMF 0:082731ede69f 144 }
JMF 0:082731ede69f 145
JMF 0:082731ede69f 146 IoT_Error_t parseDoubleValue(double *d, const char *jsonString, jsmntok_t *token) {
JMF 0:082731ede69f 147 if(token->type != JSMN_PRIMITIVE) {
JMF 0:082731ede69f 148 IOT_WARN("Token was not a double.");
JMF 0:082731ede69f 149 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 150 }
JMF 0:082731ede69f 151
JMF 0:082731ede69f 152 if(1 != sscanf(jsonString + token->start, "%lf", d)) {
JMF 0:082731ede69f 153 IOT_WARN("Token was not a double.");
JMF 0:082731ede69f 154 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 155 }
JMF 0:082731ede69f 156
JMF 0:082731ede69f 157 return AWS_SUCCESS;
JMF 0:082731ede69f 158 }
JMF 0:082731ede69f 159
JMF 0:082731ede69f 160 IoT_Error_t parseBooleanValue(bool *b, const char *jsonString, jsmntok_t *token) {
JMF 0:082731ede69f 161 if(token->type != JSMN_PRIMITIVE) {
JMF 0:082731ede69f 162 IOT_WARN("Token was not a primitive.");
JMF 0:082731ede69f 163 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 164 }
JMF 0:082731ede69f 165 if(strncmp(jsonString + token->start, "true", 4) == 0) {
JMF 0:082731ede69f 166 *b = true;
JMF 0:082731ede69f 167 } else if(strncmp(jsonString + token->start, "false", 5) == 0) {
JMF 0:082731ede69f 168 *b = false;
JMF 0:082731ede69f 169 } else {
JMF 0:082731ede69f 170 IOT_WARN("Token was not a bool.");
JMF 0:082731ede69f 171 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 172 }
JMF 0:082731ede69f 173 return AWS_SUCCESS;
JMF 0:082731ede69f 174 }
JMF 0:082731ede69f 175
JMF 0:082731ede69f 176 IoT_Error_t parseStringValue(char *buf, size_t bufLen, const char *jsonString, jsmntok_t *token) {
JMF 0:082731ede69f 177 /* This length does not include a null-terminator. */
JMF 0:082731ede69f 178 size_t stringLength = (size_t)(token->end - token->start);
JMF 0:082731ede69f 179
JMF 0:082731ede69f 180 if(token->type != JSMN_STRING) {
JMF 0:082731ede69f 181 IOT_WARN("Token was not a string.");
JMF 0:082731ede69f 182 return JSON_PARSE_ERROR;
JMF 0:082731ede69f 183 }
JMF 0:082731ede69f 184
JMF 0:082731ede69f 185 if (stringLength+1 > bufLen) {
JMF 0:082731ede69f 186 IOT_WARN("Buffer too small to hold string value.");
JMF 0:082731ede69f 187 return SHADOW_JSON_ERROR;
JMF 0:082731ede69f 188 }
JMF 0:082731ede69f 189
JMF 0:082731ede69f 190 strncpy(buf, jsonString + token->start, stringLength);
JMF 0:082731ede69f 191 buf[stringLength] = '\0';
JMF 0:082731ede69f 192
JMF 0:082731ede69f 193 return AWS_SUCCESS;
JMF 0:082731ede69f 194 }
JMF 0:082731ede69f 195
JMF 0:082731ede69f 196 jsmntok_t *findToken(const char *key, const char *jsonString, jsmntok_t *token) {
JMF 0:082731ede69f 197 jsmntok_t *result = token;
JMF 0:082731ede69f 198 int i;
JMF 0:082731ede69f 199
JMF 0:082731ede69f 200 if(token->type != JSMN_OBJECT) {
JMF 0:082731ede69f 201 IOT_WARN("Token was not an object.");
JMF 0:082731ede69f 202 return NULL;
JMF 0:082731ede69f 203 }
JMF 0:082731ede69f 204
JMF 0:082731ede69f 205 if(token->size == 0) {
JMF 0:082731ede69f 206 return NULL;
JMF 0:082731ede69f 207 }
JMF 0:082731ede69f 208
JMF 0:082731ede69f 209 result = token + 1;
JMF 0:082731ede69f 210
JMF 0:082731ede69f 211 for (i = 0; i < token->size; i++) {
JMF 0:082731ede69f 212 if (0 == jsoneq(jsonString, result, key)) {
JMF 0:082731ede69f 213 return result + 1;
JMF 0:082731ede69f 214 }
JMF 0:082731ede69f 215
JMF 0:082731ede69f 216 int propertyEnd = (result + 1)->end;
JMF 0:082731ede69f 217 result += 2;
JMF 0:082731ede69f 218 while (result->start < propertyEnd)
JMF 0:082731ede69f 219 result++;
JMF 0:082731ede69f 220 }
JMF 0:082731ede69f 221
JMF 0:082731ede69f 222 return NULL;
JMF 0:082731ede69f 223 }
JMF 0:082731ede69f 224
JMF 0:082731ede69f 225 #ifdef __cplusplus
JMF 0:082731ede69f 226 }
JMF 0:082731ede69f 227 #endif