CITY3032-wifi-mqtt

Committer:
reedas
Date:
Sat Nov 13 12:02:49 2021 +0000
Revision:
5:f62a9e4a499a
Parent:
4:7ebc3d28bcb2
trying to include mbed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
reedas 4:7ebc3d28bcb2 1 /*
reedas 4:7ebc3d28bcb2 2 * Copyright 2019-2021, Cypress Semiconductor Corporation (an Infineon company) or
reedas 4:7ebc3d28bcb2 3 * an affiliate of Cypress Semiconductor Corporation. All rights reserved.
reedas 4:7ebc3d28bcb2 4 *
reedas 4:7ebc3d28bcb2 5 * This software, including source code, documentation and related
reedas 4:7ebc3d28bcb2 6 * materials ("Software") is owned by Cypress Semiconductor Corporation
reedas 4:7ebc3d28bcb2 7 * or one of its affiliates ("Cypress") and is protected by and subject to
reedas 4:7ebc3d28bcb2 8 * worldwide patent protection (United States and foreign),
reedas 4:7ebc3d28bcb2 9 * United States copyright laws and international treaty provisions.
reedas 4:7ebc3d28bcb2 10 * Therefore, you may use this Software only as provided in the license
reedas 4:7ebc3d28bcb2 11 * agreement accompanying the software package from which you
reedas 4:7ebc3d28bcb2 12 * obtained this Software ("EULA").
reedas 4:7ebc3d28bcb2 13 * If no EULA applies, Cypress hereby grants you a personal, non-exclusive,
reedas 4:7ebc3d28bcb2 14 * non-transferable license to copy, modify, and compile the Software
reedas 4:7ebc3d28bcb2 15 * source code solely for use in connection with Cypress's
reedas 4:7ebc3d28bcb2 16 * integrated circuit products. Any reproduction, modification, translation,
reedas 4:7ebc3d28bcb2 17 * compilation, or representation of this Software except as specified
reedas 4:7ebc3d28bcb2 18 * above is prohibited without the express written permission of Cypress.
reedas 4:7ebc3d28bcb2 19 *
reedas 4:7ebc3d28bcb2 20 * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND,
reedas 4:7ebc3d28bcb2 21 * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
reedas 4:7ebc3d28bcb2 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress
reedas 4:7ebc3d28bcb2 23 * reserves the right to make changes to the Software without notice. Cypress
reedas 4:7ebc3d28bcb2 24 * does not assume any liability arising out of the application or use of the
reedas 4:7ebc3d28bcb2 25 * Software or any product or circuit described in the Software. Cypress does
reedas 4:7ebc3d28bcb2 26 * not authorize its products for use in any products where a malfunction or
reedas 4:7ebc3d28bcb2 27 * failure of the Cypress product may reasonably be expected to result in
reedas 4:7ebc3d28bcb2 28 * significant property damage, injury or death ("High Risk Product"). By
reedas 4:7ebc3d28bcb2 29 * including Cypress's product in a High Risk Product, the manufacturer
reedas 4:7ebc3d28bcb2 30 * of such system or application assumes all risk of such use and in doing
reedas 4:7ebc3d28bcb2 31 * so agrees to indemnify Cypress against all liability.
reedas 4:7ebc3d28bcb2 32 */
reedas 4:7ebc3d28bcb2 33
reedas 4:7ebc3d28bcb2 34 /** @file
reedas 4:7ebc3d28bcb2 35 *
reedas 4:7ebc3d28bcb2 36 */
reedas 4:7ebc3d28bcb2 37 #include "cy_json_parser.h"
reedas 4:7ebc3d28bcb2 38 #include <stddef.h>
reedas 4:7ebc3d28bcb2 39 #include <string.h>
reedas 4:7ebc3d28bcb2 40 #include <stdlib.h>
reedas 4:7ebc3d28bcb2 41 /******************************************************
reedas 4:7ebc3d28bcb2 42 * Macros
reedas 4:7ebc3d28bcb2 43 ******************************************************/
reedas 4:7ebc3d28bcb2 44
reedas 4:7ebc3d28bcb2 45 #define MAX_BACKUP_SIZE 500
reedas 4:7ebc3d28bcb2 46 #define MAX_PARENTS 4
reedas 4:7ebc3d28bcb2 47
reedas 4:7ebc3d28bcb2 48 /******************************************************
reedas 4:7ebc3d28bcb2 49 * Constants
reedas 4:7ebc3d28bcb2 50 ******************************************************/
reedas 4:7ebc3d28bcb2 51
reedas 4:7ebc3d28bcb2 52 /******************************************************
reedas 4:7ebc3d28bcb2 53 * Enumerations
reedas 4:7ebc3d28bcb2 54 ******************************************************/
reedas 4:7ebc3d28bcb2 55
reedas 4:7ebc3d28bcb2 56 /******************************************************
reedas 4:7ebc3d28bcb2 57 * Type Definitions
reedas 4:7ebc3d28bcb2 58 ******************************************************/
reedas 4:7ebc3d28bcb2 59
reedas 4:7ebc3d28bcb2 60 /******************************************************
reedas 4:7ebc3d28bcb2 61 * Structures
reedas 4:7ebc3d28bcb2 62 ******************************************************/
reedas 4:7ebc3d28bcb2 63
reedas 4:7ebc3d28bcb2 64 /******************************************************
reedas 4:7ebc3d28bcb2 65 * Static Function Declarations
reedas 4:7ebc3d28bcb2 66 ******************************************************/
reedas 4:7ebc3d28bcb2 67
reedas 4:7ebc3d28bcb2 68 static cy_rslt_t validate_array_value( char* start, char* stop, uint8_t len );
reedas 4:7ebc3d28bcb2 69
reedas 4:7ebc3d28bcb2 70 /******************************************************
reedas 4:7ebc3d28bcb2 71 * Variable Definitions
reedas 4:7ebc3d28bcb2 72 ******************************************************/
reedas 4:7ebc3d28bcb2 73 static cy_JSON_callback_t internal_json_callback;
reedas 4:7ebc3d28bcb2 74 static void *internal_json_argument;
reedas 4:7ebc3d28bcb2 75
reedas 4:7ebc3d28bcb2 76 static char* previous_token = NULL;
reedas 4:7ebc3d28bcb2 77 static cy_JSON_object_t json_object =
reedas 4:7ebc3d28bcb2 78 {
reedas 4:7ebc3d28bcb2 79 .object_string = NULL,
reedas 4:7ebc3d28bcb2 80 .object_string_length = 0,
reedas 4:7ebc3d28bcb2 81 .value_type = UNKNOWN_JSON_TYPE,
reedas 4:7ebc3d28bcb2 82 .value = NULL,
reedas 4:7ebc3d28bcb2 83 .value_length = 0,
reedas 4:7ebc3d28bcb2 84 .intval = 0,
reedas 4:7ebc3d28bcb2 85 .floatval = 0.0,
reedas 4:7ebc3d28bcb2 86 .boolval = true,
reedas 4:7ebc3d28bcb2 87 .parent_object = NULL
reedas 4:7ebc3d28bcb2 88 };
reedas 4:7ebc3d28bcb2 89
reedas 4:7ebc3d28bcb2 90 static int32_t parent_counter = 0;
reedas 4:7ebc3d28bcb2 91 static cy_JSON_object_t parent_json_object[ MAX_PARENTS ];
reedas 4:7ebc3d28bcb2 92
reedas 4:7ebc3d28bcb2 93 static bool incomplete_response = false;
reedas 4:7ebc3d28bcb2 94
reedas 4:7ebc3d28bcb2 95 static int32_t object_counter = 0;
reedas 4:7ebc3d28bcb2 96
reedas 4:7ebc3d28bcb2 97 static char* string_start = NULL;
reedas 4:7ebc3d28bcb2 98 static char* string_end = NULL;
reedas 4:7ebc3d28bcb2 99
reedas 4:7ebc3d28bcb2 100 static char* value_start = NULL;
reedas 4:7ebc3d28bcb2 101 static char* value_end = NULL;
reedas 4:7ebc3d28bcb2 102
reedas 4:7ebc3d28bcb2 103 static cy_JSON_type_t type = UNKNOWN_JSON_TYPE;
reedas 4:7ebc3d28bcb2 104
reedas 4:7ebc3d28bcb2 105 static char* current_input_token;
reedas 4:7ebc3d28bcb2 106 static char* end_of_input;
reedas 4:7ebc3d28bcb2 107
reedas 4:7ebc3d28bcb2 108 static char* most_recent_object_marker = NULL;
reedas 4:7ebc3d28bcb2 109
reedas 4:7ebc3d28bcb2 110 char packet_backup[ MAX_BACKUP_SIZE ];
reedas 4:7ebc3d28bcb2 111
reedas 4:7ebc3d28bcb2 112 uint32_t number_of_bytes_backed_up;
reedas 4:7ebc3d28bcb2 113
reedas 4:7ebc3d28bcb2 114 static bool escape_token = false;
reedas 4:7ebc3d28bcb2 115 static int32_t array_counter = 0;
reedas 4:7ebc3d28bcb2 116
reedas 4:7ebc3d28bcb2 117 /******************************************************
reedas 4:7ebc3d28bcb2 118 * Function Definitions
reedas 4:7ebc3d28bcb2 119 ******************************************************/
reedas 4:7ebc3d28bcb2 120 /* This function converts a string to appropriate format if the type is either
reedas 4:7ebc3d28bcb2 121 * a JSON_NUMBER_TYPE or JSON_BOOLEAN_TYPE
reedas 4:7ebc3d28bcb2 122 */
reedas 4:7ebc3d28bcb2 123 static void str_convertor( cy_JSON_object_t* json_object )
reedas 4:7ebc3d28bcb2 124 {
reedas 4:7ebc3d28bcb2 125 if( json_object->value_type == JSON_NUMBER_TYPE )
reedas 4:7ebc3d28bcb2 126 {
reedas 4:7ebc3d28bcb2 127 int i = 0;
reedas 4:7ebc3d28bcb2 128 for( i=0; i<json_object->value_length; i++ )
reedas 4:7ebc3d28bcb2 129 {
reedas 4:7ebc3d28bcb2 130 if( json_object->value[i] == '.' )
reedas 4:7ebc3d28bcb2 131 {
reedas 4:7ebc3d28bcb2 132 json_object->floatval = strtof( json_object->value, NULL );
reedas 4:7ebc3d28bcb2 133 json_object->value_type = JSON_FLOAT_TYPE;
reedas 4:7ebc3d28bcb2 134 return;
reedas 4:7ebc3d28bcb2 135 }
reedas 4:7ebc3d28bcb2 136 }
reedas 4:7ebc3d28bcb2 137 json_object->intval = strtol( json_object->value, NULL, 10 );
reedas 4:7ebc3d28bcb2 138 }
reedas 4:7ebc3d28bcb2 139 else if( json_object->value_type == JSON_BOOLEAN_TYPE )
reedas 4:7ebc3d28bcb2 140 {
reedas 4:7ebc3d28bcb2 141 if( json_object->value[0] == 't' )
reedas 4:7ebc3d28bcb2 142 {
reedas 4:7ebc3d28bcb2 143 json_object->boolval = true;
reedas 4:7ebc3d28bcb2 144 }
reedas 4:7ebc3d28bcb2 145 else
reedas 4:7ebc3d28bcb2 146 {
reedas 4:7ebc3d28bcb2 147 json_object->boolval = false;
reedas 4:7ebc3d28bcb2 148 }
reedas 4:7ebc3d28bcb2 149 }
reedas 4:7ebc3d28bcb2 150 }
reedas 4:7ebc3d28bcb2 151 static cy_rslt_t validate_array_value( char* start, char* stop, uint8_t len )
reedas 4:7ebc3d28bcb2 152 {
reedas 4:7ebc3d28bcb2 153 char* temp = NULL;
reedas 4:7ebc3d28bcb2 154 uint8_t e_count = 0;
reedas 4:7ebc3d28bcb2 155 uint8_t dot = 0;
reedas 4:7ebc3d28bcb2 156 uint8_t minus = 0;
reedas 4:7ebc3d28bcb2 157 uint8_t plus = 0;
reedas 4:7ebc3d28bcb2 158
reedas 4:7ebc3d28bcb2 159 /* TODO : Cases to be handled for example : e+- e.+1 .e-+2 -1.234e-3 */
reedas 4:7ebc3d28bcb2 160
reedas 4:7ebc3d28bcb2 161 if ( ( *start == 'f' ) && ( len == 5 ) )
reedas 4:7ebc3d28bcb2 162 {
reedas 4:7ebc3d28bcb2 163 if ( !strncmp( (const char*) start, "false", ( sizeof( "false" ) - 1 ) ) )
reedas 4:7ebc3d28bcb2 164 {
reedas 4:7ebc3d28bcb2 165 return CY_RSLT_SUCCESS;
reedas 4:7ebc3d28bcb2 166 }
reedas 4:7ebc3d28bcb2 167 else
reedas 4:7ebc3d28bcb2 168 {
reedas 4:7ebc3d28bcb2 169 return CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 170 }
reedas 4:7ebc3d28bcb2 171 }
reedas 4:7ebc3d28bcb2 172 if ( ( *start == 't' ) && ( len == 4 ) )
reedas 4:7ebc3d28bcb2 173 {
reedas 4:7ebc3d28bcb2 174 if ( !strncmp( (const char*) start, "true", ( sizeof( "true" ) - 1 ) ) )
reedas 4:7ebc3d28bcb2 175 {
reedas 4:7ebc3d28bcb2 176 return CY_RSLT_SUCCESS;
reedas 4:7ebc3d28bcb2 177 }
reedas 4:7ebc3d28bcb2 178 else
reedas 4:7ebc3d28bcb2 179 {
reedas 4:7ebc3d28bcb2 180 return CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 181 }
reedas 4:7ebc3d28bcb2 182 }
reedas 4:7ebc3d28bcb2 183 if ( ( *start == 'n' ) && ( len == 4 ) )
reedas 4:7ebc3d28bcb2 184 {
reedas 4:7ebc3d28bcb2 185 if ( !strncmp( (const char*) start, "null", ( sizeof( "null" ) - 1 ) ) )
reedas 4:7ebc3d28bcb2 186 {
reedas 4:7ebc3d28bcb2 187 return CY_RSLT_SUCCESS;
reedas 4:7ebc3d28bcb2 188 }
reedas 4:7ebc3d28bcb2 189 else
reedas 4:7ebc3d28bcb2 190 {
reedas 4:7ebc3d28bcb2 191 return CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 192 }
reedas 4:7ebc3d28bcb2 193 }
reedas 4:7ebc3d28bcb2 194
reedas 4:7ebc3d28bcb2 195 temp = start;
reedas 4:7ebc3d28bcb2 196 while ( temp <= stop )
reedas 4:7ebc3d28bcb2 197 {
reedas 4:7ebc3d28bcb2 198 if( *temp == ' ')
reedas 4:7ebc3d28bcb2 199 {
reedas 4:7ebc3d28bcb2 200 temp++;
reedas 4:7ebc3d28bcb2 201 continue;
reedas 4:7ebc3d28bcb2 202 }
reedas 4:7ebc3d28bcb2 203 if( *temp == '\n')
reedas 4:7ebc3d28bcb2 204 {
reedas 4:7ebc3d28bcb2 205 temp++;
reedas 4:7ebc3d28bcb2 206 continue;
reedas 4:7ebc3d28bcb2 207 }
reedas 4:7ebc3d28bcb2 208 if( *temp == '\r')
reedas 4:7ebc3d28bcb2 209 {
reedas 4:7ebc3d28bcb2 210 temp++;
reedas 4:7ebc3d28bcb2 211 continue;
reedas 4:7ebc3d28bcb2 212 }
reedas 4:7ebc3d28bcb2 213
reedas 4:7ebc3d28bcb2 214 switch ( *temp )
reedas 4:7ebc3d28bcb2 215 {
reedas 4:7ebc3d28bcb2 216 case 'e':
reedas 4:7ebc3d28bcb2 217 e_count++;
reedas 4:7ebc3d28bcb2 218 break;
reedas 4:7ebc3d28bcb2 219
reedas 4:7ebc3d28bcb2 220 case '+':
reedas 4:7ebc3d28bcb2 221 plus++;
reedas 4:7ebc3d28bcb2 222 break;
reedas 4:7ebc3d28bcb2 223
reedas 4:7ebc3d28bcb2 224 case '-':
reedas 4:7ebc3d28bcb2 225 minus++;
reedas 4:7ebc3d28bcb2 226 break;
reedas 4:7ebc3d28bcb2 227
reedas 4:7ebc3d28bcb2 228 case '.':
reedas 4:7ebc3d28bcb2 229 dot++;
reedas 4:7ebc3d28bcb2 230 break;
reedas 4:7ebc3d28bcb2 231
reedas 4:7ebc3d28bcb2 232 default:
reedas 4:7ebc3d28bcb2 233 break;
reedas 4:7ebc3d28bcb2 234 }
reedas 4:7ebc3d28bcb2 235
reedas 4:7ebc3d28bcb2 236 if ( !( ( ( *temp >= '0' ) && ( *temp <= '9' ) ) || ( *temp == 'e' ) || ( *temp == '-' ) || ( *temp == '.' ) || ( *temp == '+' ) ) )
reedas 4:7ebc3d28bcb2 237 {
reedas 4:7ebc3d28bcb2 238 return CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 239 }
reedas 4:7ebc3d28bcb2 240
reedas 4:7ebc3d28bcb2 241 if ( ( e_count > 1 ) || ( minus > 1 ) || ( plus > 1 ) || ( dot > 1 ) )
reedas 4:7ebc3d28bcb2 242 {
reedas 4:7ebc3d28bcb2 243 return CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 244 }
reedas 4:7ebc3d28bcb2 245 temp++;
reedas 4:7ebc3d28bcb2 246 }
reedas 4:7ebc3d28bcb2 247
reedas 4:7ebc3d28bcb2 248 return CY_RSLT_SUCCESS;
reedas 4:7ebc3d28bcb2 249 }
reedas 4:7ebc3d28bcb2 250
reedas 4:7ebc3d28bcb2 251
reedas 4:7ebc3d28bcb2 252 /* Register callbacks parser will use to populate fields*/
reedas 4:7ebc3d28bcb2 253 cy_rslt_t cy_JSON_parser_register_callback( cy_JSON_callback_t json_callback, void *arg )
reedas 4:7ebc3d28bcb2 254 {
reedas 4:7ebc3d28bcb2 255 internal_json_callback = json_callback;
reedas 4:7ebc3d28bcb2 256 internal_json_argument = arg;
reedas 4:7ebc3d28bcb2 257
reedas 4:7ebc3d28bcb2 258 return CY_RSLT_SUCCESS;
reedas 4:7ebc3d28bcb2 259 }
reedas 4:7ebc3d28bcb2 260
reedas 4:7ebc3d28bcb2 261
reedas 4:7ebc3d28bcb2 262 /* Get current callback */
reedas 4:7ebc3d28bcb2 263 cy_JSON_callback_t cy_JSON_parser_get_callback( void )
reedas 4:7ebc3d28bcb2 264 {
reedas 4:7ebc3d28bcb2 265 return internal_json_callback;
reedas 4:7ebc3d28bcb2 266 }
reedas 4:7ebc3d28bcb2 267
reedas 4:7ebc3d28bcb2 268
reedas 4:7ebc3d28bcb2 269 cy_rslt_t cy_JSON_parser( const char* json_input, uint32_t input_length )
reedas 4:7ebc3d28bcb2 270 {
reedas 4:7ebc3d28bcb2 271 cy_rslt_t valid_json_string = CY_RSLT_SUCCESS;
reedas 4:7ebc3d28bcb2 272 int space = 0;
reedas 4:7ebc3d28bcb2 273
reedas 4:7ebc3d28bcb2 274 if ( incomplete_response )
reedas 4:7ebc3d28bcb2 275 {
reedas 4:7ebc3d28bcb2 276 // If there is enough room on backup buffer to hold new data and old backed up
reedas 4:7ebc3d28bcb2 277 // data, parse the backup buffer
reedas 4:7ebc3d28bcb2 278 if ( ( input_length + number_of_bytes_backed_up ) < MAX_BACKUP_SIZE )
reedas 4:7ebc3d28bcb2 279 {
reedas 4:7ebc3d28bcb2 280 memcpy( packet_backup + number_of_bytes_backed_up, json_input, input_length );
reedas 4:7ebc3d28bcb2 281 current_input_token = packet_backup;
reedas 4:7ebc3d28bcb2 282 end_of_input = current_input_token + number_of_bytes_backed_up + input_length;
reedas 4:7ebc3d28bcb2 283 }
reedas 4:7ebc3d28bcb2 284 else
reedas 4:7ebc3d28bcb2 285 {
reedas 4:7ebc3d28bcb2 286 // We must drop entire json object from last buffer. Find start of new json object
reedas 4:7ebc3d28bcb2 287 // in new packet, and being parsing from there
reedas 4:7ebc3d28bcb2 288 while ( *json_input != '{' )
reedas 4:7ebc3d28bcb2 289 {
reedas 4:7ebc3d28bcb2 290 json_input++;
reedas 4:7ebc3d28bcb2 291 input_length--;
reedas 4:7ebc3d28bcb2 292 }
reedas 4:7ebc3d28bcb2 293 current_input_token = (char*) json_input;
reedas 4:7ebc3d28bcb2 294 end_of_input = current_input_token + input_length;
reedas 4:7ebc3d28bcb2 295 }
reedas 4:7ebc3d28bcb2 296
reedas 4:7ebc3d28bcb2 297 incomplete_response = false;
reedas 4:7ebc3d28bcb2 298 }
reedas 4:7ebc3d28bcb2 299 else
reedas 4:7ebc3d28bcb2 300 {
reedas 4:7ebc3d28bcb2 301 current_input_token = (char*) json_input;
reedas 4:7ebc3d28bcb2 302 end_of_input = current_input_token + input_length;
reedas 4:7ebc3d28bcb2 303 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 304 }
reedas 4:7ebc3d28bcb2 305
reedas 4:7ebc3d28bcb2 306 while ( *( current_input_token ) == ' ' )
reedas 4:7ebc3d28bcb2 307 {
reedas 4:7ebc3d28bcb2 308 current_input_token++;
reedas 4:7ebc3d28bcb2 309 }
reedas 4:7ebc3d28bcb2 310 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 311
reedas 4:7ebc3d28bcb2 312 if ( ( *( current_input_token ) == OBJECT_START_TOKEN ) || ( *( current_input_token ) == ARRAY_START_TOKEN ) )
reedas 4:7ebc3d28bcb2 313 {
reedas 4:7ebc3d28bcb2 314 /* Parse through entire input */
reedas 4:7ebc3d28bcb2 315 while ( current_input_token < end_of_input )
reedas 4:7ebc3d28bcb2 316 {
reedas 4:7ebc3d28bcb2 317 switch ( *current_input_token )
reedas 4:7ebc3d28bcb2 318 {
reedas 4:7ebc3d28bcb2 319 /* This is a start of object token */
reedas 4:7ebc3d28bcb2 320 case OBJECT_START_TOKEN:
reedas 4:7ebc3d28bcb2 321
reedas 4:7ebc3d28bcb2 322 if ( escape_token )
reedas 4:7ebc3d28bcb2 323 {
reedas 4:7ebc3d28bcb2 324 escape_token = false;
reedas 4:7ebc3d28bcb2 325 break;
reedas 4:7ebc3d28bcb2 326 }
reedas 4:7ebc3d28bcb2 327
reedas 4:7ebc3d28bcb2 328 /* Skip in case we're parsing a string value */
reedas 4:7ebc3d28bcb2 329 if ( ( string_start != NULL ) && ( string_end == NULL ) )
reedas 4:7ebc3d28bcb2 330 {
reedas 4:7ebc3d28bcb2 331 break;
reedas 4:7ebc3d28bcb2 332 }
reedas 4:7ebc3d28bcb2 333
reedas 4:7ebc3d28bcb2 334 /* In case the json is split across packets, record the most recent object market
reedas 4:7ebc3d28bcb2 335 * and copy from this point forward
reedas 4:7ebc3d28bcb2 336 */
reedas 4:7ebc3d28bcb2 337 most_recent_object_marker = current_input_token;
reedas 4:7ebc3d28bcb2 338
reedas 4:7ebc3d28bcb2 339 /* Keep track of the number of objects open */
reedas 4:7ebc3d28bcb2 340 object_counter++;
reedas 4:7ebc3d28bcb2 341
reedas 4:7ebc3d28bcb2 342 type = JSON_OBJECT_TYPE;
reedas 4:7ebc3d28bcb2 343 /* If we have already captured some string value, then this string must represent the name of this object */
reedas 4:7ebc3d28bcb2 344 if ( string_end )
reedas 4:7ebc3d28bcb2 345 {
reedas 4:7ebc3d28bcb2 346 /* prepare JSON object. The object string was already piced up by the start of value token */
reedas 4:7ebc3d28bcb2 347 json_object.value_type = type;
reedas 4:7ebc3d28bcb2 348 json_object.value = NULL;
reedas 4:7ebc3d28bcb2 349 json_object.value_length = 0;
reedas 4:7ebc3d28bcb2 350
reedas 4:7ebc3d28bcb2 351 /* Reset the string and value pointers */
reedas 4:7ebc3d28bcb2 352 string_start = NULL;
reedas 4:7ebc3d28bcb2 353 string_end = NULL;
reedas 4:7ebc3d28bcb2 354 value_start = NULL;
reedas 4:7ebc3d28bcb2 355 value_end = NULL;
reedas 4:7ebc3d28bcb2 356 }
reedas 4:7ebc3d28bcb2 357
reedas 4:7ebc3d28bcb2 358 if ( ( ( json_object.value_type == JSON_ARRAY_TYPE ) || ( json_object.value_type == JSON_OBJECT_TYPE ) ) && ( parent_counter < MAX_PARENTS ) )
reedas 4:7ebc3d28bcb2 359 {
reedas 4:7ebc3d28bcb2 360 parent_json_object[ parent_counter ] = json_object;
reedas 4:7ebc3d28bcb2 361 json_object.parent_object = &parent_json_object[ parent_counter ];
reedas 4:7ebc3d28bcb2 362 parent_counter++;
reedas 4:7ebc3d28bcb2 363 }
reedas 4:7ebc3d28bcb2 364 else if ( *previous_token == COMMA_SEPARATOR )
reedas 4:7ebc3d28bcb2 365 {
reedas 4:7ebc3d28bcb2 366 json_object.parent_object = &parent_json_object[ parent_counter ];
reedas 4:7ebc3d28bcb2 367 parent_counter++;
reedas 4:7ebc3d28bcb2 368 }
reedas 4:7ebc3d28bcb2 369 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 370
reedas 4:7ebc3d28bcb2 371 break;
reedas 4:7ebc3d28bcb2 372
reedas 4:7ebc3d28bcb2 373 /* This is an end of object token */
reedas 4:7ebc3d28bcb2 374 case OBJECT_END_TOKEN:
reedas 4:7ebc3d28bcb2 375
reedas 4:7ebc3d28bcb2 376 if ( escape_token )
reedas 4:7ebc3d28bcb2 377 {
reedas 4:7ebc3d28bcb2 378 escape_token = false;
reedas 4:7ebc3d28bcb2 379 break;
reedas 4:7ebc3d28bcb2 380 }
reedas 4:7ebc3d28bcb2 381
reedas 4:7ebc3d28bcb2 382 /* Skip in case we're parsing a string value */
reedas 4:7ebc3d28bcb2 383 if ( ( string_start != NULL ) && ( string_end == NULL ) )
reedas 4:7ebc3d28bcb2 384 {
reedas 4:7ebc3d28bcb2 385 break;
reedas 4:7ebc3d28bcb2 386 }
reedas 4:7ebc3d28bcb2 387
reedas 4:7ebc3d28bcb2 388 object_counter--;
reedas 4:7ebc3d28bcb2 389
reedas 4:7ebc3d28bcb2 390 if ( *( previous_token ) == COMMA_SEPARATOR )
reedas 4:7ebc3d28bcb2 391 {
reedas 4:7ebc3d28bcb2 392 if ( *( current_input_token ) == ( OBJECT_END_TOKEN ) )
reedas 4:7ebc3d28bcb2 393 {
reedas 4:7ebc3d28bcb2 394 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 395 object_counter = 0;
reedas 4:7ebc3d28bcb2 396 array_counter = 0;
reedas 4:7ebc3d28bcb2 397 return valid_json_string;
reedas 4:7ebc3d28bcb2 398 }
reedas 4:7ebc3d28bcb2 399 }
reedas 4:7ebc3d28bcb2 400 /* Extract final value in object list. If we have already marked the beginning of a value, than this must be final value in object list */
reedas 4:7ebc3d28bcb2 401 if ( value_start )
reedas 4:7ebc3d28bcb2 402 {
reedas 4:7ebc3d28bcb2 403 value_end = current_input_token;
reedas 4:7ebc3d28bcb2 404 /* If previous was a string token, then this must be a string value */
reedas 4:7ebc3d28bcb2 405 if ( *previous_token == STRING_TOKEN )
reedas 4:7ebc3d28bcb2 406 {
reedas 4:7ebc3d28bcb2 407 type = JSON_STRING_TYPE;
reedas 4:7ebc3d28bcb2 408
reedas 4:7ebc3d28bcb2 409 /* Move value token to point prior to string token and to last character of string value*/
reedas 4:7ebc3d28bcb2 410 value_end = previous_token - 1;
reedas 4:7ebc3d28bcb2 411 value_start = string_start + 1;
reedas 4:7ebc3d28bcb2 412 }
reedas 4:7ebc3d28bcb2 413 else if ( *previous_token == TRUE_TOKEN )
reedas 4:7ebc3d28bcb2 414 {
reedas 4:7ebc3d28bcb2 415 type = JSON_BOOLEAN_TYPE;
reedas 4:7ebc3d28bcb2 416
reedas 4:7ebc3d28bcb2 417 value_end = previous_token + sizeof( "true" ) - 2;
reedas 4:7ebc3d28bcb2 418 value_start = previous_token;
reedas 4:7ebc3d28bcb2 419 }
reedas 4:7ebc3d28bcb2 420 else if ( *previous_token == FALSE_TOKEN )
reedas 4:7ebc3d28bcb2 421 {
reedas 4:7ebc3d28bcb2 422 type = JSON_BOOLEAN_TYPE;
reedas 4:7ebc3d28bcb2 423
reedas 4:7ebc3d28bcb2 424 value_end = previous_token + sizeof( "false" ) - 2;
reedas 4:7ebc3d28bcb2 425 value_start = previous_token;
reedas 4:7ebc3d28bcb2 426 }
reedas 4:7ebc3d28bcb2 427 else if ( *previous_token == NULL_TOKEN )
reedas 4:7ebc3d28bcb2 428 {
reedas 4:7ebc3d28bcb2 429 type = JSON_NULL_TYPE;
reedas 4:7ebc3d28bcb2 430 value_end = previous_token + sizeof( "null" ) - 2;
reedas 4:7ebc3d28bcb2 431 value_start = previous_token;
reedas 4:7ebc3d28bcb2 432 }
reedas 4:7ebc3d28bcb2 433 else
reedas 4:7ebc3d28bcb2 434 {
reedas 4:7ebc3d28bcb2 435 char* start = NULL;
reedas 4:7ebc3d28bcb2 436 char* end = NULL;
reedas 4:7ebc3d28bcb2 437 uint8_t len = 0;
reedas 4:7ebc3d28bcb2 438 /* This must be a number value if not string. Arrays would have been picked up already by the end of array token */
reedas 4:7ebc3d28bcb2 439 type = JSON_NUMBER_TYPE;
reedas 4:7ebc3d28bcb2 440
reedas 4:7ebc3d28bcb2 441 end = value_end;
reedas 4:7ebc3d28bcb2 442
reedas 4:7ebc3d28bcb2 443 start = previous_token;
reedas 4:7ebc3d28bcb2 444 start++;
reedas 4:7ebc3d28bcb2 445 end--;
reedas 4:7ebc3d28bcb2 446 while ( *end == ' ' )
reedas 4:7ebc3d28bcb2 447 {
reedas 4:7ebc3d28bcb2 448 end--;
reedas 4:7ebc3d28bcb2 449 }
reedas 4:7ebc3d28bcb2 450 while ( *start == ' ' )
reedas 4:7ebc3d28bcb2 451 {
reedas 4:7ebc3d28bcb2 452 start++;
reedas 4:7ebc3d28bcb2 453 }
reedas 4:7ebc3d28bcb2 454
reedas 4:7ebc3d28bcb2 455 len = end - start + 1;
reedas 4:7ebc3d28bcb2 456
reedas 4:7ebc3d28bcb2 457 if ( validate_array_value( start, end, len ) != CY_RSLT_SUCCESS )
reedas 4:7ebc3d28bcb2 458 {
reedas 4:7ebc3d28bcb2 459 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 460 object_counter = 0;
reedas 4:7ebc3d28bcb2 461 array_counter = 0;
reedas 4:7ebc3d28bcb2 462 return valid_json_string;
reedas 4:7ebc3d28bcb2 463 }
reedas 4:7ebc3d28bcb2 464
reedas 4:7ebc3d28bcb2 465 /* Keep moving the value end token back till you encounter a digit */
reedas 4:7ebc3d28bcb2 466 while ( ( *value_end < '0' ) || ( *value_end > '9' ) )
reedas 4:7ebc3d28bcb2 467 {
reedas 4:7ebc3d28bcb2 468 value_end--;
reedas 4:7ebc3d28bcb2 469 }
reedas 4:7ebc3d28bcb2 470
reedas 4:7ebc3d28bcb2 471 /* Initialise the value_start token with value_end */
reedas 4:7ebc3d28bcb2 472 value_start = value_end;
reedas 4:7ebc3d28bcb2 473
reedas 4:7ebc3d28bcb2 474 /* Move value_start token until we encounter a non-digit value */
reedas 4:7ebc3d28bcb2 475 while ( ( ( *value_start >= '0' ) && ( *value_start <= '9' ) ) || ( *value_start == '.' ) || ( *value_start == '-' ) )
reedas 4:7ebc3d28bcb2 476 {
reedas 4:7ebc3d28bcb2 477 value_start--;
reedas 4:7ebc3d28bcb2 478 }
reedas 4:7ebc3d28bcb2 479
reedas 4:7ebc3d28bcb2 480 /*Point to first number */
reedas 4:7ebc3d28bcb2 481 value_start++;
reedas 4:7ebc3d28bcb2 482 }
reedas 4:7ebc3d28bcb2 483
reedas 4:7ebc3d28bcb2 484 /* Prepare JSON object */
reedas 4:7ebc3d28bcb2 485 json_object.value_type = type;
reedas 4:7ebc3d28bcb2 486 json_object.value = value_start;
reedas 4:7ebc3d28bcb2 487 json_object.value_length = value_end - value_start + 1;
reedas 4:7ebc3d28bcb2 488
reedas 4:7ebc3d28bcb2 489 if ( internal_json_callback != NULL )
reedas 4:7ebc3d28bcb2 490 {
reedas 4:7ebc3d28bcb2 491 str_convertor( &json_object );
reedas 4:7ebc3d28bcb2 492 internal_json_callback( &json_object, internal_json_argument );
reedas 4:7ebc3d28bcb2 493 }
reedas 4:7ebc3d28bcb2 494
reedas 4:7ebc3d28bcb2 495 /* Reset the value pointers */
reedas 4:7ebc3d28bcb2 496 value_start = NULL;
reedas 4:7ebc3d28bcb2 497 value_end = NULL;
reedas 4:7ebc3d28bcb2 498 string_start = NULL;
reedas 4:7ebc3d28bcb2 499 string_end = NULL;
reedas 4:7ebc3d28bcb2 500 type = UNKNOWN_JSON_TYPE;
reedas 4:7ebc3d28bcb2 501 }
reedas 4:7ebc3d28bcb2 502 if ( parent_counter )
reedas 4:7ebc3d28bcb2 503 {
reedas 4:7ebc3d28bcb2 504 parent_counter--;
reedas 4:7ebc3d28bcb2 505
reedas 4:7ebc3d28bcb2 506 if ( parent_counter )
reedas 4:7ebc3d28bcb2 507 {
reedas 4:7ebc3d28bcb2 508 json_object.parent_object = &parent_json_object[ parent_counter - 1 ];
reedas 4:7ebc3d28bcb2 509 }
reedas 4:7ebc3d28bcb2 510 else
reedas 4:7ebc3d28bcb2 511 {
reedas 4:7ebc3d28bcb2 512 json_object.parent_object = &parent_json_object[ parent_counter ];
reedas 4:7ebc3d28bcb2 513 }
reedas 4:7ebc3d28bcb2 514 }
reedas 4:7ebc3d28bcb2 515 else
reedas 4:7ebc3d28bcb2 516 {
reedas 4:7ebc3d28bcb2 517 json_object.parent_object = NULL;
reedas 4:7ebc3d28bcb2 518 }
reedas 4:7ebc3d28bcb2 519 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 520
reedas 4:7ebc3d28bcb2 521 break;
reedas 4:7ebc3d28bcb2 522
reedas 4:7ebc3d28bcb2 523 case STRING_TOKEN:
reedas 4:7ebc3d28bcb2 524
reedas 4:7ebc3d28bcb2 525 if ( escape_token )
reedas 4:7ebc3d28bcb2 526 {
reedas 4:7ebc3d28bcb2 527 escape_token = false;
reedas 4:7ebc3d28bcb2 528 break;
reedas 4:7ebc3d28bcb2 529 }
reedas 4:7ebc3d28bcb2 530 /* This indicates this must be closing token for object name */
reedas 4:7ebc3d28bcb2 531 if ( *previous_token == STRING_TOKEN )
reedas 4:7ebc3d28bcb2 532 {
reedas 4:7ebc3d28bcb2 533 /* Get the last character of the string name */
reedas 4:7ebc3d28bcb2 534 string_end = current_input_token;
reedas 4:7ebc3d28bcb2 535 }
reedas 4:7ebc3d28bcb2 536 else
reedas 4:7ebc3d28bcb2 537 {
reedas 4:7ebc3d28bcb2 538 /* Find start and end of of object name */
reedas 4:7ebc3d28bcb2 539 string_start = current_input_token;
reedas 4:7ebc3d28bcb2 540 string_end = NULL;
reedas 4:7ebc3d28bcb2 541 }
reedas 4:7ebc3d28bcb2 542 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 543
reedas 4:7ebc3d28bcb2 544 break;
reedas 4:7ebc3d28bcb2 545
reedas 4:7ebc3d28bcb2 546 case TRUE_TOKEN:
reedas 4:7ebc3d28bcb2 547 if ( escape_token )
reedas 4:7ebc3d28bcb2 548 {
reedas 4:7ebc3d28bcb2 549 escape_token = false;
reedas 4:7ebc3d28bcb2 550 break;
reedas 4:7ebc3d28bcb2 551 }
reedas 4:7ebc3d28bcb2 552 if ( *previous_token == OBJECT_START_TOKEN )
reedas 4:7ebc3d28bcb2 553 {
reedas 4:7ebc3d28bcb2 554 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 555 object_counter = 0;
reedas 4:7ebc3d28bcb2 556
reedas 4:7ebc3d28bcb2 557 return valid_json_string;
reedas 4:7ebc3d28bcb2 558 }
reedas 4:7ebc3d28bcb2 559 if ( ( *previous_token == START_OF_VALUE ) && ( string_end ) )
reedas 4:7ebc3d28bcb2 560 {
reedas 4:7ebc3d28bcb2 561 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 562 current_input_token = current_input_token + sizeof( "true" ) - 2;
reedas 4:7ebc3d28bcb2 563 }
reedas 4:7ebc3d28bcb2 564
reedas 4:7ebc3d28bcb2 565 break;
reedas 4:7ebc3d28bcb2 566
reedas 4:7ebc3d28bcb2 567 case FALSE_TOKEN:
reedas 4:7ebc3d28bcb2 568 if ( escape_token )
reedas 4:7ebc3d28bcb2 569 {
reedas 4:7ebc3d28bcb2 570 escape_token = false;
reedas 4:7ebc3d28bcb2 571 break;
reedas 4:7ebc3d28bcb2 572 }
reedas 4:7ebc3d28bcb2 573 if ( *previous_token == OBJECT_START_TOKEN )
reedas 4:7ebc3d28bcb2 574 {
reedas 4:7ebc3d28bcb2 575 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 576 object_counter = 0;
reedas 4:7ebc3d28bcb2 577 array_counter = 0;
reedas 4:7ebc3d28bcb2 578 return valid_json_string;
reedas 4:7ebc3d28bcb2 579 }
reedas 4:7ebc3d28bcb2 580 if ( ( *previous_token == START_OF_VALUE ) && ( string_end ) )
reedas 4:7ebc3d28bcb2 581 {
reedas 4:7ebc3d28bcb2 582 /* Skip ahead as this must be boolean false */
reedas 4:7ebc3d28bcb2 583 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 584 current_input_token = current_input_token + sizeof( "false" ) - 2;
reedas 4:7ebc3d28bcb2 585 }
reedas 4:7ebc3d28bcb2 586 break;
reedas 4:7ebc3d28bcb2 587
reedas 4:7ebc3d28bcb2 588 case NULL_TOKEN:
reedas 4:7ebc3d28bcb2 589 if ( escape_token )
reedas 4:7ebc3d28bcb2 590 {
reedas 4:7ebc3d28bcb2 591 escape_token = false;
reedas 4:7ebc3d28bcb2 592 break;
reedas 4:7ebc3d28bcb2 593 }
reedas 4:7ebc3d28bcb2 594 if ( ( *previous_token == START_OF_VALUE ) && ( string_end ) )
reedas 4:7ebc3d28bcb2 595 {
reedas 4:7ebc3d28bcb2 596 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 597 current_input_token = current_input_token + sizeof( "null" ) - 2;
reedas 4:7ebc3d28bcb2 598 }
reedas 4:7ebc3d28bcb2 599 break;
reedas 4:7ebc3d28bcb2 600
reedas 4:7ebc3d28bcb2 601 case ARRAY_START_TOKEN:
reedas 4:7ebc3d28bcb2 602
reedas 4:7ebc3d28bcb2 603 if ( escape_token )
reedas 4:7ebc3d28bcb2 604 {
reedas 4:7ebc3d28bcb2 605 escape_token = false;
reedas 4:7ebc3d28bcb2 606 break;
reedas 4:7ebc3d28bcb2 607 }
reedas 4:7ebc3d28bcb2 608
reedas 4:7ebc3d28bcb2 609 /* Skip in case we're parsing a string value */
reedas 4:7ebc3d28bcb2 610 if ( ( string_start != NULL ) && ( string_end == NULL ) )
reedas 4:7ebc3d28bcb2 611 {
reedas 4:7ebc3d28bcb2 612 break;
reedas 4:7ebc3d28bcb2 613 }
reedas 4:7ebc3d28bcb2 614 else if (string_start == NULL)
reedas 4:7ebc3d28bcb2 615 {
reedas 4:7ebc3d28bcb2 616 json_object.object_string = NULL;
reedas 4:7ebc3d28bcb2 617 json_object.object_string_length = 0;
reedas 4:7ebc3d28bcb2 618 }
reedas 4:7ebc3d28bcb2 619
reedas 4:7ebc3d28bcb2 620 array_counter++;
reedas 4:7ebc3d28bcb2 621 /*This means the last object name must have an array value type*/
reedas 4:7ebc3d28bcb2 622 type = JSON_ARRAY_TYPE;
reedas 4:7ebc3d28bcb2 623
reedas 4:7ebc3d28bcb2 624 json_object.value_type = type;
reedas 4:7ebc3d28bcb2 625 json_object.value = NULL;
reedas 4:7ebc3d28bcb2 626 json_object.value_length = 0;
reedas 4:7ebc3d28bcb2 627
reedas 4:7ebc3d28bcb2 628 if ( internal_json_callback != NULL )
reedas 4:7ebc3d28bcb2 629 {
reedas 4:7ebc3d28bcb2 630 str_convertor( &json_object );
reedas 4:7ebc3d28bcb2 631 internal_json_callback( &json_object, internal_json_argument );
reedas 4:7ebc3d28bcb2 632 }
reedas 4:7ebc3d28bcb2 633
reedas 4:7ebc3d28bcb2 634 /* Reset object string start/end tokens */
reedas 4:7ebc3d28bcb2 635 string_start = NULL;
reedas 4:7ebc3d28bcb2 636 string_end = NULL;
reedas 4:7ebc3d28bcb2 637
reedas 4:7ebc3d28bcb2 638 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 639
reedas 4:7ebc3d28bcb2 640 break;
reedas 4:7ebc3d28bcb2 641
reedas 4:7ebc3d28bcb2 642 case ARRAY_END_TOKEN:
reedas 4:7ebc3d28bcb2 643
reedas 4:7ebc3d28bcb2 644 if ( escape_token )
reedas 4:7ebc3d28bcb2 645 {
reedas 4:7ebc3d28bcb2 646 escape_token = false;
reedas 4:7ebc3d28bcb2 647 break;
reedas 4:7ebc3d28bcb2 648 }
reedas 4:7ebc3d28bcb2 649
reedas 4:7ebc3d28bcb2 650 /* Skip in case we're parsing a string value */
reedas 4:7ebc3d28bcb2 651 if ( ( string_start != NULL ) && ( string_end == NULL ) )
reedas 4:7ebc3d28bcb2 652 {
reedas 4:7ebc3d28bcb2 653 break;
reedas 4:7ebc3d28bcb2 654 }
reedas 4:7ebc3d28bcb2 655
reedas 4:7ebc3d28bcb2 656 array_counter--;
reedas 4:7ebc3d28bcb2 657
reedas 4:7ebc3d28bcb2 658
reedas 4:7ebc3d28bcb2 659 if ( *( previous_token ) == START_OF_VALUE )
reedas 4:7ebc3d28bcb2 660 {
reedas 4:7ebc3d28bcb2 661 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 662 object_counter = 0;
reedas 4:7ebc3d28bcb2 663 return valid_json_string;
reedas 4:7ebc3d28bcb2 664 }
reedas 4:7ebc3d28bcb2 665
reedas 4:7ebc3d28bcb2 666 if ( *( current_input_token - space - 1 ) == COMMA_SEPARATOR )
reedas 4:7ebc3d28bcb2 667 {
reedas 4:7ebc3d28bcb2 668 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 669 object_counter = 0;
reedas 4:7ebc3d28bcb2 670 array_counter = 0;
reedas 4:7ebc3d28bcb2 671 return valid_json_string;
reedas 4:7ebc3d28bcb2 672 }
reedas 4:7ebc3d28bcb2 673
reedas 4:7ebc3d28bcb2 674 /* Ignore comma separators in values */
reedas 4:7ebc3d28bcb2 675 if ( ( string_start ) && ( string_end == NULL ) )
reedas 4:7ebc3d28bcb2 676 {
reedas 4:7ebc3d28bcb2 677 break;
reedas 4:7ebc3d28bcb2 678 }
reedas 4:7ebc3d28bcb2 679 /* If this comma is within an array, it must be delimiting values, so extract the comma delimited value */
reedas 4:7ebc3d28bcb2 680 else if ( type == JSON_ARRAY_TYPE )
reedas 4:7ebc3d28bcb2 681 {
reedas 4:7ebc3d28bcb2 682 /* If the token prior to the comma was a string token, then the delimited value must be a string */
reedas 4:7ebc3d28bcb2 683 if ( *previous_token == STRING_TOKEN )
reedas 4:7ebc3d28bcb2 684 {
reedas 4:7ebc3d28bcb2 685 type = JSON_STRING_TYPE;
reedas 4:7ebc3d28bcb2 686
reedas 4:7ebc3d28bcb2 687 /* Move token to point prior to string token and to last character of string value*/
reedas 4:7ebc3d28bcb2 688 value_end = previous_token - 1;
reedas 4:7ebc3d28bcb2 689 value_start = string_start + 1;
reedas 4:7ebc3d28bcb2 690 }
reedas 4:7ebc3d28bcb2 691 else if ( *previous_token == TRUE_TOKEN )
reedas 4:7ebc3d28bcb2 692 {
reedas 4:7ebc3d28bcb2 693 type = JSON_BOOLEAN_TYPE;
reedas 4:7ebc3d28bcb2 694
reedas 4:7ebc3d28bcb2 695 value_end = previous_token + sizeof( "true" ) - 2;
reedas 4:7ebc3d28bcb2 696 value_start = previous_token;
reedas 4:7ebc3d28bcb2 697 }
reedas 4:7ebc3d28bcb2 698 else if ( *previous_token == FALSE_TOKEN )
reedas 4:7ebc3d28bcb2 699 {
reedas 4:7ebc3d28bcb2 700 type = JSON_BOOLEAN_TYPE;
reedas 4:7ebc3d28bcb2 701
reedas 4:7ebc3d28bcb2 702 value_end = previous_token + sizeof( "false" ) - 2;
reedas 4:7ebc3d28bcb2 703 value_start = previous_token;
reedas 4:7ebc3d28bcb2 704 }
reedas 4:7ebc3d28bcb2 705 else if ( *previous_token == NULL_TOKEN )
reedas 4:7ebc3d28bcb2 706 {
reedas 4:7ebc3d28bcb2 707 type = JSON_NULL_TYPE;
reedas 4:7ebc3d28bcb2 708 value_end = previous_token + sizeof( "null" ) - 2;
reedas 4:7ebc3d28bcb2 709 value_start = previous_token;
reedas 4:7ebc3d28bcb2 710 }
reedas 4:7ebc3d28bcb2 711 else
reedas 4:7ebc3d28bcb2 712 {
reedas 4:7ebc3d28bcb2 713 char* start = NULL;
reedas 4:7ebc3d28bcb2 714 char* end = NULL;
reedas 4:7ebc3d28bcb2 715 uint8_t len = 0;
reedas 4:7ebc3d28bcb2 716 /* Delimited values must be a NUMBER if they are not a string */
reedas 4:7ebc3d28bcb2 717 type = JSON_NUMBER_TYPE;
reedas 4:7ebc3d28bcb2 718
reedas 4:7ebc3d28bcb2 719 /* Set value_end to point to current location */
reedas 4:7ebc3d28bcb2 720 value_end = current_input_token;
reedas 4:7ebc3d28bcb2 721
reedas 4:7ebc3d28bcb2 722 /* This must be a number value if not string. Arrays would have been picked up already by the end of array token */
reedas 4:7ebc3d28bcb2 723 type = JSON_NUMBER_TYPE;
reedas 4:7ebc3d28bcb2 724
reedas 4:7ebc3d28bcb2 725 end = value_end;
reedas 4:7ebc3d28bcb2 726
reedas 4:7ebc3d28bcb2 727 start = previous_token;
reedas 4:7ebc3d28bcb2 728 start++;
reedas 4:7ebc3d28bcb2 729 end--;
reedas 4:7ebc3d28bcb2 730 while ( *end == ' ' )
reedas 4:7ebc3d28bcb2 731 {
reedas 4:7ebc3d28bcb2 732 end--;
reedas 4:7ebc3d28bcb2 733 }
reedas 4:7ebc3d28bcb2 734 while ( *start == ' ' )
reedas 4:7ebc3d28bcb2 735 {
reedas 4:7ebc3d28bcb2 736 start++;
reedas 4:7ebc3d28bcb2 737 }
reedas 4:7ebc3d28bcb2 738
reedas 4:7ebc3d28bcb2 739 len = end - start + 1;
reedas 4:7ebc3d28bcb2 740
reedas 4:7ebc3d28bcb2 741 if ( validate_array_value( start, end, len ) != CY_RSLT_SUCCESS )
reedas 4:7ebc3d28bcb2 742 {
reedas 4:7ebc3d28bcb2 743 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 744 object_counter = 0;
reedas 4:7ebc3d28bcb2 745 array_counter = 0;
reedas 4:7ebc3d28bcb2 746 return valid_json_string;
reedas 4:7ebc3d28bcb2 747 }
reedas 4:7ebc3d28bcb2 748
reedas 4:7ebc3d28bcb2 749 /* Point to last number. Keep moving the value end token back till you encounter a digit */
reedas 4:7ebc3d28bcb2 750 while ( ( *value_end < '0' ) || ( *value_end > '9' ) )
reedas 4:7ebc3d28bcb2 751 {
reedas 4:7ebc3d28bcb2 752 value_end--;
reedas 4:7ebc3d28bcb2 753 }
reedas 4:7ebc3d28bcb2 754
reedas 4:7ebc3d28bcb2 755 /* Initialise the value_start pointer to point to last digit */
reedas 4:7ebc3d28bcb2 756 value_start = value_end;
reedas 4:7ebc3d28bcb2 757
reedas 4:7ebc3d28bcb2 758 /* Increment value_start until you reach first number */
reedas 4:7ebc3d28bcb2 759 while ( ( ( *value_start >= '0' ) && ( *value_start <= '9' ) ) || ( *value_start == '.' ) || ( *value_start == '-' ) )
reedas 4:7ebc3d28bcb2 760 {
reedas 4:7ebc3d28bcb2 761 value_start--;
reedas 4:7ebc3d28bcb2 762 }
reedas 4:7ebc3d28bcb2 763
reedas 4:7ebc3d28bcb2 764 /*Point to first number */
reedas 4:7ebc3d28bcb2 765 value_start++;
reedas 4:7ebc3d28bcb2 766 }
reedas 4:7ebc3d28bcb2 767
reedas 4:7ebc3d28bcb2 768 /* prepare JSON object */
reedas 4:7ebc3d28bcb2 769 json_object.object_string = NULL;
reedas 4:7ebc3d28bcb2 770 json_object.object_string_length = 0;
reedas 4:7ebc3d28bcb2 771 json_object.value_type = type;
reedas 4:7ebc3d28bcb2 772 json_object.value = value_start;
reedas 4:7ebc3d28bcb2 773 json_object.value_length = value_end - value_start + 1;
reedas 4:7ebc3d28bcb2 774
reedas 4:7ebc3d28bcb2 775 if ( internal_json_callback != NULL )
reedas 4:7ebc3d28bcb2 776 {
reedas 4:7ebc3d28bcb2 777 str_convertor( &json_object );
reedas 4:7ebc3d28bcb2 778 internal_json_callback( &json_object, internal_json_argument );
reedas 4:7ebc3d28bcb2 779 }
reedas 4:7ebc3d28bcb2 780
reedas 4:7ebc3d28bcb2 781 string_start = NULL;
reedas 4:7ebc3d28bcb2 782 string_end = NULL;
reedas 4:7ebc3d28bcb2 783 value_start = NULL;
reedas 4:7ebc3d28bcb2 784 value_end = NULL;
reedas 4:7ebc3d28bcb2 785 type = JSON_ARRAY_TYPE;
reedas 4:7ebc3d28bcb2 786 }
reedas 4:7ebc3d28bcb2 787
reedas 4:7ebc3d28bcb2 788 type = UNKNOWN_JSON_TYPE;
reedas 4:7ebc3d28bcb2 789 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 790
reedas 4:7ebc3d28bcb2 791 break;
reedas 4:7ebc3d28bcb2 792
reedas 4:7ebc3d28bcb2 793 case START_OF_VALUE:
reedas 4:7ebc3d28bcb2 794
reedas 4:7ebc3d28bcb2 795 if ( escape_token )
reedas 4:7ebc3d28bcb2 796 {
reedas 4:7ebc3d28bcb2 797 escape_token = false;
reedas 4:7ebc3d28bcb2 798 break;
reedas 4:7ebc3d28bcb2 799 }
reedas 4:7ebc3d28bcb2 800
reedas 4:7ebc3d28bcb2 801 if ( ( *( previous_token ) == OBJECT_START_TOKEN ) || ( *( previous_token ) == ARRAY_START_TOKEN ) )
reedas 4:7ebc3d28bcb2 802 {
reedas 4:7ebc3d28bcb2 803 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 804 object_counter = 0;
reedas 4:7ebc3d28bcb2 805 array_counter = 0;
reedas 4:7ebc3d28bcb2 806 return valid_json_string;
reedas 4:7ebc3d28bcb2 807 }
reedas 4:7ebc3d28bcb2 808 if ( string_end )
reedas 4:7ebc3d28bcb2 809 {
reedas 4:7ebc3d28bcb2 810 /* prepare JSON object */
reedas 4:7ebc3d28bcb2 811 json_object.object_string = string_start + 1;
reedas 4:7ebc3d28bcb2 812 json_object.object_string_length = string_end - string_start - 1;
reedas 4:7ebc3d28bcb2 813 type = UNKNOWN_JSON_TYPE;
reedas 4:7ebc3d28bcb2 814 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 815 }
reedas 4:7ebc3d28bcb2 816 if ( value_start == NULL )
reedas 4:7ebc3d28bcb2 817 {
reedas 4:7ebc3d28bcb2 818 value_start = current_input_token;
reedas 4:7ebc3d28bcb2 819 }
reedas 4:7ebc3d28bcb2 820
reedas 4:7ebc3d28bcb2 821 break;
reedas 4:7ebc3d28bcb2 822
reedas 4:7ebc3d28bcb2 823 case COMMA_SEPARATOR:
reedas 4:7ebc3d28bcb2 824
reedas 4:7ebc3d28bcb2 825 if ( escape_token )
reedas 4:7ebc3d28bcb2 826 {
reedas 4:7ebc3d28bcb2 827 escape_token = false;
reedas 4:7ebc3d28bcb2 828 break;
reedas 4:7ebc3d28bcb2 829 }
reedas 4:7ebc3d28bcb2 830
reedas 4:7ebc3d28bcb2 831 /* Ignore comma separators in values */
reedas 4:7ebc3d28bcb2 832 if ( ( string_start ) && ( string_end == NULL ) )
reedas 4:7ebc3d28bcb2 833 {
reedas 4:7ebc3d28bcb2 834 break;
reedas 4:7ebc3d28bcb2 835 }
reedas 4:7ebc3d28bcb2 836 /* If this comma is within an array, it must be delimiting values, so extract the comma delimited value */
reedas 4:7ebc3d28bcb2 837 else if ( type == JSON_ARRAY_TYPE )
reedas 4:7ebc3d28bcb2 838 {
reedas 4:7ebc3d28bcb2 839 /* If the token prior to the comma was a string token, then the delimited value must be a string */
reedas 4:7ebc3d28bcb2 840 if ( *previous_token == STRING_TOKEN )
reedas 4:7ebc3d28bcb2 841 {
reedas 4:7ebc3d28bcb2 842 type = JSON_STRING_TYPE;
reedas 4:7ebc3d28bcb2 843
reedas 4:7ebc3d28bcb2 844 /* Move token to point prior to string token and to last character of string value*/
reedas 4:7ebc3d28bcb2 845 value_end = previous_token - 1;
reedas 4:7ebc3d28bcb2 846 value_start = string_start + 1;
reedas 4:7ebc3d28bcb2 847 }
reedas 4:7ebc3d28bcb2 848 else if ( *previous_token == TRUE_TOKEN )
reedas 4:7ebc3d28bcb2 849 {
reedas 4:7ebc3d28bcb2 850 type = JSON_BOOLEAN_TYPE;
reedas 4:7ebc3d28bcb2 851
reedas 4:7ebc3d28bcb2 852 value_end = previous_token + sizeof( "true" ) - 2;
reedas 4:7ebc3d28bcb2 853 value_start = previous_token;
reedas 4:7ebc3d28bcb2 854 }
reedas 4:7ebc3d28bcb2 855 else if ( *previous_token == FALSE_TOKEN )
reedas 4:7ebc3d28bcb2 856 {
reedas 4:7ebc3d28bcb2 857 type = JSON_BOOLEAN_TYPE;
reedas 4:7ebc3d28bcb2 858
reedas 4:7ebc3d28bcb2 859 value_end = previous_token + sizeof( "false" ) - 2;
reedas 4:7ebc3d28bcb2 860 value_start = previous_token;
reedas 4:7ebc3d28bcb2 861 }
reedas 4:7ebc3d28bcb2 862 else if ( *previous_token == NULL_TOKEN )
reedas 4:7ebc3d28bcb2 863 {
reedas 4:7ebc3d28bcb2 864 type = JSON_NULL_TYPE;
reedas 4:7ebc3d28bcb2 865 value_end = previous_token + sizeof( "null" ) - 2;
reedas 4:7ebc3d28bcb2 866 value_start = previous_token;
reedas 4:7ebc3d28bcb2 867 }
reedas 4:7ebc3d28bcb2 868 else
reedas 4:7ebc3d28bcb2 869 {
reedas 4:7ebc3d28bcb2 870 /* Delimited values must be a NUMBER if they are not a string */
reedas 4:7ebc3d28bcb2 871 type = JSON_NUMBER_TYPE;
reedas 4:7ebc3d28bcb2 872
reedas 4:7ebc3d28bcb2 873 /* Set value_end to point to current location */
reedas 4:7ebc3d28bcb2 874 value_end = current_input_token;
reedas 4:7ebc3d28bcb2 875
reedas 4:7ebc3d28bcb2 876 /* Point to last number. Keep moving the value end token back till you encounter a digit */
reedas 4:7ebc3d28bcb2 877 while ( ( *value_end < '0' ) || ( *value_end > '9' ) )
reedas 4:7ebc3d28bcb2 878 {
reedas 4:7ebc3d28bcb2 879 value_end--;
reedas 4:7ebc3d28bcb2 880 }
reedas 4:7ebc3d28bcb2 881
reedas 4:7ebc3d28bcb2 882 /* Initialise the value_start pointer to point to last digit */
reedas 4:7ebc3d28bcb2 883 value_start = value_end;
reedas 4:7ebc3d28bcb2 884
reedas 4:7ebc3d28bcb2 885 /* Increment value_start until you reach first number */
reedas 4:7ebc3d28bcb2 886 while ( ( ( ( *value_start >= '0' ) && ( *value_start <= '9' ) ) || ( *value_start == '.' ) || ( *value_start == '-' ) ) && ( *previous_token != *value_start ) )
reedas 4:7ebc3d28bcb2 887 {
reedas 4:7ebc3d28bcb2 888 value_start--;
reedas 4:7ebc3d28bcb2 889 }
reedas 4:7ebc3d28bcb2 890
reedas 4:7ebc3d28bcb2 891 /*Point to first number */
reedas 4:7ebc3d28bcb2 892 value_start++;
reedas 4:7ebc3d28bcb2 893 }
reedas 4:7ebc3d28bcb2 894
reedas 4:7ebc3d28bcb2 895 /* prepare JSON object */
reedas 4:7ebc3d28bcb2 896 json_object.object_string = NULL;
reedas 4:7ebc3d28bcb2 897 json_object.object_string_length = 0;
reedas 4:7ebc3d28bcb2 898 json_object.value_type = type;
reedas 4:7ebc3d28bcb2 899 json_object.value = value_start;
reedas 4:7ebc3d28bcb2 900 json_object.value_length = value_end - value_start + 1;
reedas 4:7ebc3d28bcb2 901
reedas 4:7ebc3d28bcb2 902 if ( internal_json_callback != NULL )
reedas 4:7ebc3d28bcb2 903 {
reedas 4:7ebc3d28bcb2 904 str_convertor( &json_object );
reedas 4:7ebc3d28bcb2 905 internal_json_callback( &json_object, internal_json_argument );
reedas 4:7ebc3d28bcb2 906 }
reedas 4:7ebc3d28bcb2 907 value_start = NULL;
reedas 4:7ebc3d28bcb2 908 value_end = NULL;
reedas 4:7ebc3d28bcb2 909 string_start = NULL;
reedas 4:7ebc3d28bcb2 910 string_end = NULL;
reedas 4:7ebc3d28bcb2 911 type = JSON_ARRAY_TYPE;
reedas 4:7ebc3d28bcb2 912 }
reedas 4:7ebc3d28bcb2 913 else if ( value_start )
reedas 4:7ebc3d28bcb2 914 {
reedas 4:7ebc3d28bcb2 915 value_end = current_input_token;
reedas 4:7ebc3d28bcb2 916
reedas 4:7ebc3d28bcb2 917 /* Commas are only used to seperate values so this must indicate an end of value, which means last object information is for us */
reedas 4:7ebc3d28bcb2 918 if ( *previous_token == STRING_TOKEN )
reedas 4:7ebc3d28bcb2 919 {
reedas 4:7ebc3d28bcb2 920 type = JSON_STRING_TYPE;
reedas 4:7ebc3d28bcb2 921
reedas 4:7ebc3d28bcb2 922 value_end = previous_token - 1;
reedas 4:7ebc3d28bcb2 923 value_start = string_start + 1;
reedas 4:7ebc3d28bcb2 924 }
reedas 4:7ebc3d28bcb2 925 else if ( *previous_token == ARRAY_END_TOKEN )
reedas 4:7ebc3d28bcb2 926 {
reedas 4:7ebc3d28bcb2 927 if ( string_start )
reedas 4:7ebc3d28bcb2 928 {
reedas 4:7ebc3d28bcb2 929 type = JSON_STRING_TYPE;
reedas 4:7ebc3d28bcb2 930 value_start = string_start + 1;
reedas 4:7ebc3d28bcb2 931 value_end = string_end - 1;
reedas 4:7ebc3d28bcb2 932 }
reedas 4:7ebc3d28bcb2 933 else
reedas 4:7ebc3d28bcb2 934 {
reedas 4:7ebc3d28bcb2 935 type = JSON_NUMBER_TYPE;
reedas 4:7ebc3d28bcb2 936
reedas 4:7ebc3d28bcb2 937 /* Keep moving the value end token back till you encounter a digit */
reedas 4:7ebc3d28bcb2 938 while ( ( *value_end < '0' ) || ( *value_end > '9' ) )
reedas 4:7ebc3d28bcb2 939 {
reedas 4:7ebc3d28bcb2 940 value_end--;
reedas 4:7ebc3d28bcb2 941 }
reedas 4:7ebc3d28bcb2 942
reedas 4:7ebc3d28bcb2 943 value_start = value_end;
reedas 4:7ebc3d28bcb2 944
reedas 4:7ebc3d28bcb2 945 while ( ( *value_start >= '0' ) && ( *value_start <= '9' ) )
reedas 4:7ebc3d28bcb2 946 {
reedas 4:7ebc3d28bcb2 947 value_start--;
reedas 4:7ebc3d28bcb2 948 }
reedas 4:7ebc3d28bcb2 949
reedas 4:7ebc3d28bcb2 950 value_start++;
reedas 4:7ebc3d28bcb2 951 }
reedas 4:7ebc3d28bcb2 952 }
reedas 4:7ebc3d28bcb2 953 else if ( *previous_token == TRUE_TOKEN )
reedas 4:7ebc3d28bcb2 954 {
reedas 4:7ebc3d28bcb2 955 type = JSON_BOOLEAN_TYPE;
reedas 4:7ebc3d28bcb2 956
reedas 4:7ebc3d28bcb2 957 value_end = previous_token + sizeof( "true" ) - 2;
reedas 4:7ebc3d28bcb2 958 value_start = previous_token;
reedas 4:7ebc3d28bcb2 959 }
reedas 4:7ebc3d28bcb2 960 else if ( *previous_token == FALSE_TOKEN )
reedas 4:7ebc3d28bcb2 961 {
reedas 4:7ebc3d28bcb2 962 type = JSON_BOOLEAN_TYPE;
reedas 4:7ebc3d28bcb2 963
reedas 4:7ebc3d28bcb2 964 value_end = previous_token + sizeof( "false" ) - 2;
reedas 4:7ebc3d28bcb2 965 value_start = previous_token;
reedas 4:7ebc3d28bcb2 966 }
reedas 4:7ebc3d28bcb2 967 else if ( *previous_token == NULL_TOKEN )
reedas 4:7ebc3d28bcb2 968 {
reedas 4:7ebc3d28bcb2 969 type = JSON_NULL_TYPE;
reedas 4:7ebc3d28bcb2 970 value_end = previous_token + sizeof( "null" ) - 2;
reedas 4:7ebc3d28bcb2 971 value_start = previous_token;
reedas 4:7ebc3d28bcb2 972 }
reedas 4:7ebc3d28bcb2 973 else
reedas 4:7ebc3d28bcb2 974 {
reedas 4:7ebc3d28bcb2 975 type = JSON_NUMBER_TYPE;
reedas 4:7ebc3d28bcb2 976
reedas 4:7ebc3d28bcb2 977 /* Keep moving the value end token back till you encounter a digit */
reedas 4:7ebc3d28bcb2 978 while ( ( ( *value_end < '0' ) || ( *value_end > '9' ) ) )
reedas 4:7ebc3d28bcb2 979 {
reedas 4:7ebc3d28bcb2 980 value_end--;
reedas 4:7ebc3d28bcb2 981 }
reedas 4:7ebc3d28bcb2 982
reedas 4:7ebc3d28bcb2 983 value_start = value_end;
reedas 4:7ebc3d28bcb2 984
reedas 4:7ebc3d28bcb2 985 while ( ( ( *value_start >= '0' ) && ( *value_start <= '9' ) ) || ( *value_start == '.' ) || ( *value_start == '-' ) )
reedas 4:7ebc3d28bcb2 986 {
reedas 4:7ebc3d28bcb2 987 value_start--;
reedas 4:7ebc3d28bcb2 988 }
reedas 4:7ebc3d28bcb2 989
reedas 4:7ebc3d28bcb2 990 value_start++;
reedas 4:7ebc3d28bcb2 991 }
reedas 4:7ebc3d28bcb2 992
reedas 4:7ebc3d28bcb2 993 json_object.value_type = type;
reedas 4:7ebc3d28bcb2 994 json_object.value = value_start;
reedas 4:7ebc3d28bcb2 995 json_object.value_length = value_end - value_start + 1;
reedas 4:7ebc3d28bcb2 996
reedas 4:7ebc3d28bcb2 997 if ( internal_json_callback != NULL )
reedas 4:7ebc3d28bcb2 998 {
reedas 4:7ebc3d28bcb2 999 str_convertor( &json_object );
reedas 4:7ebc3d28bcb2 1000 internal_json_callback( &json_object, internal_json_argument );
reedas 4:7ebc3d28bcb2 1001 }
reedas 4:7ebc3d28bcb2 1002
reedas 4:7ebc3d28bcb2 1003 string_start = NULL;
reedas 4:7ebc3d28bcb2 1004 string_end = NULL;
reedas 4:7ebc3d28bcb2 1005 value_start = NULL;
reedas 4:7ebc3d28bcb2 1006 value_end = NULL;
reedas 4:7ebc3d28bcb2 1007 type = UNKNOWN_JSON_TYPE;
reedas 4:7ebc3d28bcb2 1008 }
reedas 4:7ebc3d28bcb2 1009
reedas 4:7ebc3d28bcb2 1010 previous_token = current_input_token;
reedas 4:7ebc3d28bcb2 1011
reedas 4:7ebc3d28bcb2 1012 break;
reedas 4:7ebc3d28bcb2 1013
reedas 4:7ebc3d28bcb2 1014 case ESCAPE_TOKEN:
reedas 4:7ebc3d28bcb2 1015 /* Clear escape token flag, if the previous token is an escape token. Else set it */
reedas 4:7ebc3d28bcb2 1016 escape_token = ( escape_token == true ) ? false : true;
reedas 4:7ebc3d28bcb2 1017
reedas 4:7ebc3d28bcb2 1018 break;
reedas 4:7ebc3d28bcb2 1019
reedas 4:7ebc3d28bcb2 1020 default:
reedas 4:7ebc3d28bcb2 1021 /* Reset escape token flag */
reedas 4:7ebc3d28bcb2 1022 escape_token = false;
reedas 4:7ebc3d28bcb2 1023 if ( ( object_counter == 0 ) && ( array_counter == 0 ) && ( *current_input_token != ' ' ) &&
reedas 4:7ebc3d28bcb2 1024 ( JSON_IS_NOT_ESC_CHAR ( *current_input_token ) ) )
reedas 4:7ebc3d28bcb2 1025 {
reedas 4:7ebc3d28bcb2 1026 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 1027 object_counter = 0;
reedas 4:7ebc3d28bcb2 1028 array_counter = 0;
reedas 4:7ebc3d28bcb2 1029 return valid_json_string;
reedas 4:7ebc3d28bcb2 1030 }
reedas 4:7ebc3d28bcb2 1031 break;
reedas 4:7ebc3d28bcb2 1032 } // switch
reedas 4:7ebc3d28bcb2 1033
reedas 4:7ebc3d28bcb2 1034 /* Counting spaces*/
reedas 4:7ebc3d28bcb2 1035 if ( *( current_input_token ) == ' ' )
reedas 4:7ebc3d28bcb2 1036 {
reedas 4:7ebc3d28bcb2 1037 space++;
reedas 4:7ebc3d28bcb2 1038 }
reedas 4:7ebc3d28bcb2 1039 else
reedas 4:7ebc3d28bcb2 1040 {
reedas 4:7ebc3d28bcb2 1041 space = 0;
reedas 4:7ebc3d28bcb2 1042 }
reedas 4:7ebc3d28bcb2 1043 current_input_token++;
reedas 4:7ebc3d28bcb2 1044 if ( ( *( current_input_token ) == '\0' ) && ( ( ( *( previous_token ) == COMMA_SEPARATOR ) || ( *( previous_token ) == STRING_TOKEN ) || ( *( previous_token ) == START_OF_VALUE ) || ( *( previous_token ) == ARRAY_START_TOKEN ) ) ) )
reedas 4:7ebc3d28bcb2 1045 {
reedas 4:7ebc3d28bcb2 1046 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 1047 object_counter = 0;
reedas 4:7ebc3d28bcb2 1048 array_counter = 0;
reedas 4:7ebc3d28bcb2 1049 return valid_json_string;
reedas 4:7ebc3d28bcb2 1050 }
reedas 4:7ebc3d28bcb2 1051 } // while
reedas 4:7ebc3d28bcb2 1052 } // if
reedas 4:7ebc3d28bcb2 1053 else
reedas 4:7ebc3d28bcb2 1054 {
reedas 4:7ebc3d28bcb2 1055 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 1056 return valid_json_string;
reedas 4:7ebc3d28bcb2 1057 }
reedas 4:7ebc3d28bcb2 1058
reedas 4:7ebc3d28bcb2 1059 /* This means that a closing brace has not been found for an object. This data is split across packets */
reedas 4:7ebc3d28bcb2 1060 if ( object_counter || array_counter )
reedas 4:7ebc3d28bcb2 1061 {
reedas 4:7ebc3d28bcb2 1062 memset( packet_backup, 0x0, sizeof( packet_backup ) );
reedas 4:7ebc3d28bcb2 1063
reedas 4:7ebc3d28bcb2 1064 // Copy everything from the most recent unfinished object onwards
reedas 4:7ebc3d28bcb2 1065
reedas 4:7ebc3d28bcb2 1066 number_of_bytes_backed_up = end_of_input - most_recent_object_marker;
reedas 4:7ebc3d28bcb2 1067
reedas 4:7ebc3d28bcb2 1068 memcpy( packet_backup, most_recent_object_marker, number_of_bytes_backed_up );
reedas 4:7ebc3d28bcb2 1069
reedas 4:7ebc3d28bcb2 1070
reedas 4:7ebc3d28bcb2 1071 incomplete_response = true;
reedas 4:7ebc3d28bcb2 1072 valid_json_string = CY_RSLT_JSON_GENERIC_ERROR;
reedas 4:7ebc3d28bcb2 1073 object_counter = 0;
reedas 4:7ebc3d28bcb2 1074
reedas 4:7ebc3d28bcb2 1075 return valid_json_string;
reedas 4:7ebc3d28bcb2 1076 }
reedas 4:7ebc3d28bcb2 1077
reedas 4:7ebc3d28bcb2 1078
reedas 4:7ebc3d28bcb2 1079 memset( &parent_json_object, 0x0, sizeof( parent_json_object ) );
reedas 4:7ebc3d28bcb2 1080
reedas 4:7ebc3d28bcb2 1081 incomplete_response = false;
reedas 4:7ebc3d28bcb2 1082
reedas 4:7ebc3d28bcb2 1083 object_counter = 0;
reedas 4:7ebc3d28bcb2 1084
reedas 4:7ebc3d28bcb2 1085 string_start = NULL;
reedas 4:7ebc3d28bcb2 1086 string_end = NULL;
reedas 4:7ebc3d28bcb2 1087
reedas 4:7ebc3d28bcb2 1088 value_start = NULL;
reedas 4:7ebc3d28bcb2 1089 value_end = NULL;
reedas 4:7ebc3d28bcb2 1090
reedas 4:7ebc3d28bcb2 1091 type = UNKNOWN_JSON_TYPE;
reedas 4:7ebc3d28bcb2 1092
reedas 4:7ebc3d28bcb2 1093 escape_token = false;
reedas 4:7ebc3d28bcb2 1094
reedas 4:7ebc3d28bcb2 1095 previous_token = NULL;
reedas 4:7ebc3d28bcb2 1096
reedas 4:7ebc3d28bcb2 1097 return valid_json_string;
reedas 4:7ebc3d28bcb2 1098 }