Simple sample that demonstrates reading the FXOS8700CQ accelerometer, convert the data to JSON and send to an Azure IoT Hub.

Dependencies:   azure_umqtt_c iothub_mqtt_transport mbed-rtos mbed wolfSSL Socket lwip-eth lwip-sys lwip

Committer:
markrad
Date:
Tue Apr 25 01:33:13 2017 +0000
Revision:
7:2564d95cbf81
Parent:
3:c0556ff7b8e3
Fix bug in NTP library. Clean up code some.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
markrad 3:c0556ff7b8e3 1 /*
markrad 3:c0556ff7b8e3 2 Parson ( http://kgabis.github.com/parson/ )
markrad 3:c0556ff7b8e3 3 Copyright (c) 2012 - 2016 Krzysztof Gabis
markrad 3:c0556ff7b8e3 4
markrad 3:c0556ff7b8e3 5 Permission is hereby granted, free of charge, to any person obtaining a copy
markrad 3:c0556ff7b8e3 6 of this software and associated documentation files (the "Software"), to deal
markrad 3:c0556ff7b8e3 7 in the Software without restriction, including without limitation the rights
markrad 3:c0556ff7b8e3 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
markrad 3:c0556ff7b8e3 9 copies of the Software, and to permit persons to whom the Software is
markrad 3:c0556ff7b8e3 10 furnished to do so, subject to the following conditions:
markrad 3:c0556ff7b8e3 11
markrad 3:c0556ff7b8e3 12 The above copyright notice and this permission notice shall be included in
markrad 3:c0556ff7b8e3 13 all copies or substantial portions of the Software.
markrad 3:c0556ff7b8e3 14
markrad 3:c0556ff7b8e3 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
markrad 3:c0556ff7b8e3 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
markrad 3:c0556ff7b8e3 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
markrad 3:c0556ff7b8e3 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
markrad 3:c0556ff7b8e3 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
markrad 3:c0556ff7b8e3 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
markrad 3:c0556ff7b8e3 21 THE SOFTWARE.
markrad 3:c0556ff7b8e3 22 */
markrad 3:c0556ff7b8e3 23 #ifdef _MSC_VER
markrad 3:c0556ff7b8e3 24 #ifndef _CRT_SECURE_NO_WARNINGS
markrad 3:c0556ff7b8e3 25 #define _CRT_SECURE_NO_WARNINGS
markrad 3:c0556ff7b8e3 26 #endif /* _CRT_SECURE_NO_WARNINGS */
markrad 3:c0556ff7b8e3 27 #endif /* _MSC_VER */
markrad 3:c0556ff7b8e3 28
markrad 3:c0556ff7b8e3 29 #include "parson.h"
markrad 3:c0556ff7b8e3 30
markrad 3:c0556ff7b8e3 31 #include <stdio.h>
markrad 3:c0556ff7b8e3 32 #include <stdlib.h>
markrad 3:c0556ff7b8e3 33 #include <string.h>
markrad 3:c0556ff7b8e3 34 #include <ctype.h>
markrad 3:c0556ff7b8e3 35 #include <math.h>
markrad 3:c0556ff7b8e3 36
markrad 3:c0556ff7b8e3 37 #define STARTING_CAPACITY 15
markrad 3:c0556ff7b8e3 38 #define ARRAY_MAX_CAPACITY 122880 /* 15*(2^13) */
markrad 3:c0556ff7b8e3 39 #define OBJECT_MAX_CAPACITY 960 /* 15*(2^6) */
markrad 3:c0556ff7b8e3 40 #define MAX_NESTING 19
markrad 3:c0556ff7b8e3 41 #define DOUBLE_SERIALIZATION_FORMAT "%f"
markrad 3:c0556ff7b8e3 42
markrad 3:c0556ff7b8e3 43 #define SIZEOF_TOKEN(a) (sizeof(a) - 1)
markrad 3:c0556ff7b8e3 44 #define SKIP_CHAR(str) ((*str)++)
markrad 3:c0556ff7b8e3 45 #define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
markrad 3:c0556ff7b8e3 46 #define MAX(a, b) ((a) > (b) ? (a) : (b))
markrad 3:c0556ff7b8e3 47
markrad 3:c0556ff7b8e3 48 #undef malloc
markrad 3:c0556ff7b8e3 49 #undef free
markrad 3:c0556ff7b8e3 50
markrad 3:c0556ff7b8e3 51 static JSON_Malloc_Function parson_malloc = malloc;
markrad 3:c0556ff7b8e3 52 static JSON_Free_Function parson_free = free;
markrad 3:c0556ff7b8e3 53
markrad 3:c0556ff7b8e3 54 #define IS_CONT(b) (((unsigned char)(b) & 0xC0) == 0x80) /* is utf-8 continuation byte */
markrad 3:c0556ff7b8e3 55
markrad 3:c0556ff7b8e3 56 /* Type definitions */
markrad 3:c0556ff7b8e3 57 typedef union json_value_value {
markrad 3:c0556ff7b8e3 58 char *string;
markrad 3:c0556ff7b8e3 59 double number;
markrad 3:c0556ff7b8e3 60 JSON_Object *object;
markrad 3:c0556ff7b8e3 61 JSON_Array *array;
markrad 3:c0556ff7b8e3 62 int boolean;
markrad 3:c0556ff7b8e3 63 int null;
markrad 3:c0556ff7b8e3 64 } JSON_Value_Value;
markrad 3:c0556ff7b8e3 65
markrad 3:c0556ff7b8e3 66 struct json_value_t {
markrad 3:c0556ff7b8e3 67 JSON_Value_Type type;
markrad 3:c0556ff7b8e3 68 JSON_Value_Value value;
markrad 3:c0556ff7b8e3 69 };
markrad 3:c0556ff7b8e3 70
markrad 3:c0556ff7b8e3 71 struct json_object_t {
markrad 3:c0556ff7b8e3 72 char **names;
markrad 3:c0556ff7b8e3 73 JSON_Value **values;
markrad 3:c0556ff7b8e3 74 size_t count;
markrad 3:c0556ff7b8e3 75 size_t capacity;
markrad 3:c0556ff7b8e3 76 };
markrad 3:c0556ff7b8e3 77
markrad 3:c0556ff7b8e3 78 struct json_array_t {
markrad 3:c0556ff7b8e3 79 JSON_Value **items;
markrad 3:c0556ff7b8e3 80 size_t count;
markrad 3:c0556ff7b8e3 81 size_t capacity;
markrad 3:c0556ff7b8e3 82 };
markrad 3:c0556ff7b8e3 83
markrad 3:c0556ff7b8e3 84 /* Various */
markrad 3:c0556ff7b8e3 85 static char * read_file(const char *filename);
markrad 3:c0556ff7b8e3 86 static void remove_comments(char *string, const char *start_token, const char *end_token);
markrad 3:c0556ff7b8e3 87 static char * parson_strndup(const char *string, size_t n);
markrad 3:c0556ff7b8e3 88 static char * parson_strdup(const char *string);
markrad 3:c0556ff7b8e3 89 static int is_utf16_hex(const unsigned char *string);
markrad 3:c0556ff7b8e3 90 static int num_bytes_in_utf8_sequence(unsigned char c);
markrad 3:c0556ff7b8e3 91 static int verify_utf8_sequence(const unsigned char *string, int *len);
markrad 3:c0556ff7b8e3 92 static int is_valid_utf8(const char *string, size_t string_len);
markrad 3:c0556ff7b8e3 93 static int is_decimal(const char *string, size_t length);
markrad 3:c0556ff7b8e3 94
markrad 3:c0556ff7b8e3 95 /* JSON Object */
markrad 3:c0556ff7b8e3 96 static JSON_Object * json_object_init(void);
markrad 3:c0556ff7b8e3 97 static JSON_Status json_object_add(JSON_Object *object, const char *name, JSON_Value *value);
markrad 3:c0556ff7b8e3 98 static JSON_Status json_object_resize(JSON_Object *object, size_t new_capacity);
markrad 3:c0556ff7b8e3 99 static JSON_Value * json_object_nget_value(const JSON_Object *object, const char *name, size_t n);
markrad 3:c0556ff7b8e3 100 static void json_object_free(JSON_Object *object);
markrad 3:c0556ff7b8e3 101
markrad 3:c0556ff7b8e3 102 /* JSON Array */
markrad 3:c0556ff7b8e3 103 static JSON_Array * json_array_init(void);
markrad 3:c0556ff7b8e3 104 static JSON_Status json_array_add(JSON_Array *array, JSON_Value *value);
markrad 3:c0556ff7b8e3 105 static JSON_Status json_array_resize(JSON_Array *array, size_t new_capacity);
markrad 3:c0556ff7b8e3 106 static void json_array_free(JSON_Array *array);
markrad 3:c0556ff7b8e3 107
markrad 3:c0556ff7b8e3 108 /* JSON Value */
markrad 3:c0556ff7b8e3 109 static JSON_Value * json_value_init_string_no_copy(char *string);
markrad 3:c0556ff7b8e3 110
markrad 3:c0556ff7b8e3 111 /* Parser */
markrad 3:c0556ff7b8e3 112 static JSON_Status skip_quotes(const char **string);
markrad 3:c0556ff7b8e3 113 static int parse_utf_16(const char **unprocessed, char **processed);
markrad 3:c0556ff7b8e3 114 static char * process_string(const char *input, size_t len);
markrad 3:c0556ff7b8e3 115 static char * get_quoted_string(const char **string);
markrad 3:c0556ff7b8e3 116 static JSON_Value * parse_object_value(const char **string, size_t nesting);
markrad 3:c0556ff7b8e3 117 static JSON_Value * parse_array_value(const char **string, size_t nesting);
markrad 3:c0556ff7b8e3 118 static JSON_Value * parse_string_value(const char **string);
markrad 3:c0556ff7b8e3 119 static JSON_Value * parse_boolean_value(const char **string);
markrad 3:c0556ff7b8e3 120 static JSON_Value * parse_number_value(const char **string);
markrad 3:c0556ff7b8e3 121 static JSON_Value * parse_null_value(const char **string);
markrad 3:c0556ff7b8e3 122 static JSON_Value * parse_value(const char **string, size_t nesting);
markrad 3:c0556ff7b8e3 123
markrad 3:c0556ff7b8e3 124 /* Serialization */
markrad 3:c0556ff7b8e3 125 static int json_serialize_to_buffer_r(const JSON_Value *value, char *buf, int level, int is_pretty, char *num_buf);
markrad 3:c0556ff7b8e3 126 static int json_serialize_string(const char *string, char *buf);
markrad 3:c0556ff7b8e3 127 static int append_indent(char *buf, int level);
markrad 3:c0556ff7b8e3 128 static int append_string(char *buf, const char *string);
markrad 3:c0556ff7b8e3 129
markrad 3:c0556ff7b8e3 130 /* Various */
markrad 3:c0556ff7b8e3 131 static char * parson_strndup(const char *string, size_t n) {
markrad 3:c0556ff7b8e3 132 char *output_string = (char*)parson_malloc(n + 1);
markrad 3:c0556ff7b8e3 133 if (!output_string) {
markrad 3:c0556ff7b8e3 134 return NULL;
markrad 3:c0556ff7b8e3 135 }
markrad 3:c0556ff7b8e3 136 output_string[n] = '\0';
markrad 3:c0556ff7b8e3 137 strncpy(output_string, string, n);
markrad 3:c0556ff7b8e3 138 return output_string;
markrad 3:c0556ff7b8e3 139 }
markrad 3:c0556ff7b8e3 140
markrad 3:c0556ff7b8e3 141 static char * parson_strdup(const char *string) {
markrad 3:c0556ff7b8e3 142 return parson_strndup(string, strlen(string));
markrad 3:c0556ff7b8e3 143 }
markrad 3:c0556ff7b8e3 144
markrad 3:c0556ff7b8e3 145 static int is_utf16_hex(const unsigned char *s) {
markrad 3:c0556ff7b8e3 146 return isxdigit(s[0]) && isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]);
markrad 3:c0556ff7b8e3 147 }
markrad 3:c0556ff7b8e3 148
markrad 3:c0556ff7b8e3 149 static int num_bytes_in_utf8_sequence(unsigned char c) {
markrad 3:c0556ff7b8e3 150 if (c == 0xC0 || c == 0xC1 || c > 0xF4 || IS_CONT(c)) {
markrad 3:c0556ff7b8e3 151 return 0;
markrad 3:c0556ff7b8e3 152 } else if ((c & 0x80) == 0) { /* 0xxxxxxx */
markrad 3:c0556ff7b8e3 153 return 1;
markrad 3:c0556ff7b8e3 154 } else if ((c & 0xE0) == 0xC0) { /* 110xxxxx */
markrad 3:c0556ff7b8e3 155 return 2;
markrad 3:c0556ff7b8e3 156 } else if ((c & 0xF0) == 0xE0) { /* 1110xxxx */
markrad 3:c0556ff7b8e3 157 return 3;
markrad 3:c0556ff7b8e3 158 } else if ((c & 0xF8) == 0xF0) { /* 11110xxx */
markrad 3:c0556ff7b8e3 159 return 4;
markrad 3:c0556ff7b8e3 160 }
markrad 3:c0556ff7b8e3 161 return 0; /* won't happen */
markrad 3:c0556ff7b8e3 162 }
markrad 3:c0556ff7b8e3 163
markrad 3:c0556ff7b8e3 164 static int verify_utf8_sequence(const unsigned char *string, int *len) {
markrad 3:c0556ff7b8e3 165 unsigned int cp = 0;
markrad 3:c0556ff7b8e3 166 *len = num_bytes_in_utf8_sequence(string[0]);
markrad 3:c0556ff7b8e3 167
markrad 3:c0556ff7b8e3 168 if (*len == 1) {
markrad 3:c0556ff7b8e3 169 cp = string[0];
markrad 3:c0556ff7b8e3 170 } else if (*len == 2 && IS_CONT(string[1])) {
markrad 3:c0556ff7b8e3 171 cp = string[0] & 0x1F;
markrad 3:c0556ff7b8e3 172 cp = (cp << 6) | (string[1] & 0x3F);
markrad 3:c0556ff7b8e3 173 } else if (*len == 3 && IS_CONT(string[1]) && IS_CONT(string[2])) {
markrad 3:c0556ff7b8e3 174 cp = ((unsigned char)string[0]) & 0xF;
markrad 3:c0556ff7b8e3 175 cp = (cp << 6) | (string[1] & 0x3F);
markrad 3:c0556ff7b8e3 176 cp = (cp << 6) | (string[2] & 0x3F);
markrad 3:c0556ff7b8e3 177 } else if (*len == 4 && IS_CONT(string[1]) && IS_CONT(string[2]) && IS_CONT(string[3])) {
markrad 3:c0556ff7b8e3 178 cp = string[0] & 0x7;
markrad 3:c0556ff7b8e3 179 cp = (cp << 6) | (string[1] & 0x3F);
markrad 3:c0556ff7b8e3 180 cp = (cp << 6) | (string[2] & 0x3F);
markrad 3:c0556ff7b8e3 181 cp = (cp << 6) | (string[3] & 0x3F);
markrad 3:c0556ff7b8e3 182 } else {
markrad 3:c0556ff7b8e3 183 return 0;
markrad 3:c0556ff7b8e3 184 }
markrad 3:c0556ff7b8e3 185
markrad 3:c0556ff7b8e3 186 /* overlong encodings */
markrad 3:c0556ff7b8e3 187 if ((cp < 0x80 && *len > 1) ||
markrad 3:c0556ff7b8e3 188 (cp < 0x800 && *len > 2) ||
markrad 3:c0556ff7b8e3 189 (cp < 0x10000 && *len > 3)) {
markrad 3:c0556ff7b8e3 190 return 0;
markrad 3:c0556ff7b8e3 191 }
markrad 3:c0556ff7b8e3 192
markrad 3:c0556ff7b8e3 193 /* invalid unicode */
markrad 3:c0556ff7b8e3 194 if (cp > 0x10FFFF) {
markrad 3:c0556ff7b8e3 195 return 0;
markrad 3:c0556ff7b8e3 196 }
markrad 3:c0556ff7b8e3 197
markrad 3:c0556ff7b8e3 198 /* surrogate halves */
markrad 3:c0556ff7b8e3 199 if (cp >= 0xD800 && cp <= 0xDFFF) {
markrad 3:c0556ff7b8e3 200 return 0;
markrad 3:c0556ff7b8e3 201 }
markrad 3:c0556ff7b8e3 202
markrad 3:c0556ff7b8e3 203 return 1;
markrad 3:c0556ff7b8e3 204 }
markrad 3:c0556ff7b8e3 205
markrad 3:c0556ff7b8e3 206 static int is_valid_utf8(const char *string, size_t string_len) {
markrad 3:c0556ff7b8e3 207 int len = 0;
markrad 3:c0556ff7b8e3 208 const char *string_end = string + string_len;
markrad 3:c0556ff7b8e3 209 while (string < string_end) {
markrad 3:c0556ff7b8e3 210 if (!verify_utf8_sequence((const unsigned char*)string, &len)) {
markrad 3:c0556ff7b8e3 211 return 0;
markrad 3:c0556ff7b8e3 212 }
markrad 3:c0556ff7b8e3 213 string += len;
markrad 3:c0556ff7b8e3 214 }
markrad 3:c0556ff7b8e3 215 return 1;
markrad 3:c0556ff7b8e3 216 }
markrad 3:c0556ff7b8e3 217
markrad 3:c0556ff7b8e3 218 static int is_decimal(const char *string, size_t length) {
markrad 3:c0556ff7b8e3 219 if (length > 1 && string[0] == '0' && string[1] != '.') {
markrad 3:c0556ff7b8e3 220 return 0;
markrad 3:c0556ff7b8e3 221 }
markrad 3:c0556ff7b8e3 222 if (length > 2 && !strncmp(string, "-0", 2) && string[2] != '.') {
markrad 3:c0556ff7b8e3 223 return 0;
markrad 3:c0556ff7b8e3 224 }
markrad 3:c0556ff7b8e3 225 while (length--)
markrad 3:c0556ff7b8e3 226 if (strchr("xX", string[length])) {
markrad 3:c0556ff7b8e3 227 return 0;
markrad 3:c0556ff7b8e3 228 }
markrad 3:c0556ff7b8e3 229 return 1;
markrad 3:c0556ff7b8e3 230 }
markrad 3:c0556ff7b8e3 231
markrad 3:c0556ff7b8e3 232 static char * read_file(const char * filename) {
markrad 3:c0556ff7b8e3 233 FILE *fp = fopen(filename, "r");
markrad 3:c0556ff7b8e3 234 size_t file_size;
markrad 3:c0556ff7b8e3 235 long pos;
markrad 3:c0556ff7b8e3 236 char *file_contents;
markrad 3:c0556ff7b8e3 237 if (!fp) {
markrad 3:c0556ff7b8e3 238 return NULL;
markrad 3:c0556ff7b8e3 239 }
markrad 3:c0556ff7b8e3 240 fseek(fp, 0L, SEEK_END);
markrad 3:c0556ff7b8e3 241 pos = ftell(fp);
markrad 3:c0556ff7b8e3 242 if (pos < 0) {
markrad 3:c0556ff7b8e3 243 fclose(fp);
markrad 3:c0556ff7b8e3 244 return NULL;
markrad 3:c0556ff7b8e3 245 }
markrad 3:c0556ff7b8e3 246 file_size = pos;
markrad 3:c0556ff7b8e3 247 rewind(fp);
markrad 3:c0556ff7b8e3 248 file_contents = (char*)parson_malloc(sizeof(char) * (file_size + 1));
markrad 3:c0556ff7b8e3 249 if (!file_contents) {
markrad 3:c0556ff7b8e3 250 fclose(fp);
markrad 3:c0556ff7b8e3 251 return NULL;
markrad 3:c0556ff7b8e3 252 }
markrad 3:c0556ff7b8e3 253 if (fread(file_contents, file_size, 1, fp) < 1) {
markrad 3:c0556ff7b8e3 254 if (ferror(fp)) {
markrad 3:c0556ff7b8e3 255 fclose(fp);
markrad 3:c0556ff7b8e3 256 parson_free(file_contents);
markrad 3:c0556ff7b8e3 257 return NULL;
markrad 3:c0556ff7b8e3 258 }
markrad 3:c0556ff7b8e3 259 }
markrad 3:c0556ff7b8e3 260 fclose(fp);
markrad 3:c0556ff7b8e3 261 file_contents[file_size] = '\0';
markrad 3:c0556ff7b8e3 262 return file_contents;
markrad 3:c0556ff7b8e3 263 }
markrad 3:c0556ff7b8e3 264
markrad 3:c0556ff7b8e3 265 static void remove_comments(char *string, const char *start_token, const char *end_token) {
markrad 3:c0556ff7b8e3 266 int in_string = 0, escaped = 0;
markrad 3:c0556ff7b8e3 267 size_t i;
markrad 3:c0556ff7b8e3 268 char *ptr = NULL, current_char;
markrad 3:c0556ff7b8e3 269 size_t start_token_len = strlen(start_token);
markrad 3:c0556ff7b8e3 270 size_t end_token_len = strlen(end_token);
markrad 3:c0556ff7b8e3 271 if (start_token_len == 0 || end_token_len == 0) {
markrad 3:c0556ff7b8e3 272 return;
markrad 3:c0556ff7b8e3 273 }
markrad 3:c0556ff7b8e3 274 while ((current_char = *string) != '\0') {
markrad 3:c0556ff7b8e3 275 if (current_char == '\\' && !escaped) {
markrad 3:c0556ff7b8e3 276 escaped = 1;
markrad 3:c0556ff7b8e3 277 string++;
markrad 3:c0556ff7b8e3 278 continue;
markrad 3:c0556ff7b8e3 279 } else if (current_char == '\"' && !escaped) {
markrad 3:c0556ff7b8e3 280 in_string = !in_string;
markrad 3:c0556ff7b8e3 281 } else if (!in_string && strncmp(string, start_token, start_token_len) == 0) {
markrad 3:c0556ff7b8e3 282 for(i = 0; i < start_token_len; i++) {
markrad 3:c0556ff7b8e3 283 string[i] = ' ';
markrad 3:c0556ff7b8e3 284 }
markrad 3:c0556ff7b8e3 285 string = string + start_token_len;
markrad 3:c0556ff7b8e3 286 ptr = strstr(string, end_token);
markrad 3:c0556ff7b8e3 287 if (!ptr) {
markrad 3:c0556ff7b8e3 288 return;
markrad 3:c0556ff7b8e3 289 }
markrad 3:c0556ff7b8e3 290 for (i = 0; i < (ptr - string) + end_token_len; i++) {
markrad 3:c0556ff7b8e3 291 string[i] = ' ';
markrad 3:c0556ff7b8e3 292 }
markrad 3:c0556ff7b8e3 293 string = ptr + end_token_len - 1;
markrad 3:c0556ff7b8e3 294 }
markrad 3:c0556ff7b8e3 295 escaped = 0;
markrad 3:c0556ff7b8e3 296 string++;
markrad 3:c0556ff7b8e3 297 }
markrad 3:c0556ff7b8e3 298 }
markrad 3:c0556ff7b8e3 299
markrad 3:c0556ff7b8e3 300 /* JSON Object */
markrad 3:c0556ff7b8e3 301 static JSON_Object * json_object_init(void) {
markrad 3:c0556ff7b8e3 302 JSON_Object *new_obj = (JSON_Object*)parson_malloc(sizeof(JSON_Object));
markrad 3:c0556ff7b8e3 303 if (!new_obj) {
markrad 3:c0556ff7b8e3 304 return NULL;
markrad 3:c0556ff7b8e3 305 }
markrad 3:c0556ff7b8e3 306 new_obj->names = (char**)NULL;
markrad 3:c0556ff7b8e3 307 new_obj->values = (JSON_Value**)NULL;
markrad 3:c0556ff7b8e3 308 new_obj->capacity = 0;
markrad 3:c0556ff7b8e3 309 new_obj->count = 0;
markrad 3:c0556ff7b8e3 310 return new_obj;
markrad 3:c0556ff7b8e3 311 }
markrad 3:c0556ff7b8e3 312
markrad 3:c0556ff7b8e3 313 static JSON_Status json_object_add(JSON_Object *object, const char *name, JSON_Value *value) {
markrad 3:c0556ff7b8e3 314 size_t index = 0;
markrad 3:c0556ff7b8e3 315 if (object == NULL || name == NULL || value == NULL) {
markrad 3:c0556ff7b8e3 316 return JSONFailure;
markrad 3:c0556ff7b8e3 317 }
markrad 3:c0556ff7b8e3 318 if (json_object_get_value(object, name) != NULL) {
markrad 3:c0556ff7b8e3 319 return JSONFailure;
markrad 3:c0556ff7b8e3 320 }
markrad 3:c0556ff7b8e3 321 if (object->count >= object->capacity) {
markrad 3:c0556ff7b8e3 322 size_t new_capacity = MAX(object->capacity * 2, STARTING_CAPACITY);
markrad 3:c0556ff7b8e3 323 if (new_capacity > OBJECT_MAX_CAPACITY) {
markrad 3:c0556ff7b8e3 324 return JSONFailure;
markrad 3:c0556ff7b8e3 325 }
markrad 3:c0556ff7b8e3 326 if (json_object_resize(object, new_capacity) == JSONFailure) {
markrad 3:c0556ff7b8e3 327 return JSONFailure;
markrad 3:c0556ff7b8e3 328 }
markrad 3:c0556ff7b8e3 329 }
markrad 3:c0556ff7b8e3 330 index = object->count;
markrad 3:c0556ff7b8e3 331 object->names[index] = parson_strdup(name);
markrad 3:c0556ff7b8e3 332 if (object->names[index] == NULL) {
markrad 3:c0556ff7b8e3 333 return JSONFailure;
markrad 3:c0556ff7b8e3 334 }
markrad 3:c0556ff7b8e3 335 object->values[index] = value;
markrad 3:c0556ff7b8e3 336 object->count++;
markrad 3:c0556ff7b8e3 337 return JSONSuccess;
markrad 3:c0556ff7b8e3 338 }
markrad 3:c0556ff7b8e3 339
markrad 3:c0556ff7b8e3 340 static JSON_Status json_object_resize(JSON_Object *object, size_t new_capacity) {
markrad 3:c0556ff7b8e3 341 char **temp_names = NULL;
markrad 3:c0556ff7b8e3 342 JSON_Value **temp_values = NULL;
markrad 3:c0556ff7b8e3 343
markrad 3:c0556ff7b8e3 344 if ((object->names == NULL && object->values != NULL) ||
markrad 3:c0556ff7b8e3 345 (object->names != NULL && object->values == NULL) ||
markrad 3:c0556ff7b8e3 346 new_capacity == 0) {
markrad 3:c0556ff7b8e3 347 return JSONFailure; /* Shouldn't happen */
markrad 3:c0556ff7b8e3 348 }
markrad 3:c0556ff7b8e3 349
markrad 3:c0556ff7b8e3 350 temp_names = (char**)parson_malloc(new_capacity * sizeof(char*));
markrad 3:c0556ff7b8e3 351 if (temp_names == NULL) {
markrad 3:c0556ff7b8e3 352 return JSONFailure;
markrad 3:c0556ff7b8e3 353 }
markrad 3:c0556ff7b8e3 354
markrad 3:c0556ff7b8e3 355 temp_values = (JSON_Value**)parson_malloc(new_capacity * sizeof(JSON_Value*));
markrad 3:c0556ff7b8e3 356 if (temp_values == NULL) {
markrad 3:c0556ff7b8e3 357 parson_free(temp_names);
markrad 3:c0556ff7b8e3 358 return JSONFailure;
markrad 3:c0556ff7b8e3 359 }
markrad 3:c0556ff7b8e3 360
markrad 3:c0556ff7b8e3 361 if (object->names != NULL && object->values != NULL && object->count > 0) {
markrad 3:c0556ff7b8e3 362 memcpy(temp_names, object->names, object->count * sizeof(char*));
markrad 3:c0556ff7b8e3 363 memcpy(temp_values, object->values, object->count * sizeof(JSON_Value*));
markrad 3:c0556ff7b8e3 364 }
markrad 3:c0556ff7b8e3 365 parson_free(object->names);
markrad 3:c0556ff7b8e3 366 parson_free(object->values);
markrad 3:c0556ff7b8e3 367 object->names = temp_names;
markrad 3:c0556ff7b8e3 368 object->values = temp_values;
markrad 3:c0556ff7b8e3 369 object->capacity = new_capacity;
markrad 3:c0556ff7b8e3 370 return JSONSuccess;
markrad 3:c0556ff7b8e3 371 }
markrad 3:c0556ff7b8e3 372
markrad 3:c0556ff7b8e3 373 static JSON_Value * json_object_nget_value(const JSON_Object *object, const char *name, size_t n) {
markrad 3:c0556ff7b8e3 374 size_t i, name_length;
markrad 3:c0556ff7b8e3 375 for (i = 0; i < json_object_get_count(object); i++) {
markrad 3:c0556ff7b8e3 376 name_length = strlen(object->names[i]);
markrad 3:c0556ff7b8e3 377 if (name_length != n) {
markrad 3:c0556ff7b8e3 378 continue;
markrad 3:c0556ff7b8e3 379 }
markrad 3:c0556ff7b8e3 380 if (strncmp(object->names[i], name, n) == 0) {
markrad 3:c0556ff7b8e3 381 return object->values[i];
markrad 3:c0556ff7b8e3 382 }
markrad 3:c0556ff7b8e3 383 }
markrad 3:c0556ff7b8e3 384 return NULL;
markrad 3:c0556ff7b8e3 385 }
markrad 3:c0556ff7b8e3 386
markrad 3:c0556ff7b8e3 387 static void json_object_free(JSON_Object *object) {
markrad 3:c0556ff7b8e3 388 while(object->count--) {
markrad 3:c0556ff7b8e3 389 parson_free(object->names[object->count]);
markrad 3:c0556ff7b8e3 390 json_value_free(object->values[object->count]);
markrad 3:c0556ff7b8e3 391 }
markrad 3:c0556ff7b8e3 392 parson_free(object->names);
markrad 3:c0556ff7b8e3 393 parson_free(object->values);
markrad 3:c0556ff7b8e3 394 parson_free(object);
markrad 3:c0556ff7b8e3 395 }
markrad 3:c0556ff7b8e3 396
markrad 3:c0556ff7b8e3 397 /* JSON Array */
markrad 3:c0556ff7b8e3 398 static JSON_Array * json_array_init(void) {
markrad 3:c0556ff7b8e3 399 JSON_Array *new_array = (JSON_Array*)parson_malloc(sizeof(JSON_Array));
markrad 3:c0556ff7b8e3 400 if (!new_array) {
markrad 3:c0556ff7b8e3 401 return NULL;
markrad 3:c0556ff7b8e3 402 }
markrad 3:c0556ff7b8e3 403 new_array->items = (JSON_Value**)NULL;
markrad 3:c0556ff7b8e3 404 new_array->capacity = 0;
markrad 3:c0556ff7b8e3 405 new_array->count = 0;
markrad 3:c0556ff7b8e3 406 return new_array;
markrad 3:c0556ff7b8e3 407 }
markrad 3:c0556ff7b8e3 408
markrad 3:c0556ff7b8e3 409 static JSON_Status json_array_add(JSON_Array *array, JSON_Value *value) {
markrad 3:c0556ff7b8e3 410 if (array->count >= array->capacity) {
markrad 3:c0556ff7b8e3 411 size_t new_capacity = MAX(array->capacity * 2, STARTING_CAPACITY);
markrad 3:c0556ff7b8e3 412 if (new_capacity > ARRAY_MAX_CAPACITY) {
markrad 3:c0556ff7b8e3 413 return JSONFailure;
markrad 3:c0556ff7b8e3 414 }
markrad 3:c0556ff7b8e3 415 if (json_array_resize(array, new_capacity) == JSONFailure) {
markrad 3:c0556ff7b8e3 416 return JSONFailure;
markrad 3:c0556ff7b8e3 417 }
markrad 3:c0556ff7b8e3 418 }
markrad 3:c0556ff7b8e3 419 array->items[array->count] = value;
markrad 3:c0556ff7b8e3 420 array->count++;
markrad 3:c0556ff7b8e3 421 return JSONSuccess;
markrad 3:c0556ff7b8e3 422 }
markrad 3:c0556ff7b8e3 423
markrad 3:c0556ff7b8e3 424 static JSON_Status json_array_resize(JSON_Array *array, size_t new_capacity) {
markrad 3:c0556ff7b8e3 425 JSON_Value **new_items = NULL;
markrad 3:c0556ff7b8e3 426 if (new_capacity == 0) {
markrad 3:c0556ff7b8e3 427 return JSONFailure;
markrad 3:c0556ff7b8e3 428 }
markrad 3:c0556ff7b8e3 429 new_items = (JSON_Value**)parson_malloc(new_capacity * sizeof(JSON_Value*));
markrad 3:c0556ff7b8e3 430 if (new_items == NULL) {
markrad 3:c0556ff7b8e3 431 return JSONFailure;
markrad 3:c0556ff7b8e3 432 }
markrad 3:c0556ff7b8e3 433 if (array->items != NULL && array->count > 0) {
markrad 3:c0556ff7b8e3 434 memcpy(new_items, array->items, array->count * sizeof(JSON_Value*));
markrad 3:c0556ff7b8e3 435 }
markrad 3:c0556ff7b8e3 436 parson_free(array->items);
markrad 3:c0556ff7b8e3 437 array->items = new_items;
markrad 3:c0556ff7b8e3 438 array->capacity = new_capacity;
markrad 3:c0556ff7b8e3 439 return JSONSuccess;
markrad 3:c0556ff7b8e3 440 }
markrad 3:c0556ff7b8e3 441
markrad 3:c0556ff7b8e3 442 static void json_array_free(JSON_Array *array) {
markrad 3:c0556ff7b8e3 443 while (array->count--)
markrad 3:c0556ff7b8e3 444 json_value_free(array->items[array->count]);
markrad 3:c0556ff7b8e3 445 parson_free(array->items);
markrad 3:c0556ff7b8e3 446 parson_free(array);
markrad 3:c0556ff7b8e3 447 }
markrad 3:c0556ff7b8e3 448
markrad 3:c0556ff7b8e3 449 /* JSON Value */
markrad 3:c0556ff7b8e3 450 static JSON_Value * json_value_init_string_no_copy(char *string) {
markrad 3:c0556ff7b8e3 451 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
markrad 3:c0556ff7b8e3 452 if (!new_value) {
markrad 3:c0556ff7b8e3 453 return NULL;
markrad 3:c0556ff7b8e3 454 }
markrad 3:c0556ff7b8e3 455 new_value->type = JSONString;
markrad 3:c0556ff7b8e3 456 new_value->value.string = string;
markrad 3:c0556ff7b8e3 457 return new_value;
markrad 3:c0556ff7b8e3 458 }
markrad 3:c0556ff7b8e3 459
markrad 3:c0556ff7b8e3 460 /* Parser */
markrad 3:c0556ff7b8e3 461 static JSON_Status skip_quotes(const char **string) {
markrad 3:c0556ff7b8e3 462 if (**string != '\"') {
markrad 3:c0556ff7b8e3 463 return JSONFailure;
markrad 3:c0556ff7b8e3 464 }
markrad 3:c0556ff7b8e3 465 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 466 while (**string != '\"') {
markrad 3:c0556ff7b8e3 467 if (**string == '\0') {
markrad 3:c0556ff7b8e3 468 return JSONFailure;
markrad 3:c0556ff7b8e3 469 } else if (**string == '\\') {
markrad 3:c0556ff7b8e3 470 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 471 if (**string == '\0') {
markrad 3:c0556ff7b8e3 472 return JSONFailure;
markrad 3:c0556ff7b8e3 473 }
markrad 3:c0556ff7b8e3 474 }
markrad 3:c0556ff7b8e3 475 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 476 }
markrad 3:c0556ff7b8e3 477 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 478 return JSONSuccess;
markrad 3:c0556ff7b8e3 479 }
markrad 3:c0556ff7b8e3 480
markrad 3:c0556ff7b8e3 481 static int parse_utf_16(const char **unprocessed, char **processed) {
markrad 3:c0556ff7b8e3 482 unsigned int cp, lead, trail;
markrad 3:c0556ff7b8e3 483 char *processed_ptr = *processed;
markrad 3:c0556ff7b8e3 484 const char *unprocessed_ptr = *unprocessed;
markrad 3:c0556ff7b8e3 485 unprocessed_ptr++; /* skips u */
markrad 3:c0556ff7b8e3 486 if (!is_utf16_hex((const unsigned char*)unprocessed_ptr) || sscanf(unprocessed_ptr, "%4x", &cp) == EOF) {
markrad 3:c0556ff7b8e3 487 return JSONFailure;
markrad 3:c0556ff7b8e3 488 }
markrad 3:c0556ff7b8e3 489 if (cp < 0x80) {
markrad 3:c0556ff7b8e3 490 *processed_ptr = cp; /* 0xxxxxxx */
markrad 3:c0556ff7b8e3 491 } else if (cp < 0x800) {
markrad 3:c0556ff7b8e3 492 *processed_ptr++ = ((cp >> 6) & 0x1F) | 0xC0; /* 110xxxxx */
markrad 3:c0556ff7b8e3 493 *processed_ptr = ((cp ) & 0x3F) | 0x80; /* 10xxxxxx */
markrad 3:c0556ff7b8e3 494 } else if (cp < 0xD800 || cp > 0xDFFF) {
markrad 3:c0556ff7b8e3 495 *processed_ptr++ = ((cp >> 12) & 0x0F) | 0xE0; /* 1110xxxx */
markrad 3:c0556ff7b8e3 496 *processed_ptr++ = ((cp >> 6) & 0x3F) | 0x80; /* 10xxxxxx */
markrad 3:c0556ff7b8e3 497 *processed_ptr = ((cp ) & 0x3F) | 0x80; /* 10xxxxxx */
markrad 3:c0556ff7b8e3 498 } else if (cp >= 0xD800 && cp <= 0xDBFF) { /* lead surrogate (0xD800..0xDBFF) */
markrad 3:c0556ff7b8e3 499 lead = cp;
markrad 3:c0556ff7b8e3 500 unprocessed_ptr += 4; /* should always be within the buffer, otherwise previous sscanf would fail */
markrad 3:c0556ff7b8e3 501 if (*unprocessed_ptr++ != '\\' || *unprocessed_ptr++ != 'u' || /* starts with \u? */
markrad 3:c0556ff7b8e3 502 !is_utf16_hex((const unsigned char*)unprocessed_ptr) ||
markrad 3:c0556ff7b8e3 503 sscanf(unprocessed_ptr, "%4x", &trail) == EOF ||
markrad 3:c0556ff7b8e3 504 trail < 0xDC00 || trail > 0xDFFF) { /* valid trail surrogate? (0xDC00..0xDFFF) */
markrad 3:c0556ff7b8e3 505 return JSONFailure;
markrad 3:c0556ff7b8e3 506 }
markrad 3:c0556ff7b8e3 507 cp = ((((lead-0xD800)&0x3FF)<<10)|((trail-0xDC00)&0x3FF))+0x010000;
markrad 3:c0556ff7b8e3 508 *processed_ptr++ = (((cp >> 18) & 0x07) | 0xF0); /* 11110xxx */
markrad 3:c0556ff7b8e3 509 *processed_ptr++ = (((cp >> 12) & 0x3F) | 0x80); /* 10xxxxxx */
markrad 3:c0556ff7b8e3 510 *processed_ptr++ = (((cp >> 6) & 0x3F) | 0x80); /* 10xxxxxx */
markrad 3:c0556ff7b8e3 511 *processed_ptr = (((cp ) & 0x3F) | 0x80); /* 10xxxxxx */
markrad 3:c0556ff7b8e3 512 } else { /* trail surrogate before lead surrogate */
markrad 3:c0556ff7b8e3 513 return JSONFailure;
markrad 3:c0556ff7b8e3 514 }
markrad 3:c0556ff7b8e3 515 unprocessed_ptr += 3;
markrad 3:c0556ff7b8e3 516 *processed = processed_ptr;
markrad 3:c0556ff7b8e3 517 *unprocessed = unprocessed_ptr;
markrad 3:c0556ff7b8e3 518 return JSONSuccess;
markrad 3:c0556ff7b8e3 519 }
markrad 3:c0556ff7b8e3 520
markrad 3:c0556ff7b8e3 521
markrad 3:c0556ff7b8e3 522 /* Copies and processes passed string up to supplied length.
markrad 3:c0556ff7b8e3 523 Example: "\u006Corem ipsum" -> lorem ipsum */
markrad 3:c0556ff7b8e3 524 static char* process_string(const char *input, size_t len) {
markrad 3:c0556ff7b8e3 525 const char *input_ptr = input;
markrad 3:c0556ff7b8e3 526 size_t initial_size = (len + 1) * sizeof(char);
markrad 3:c0556ff7b8e3 527 size_t final_size = 0;
markrad 3:c0556ff7b8e3 528 char *output = (char*)parson_malloc(initial_size);
markrad 3:c0556ff7b8e3 529 char *output_ptr = output;
markrad 3:c0556ff7b8e3 530 char *resized_output = NULL;
markrad 3:c0556ff7b8e3 531 while ((*input_ptr != '\0') && (size_t)(input_ptr - input) < len) {
markrad 3:c0556ff7b8e3 532 if (*input_ptr == '\\') {
markrad 3:c0556ff7b8e3 533 input_ptr++;
markrad 3:c0556ff7b8e3 534 switch (*input_ptr) {
markrad 3:c0556ff7b8e3 535 case '\"': *output_ptr = '\"'; break;
markrad 3:c0556ff7b8e3 536 case '\\': *output_ptr = '\\'; break;
markrad 3:c0556ff7b8e3 537 case '/': *output_ptr = '/'; break;
markrad 3:c0556ff7b8e3 538 case 'b': *output_ptr = '\b'; break;
markrad 3:c0556ff7b8e3 539 case 'f': *output_ptr = '\f'; break;
markrad 3:c0556ff7b8e3 540 case 'n': *output_ptr = '\n'; break;
markrad 3:c0556ff7b8e3 541 case 'r': *output_ptr = '\r'; break;
markrad 3:c0556ff7b8e3 542 case 't': *output_ptr = '\t'; break;
markrad 3:c0556ff7b8e3 543 case 'u':
markrad 3:c0556ff7b8e3 544 if (parse_utf_16(&input_ptr, &output_ptr) == JSONFailure) {
markrad 3:c0556ff7b8e3 545 goto error;
markrad 3:c0556ff7b8e3 546 }
markrad 3:c0556ff7b8e3 547 break;
markrad 3:c0556ff7b8e3 548 default:
markrad 3:c0556ff7b8e3 549 goto error;
markrad 3:c0556ff7b8e3 550 }
markrad 3:c0556ff7b8e3 551 } else if ((unsigned char)*input_ptr < 0x20) {
markrad 3:c0556ff7b8e3 552 goto error; /* 0x00-0x19 are invalid characters for json string (http://www.ietf.org/rfc/rfc4627.txt) */
markrad 3:c0556ff7b8e3 553 } else {
markrad 3:c0556ff7b8e3 554 *output_ptr = *input_ptr;
markrad 3:c0556ff7b8e3 555 }
markrad 3:c0556ff7b8e3 556 output_ptr++;
markrad 3:c0556ff7b8e3 557 input_ptr++;
markrad 3:c0556ff7b8e3 558 }
markrad 3:c0556ff7b8e3 559 *output_ptr = '\0';
markrad 3:c0556ff7b8e3 560 /* resize to new length */
markrad 3:c0556ff7b8e3 561 final_size = (size_t)(output_ptr-output) + 1;
markrad 3:c0556ff7b8e3 562 /* todo: don't resize if final_size == initial_size */
markrad 3:c0556ff7b8e3 563 resized_output = (char*)parson_malloc(final_size);
markrad 3:c0556ff7b8e3 564 if (resized_output == NULL) {
markrad 3:c0556ff7b8e3 565 goto error;
markrad 3:c0556ff7b8e3 566 }
markrad 3:c0556ff7b8e3 567 memcpy(resized_output, output, final_size);
markrad 3:c0556ff7b8e3 568 parson_free(output);
markrad 3:c0556ff7b8e3 569 return resized_output;
markrad 3:c0556ff7b8e3 570 error:
markrad 3:c0556ff7b8e3 571 parson_free(output);
markrad 3:c0556ff7b8e3 572 return NULL;
markrad 3:c0556ff7b8e3 573 }
markrad 3:c0556ff7b8e3 574
markrad 3:c0556ff7b8e3 575 /* Return processed contents of a string between quotes and
markrad 3:c0556ff7b8e3 576 skips passed argument to a matching quote. */
markrad 3:c0556ff7b8e3 577 static char * get_quoted_string(const char **string) {
markrad 3:c0556ff7b8e3 578 const char *string_start = *string;
markrad 3:c0556ff7b8e3 579 size_t string_len = 0;
markrad 3:c0556ff7b8e3 580 JSON_Status status = skip_quotes(string);
markrad 3:c0556ff7b8e3 581 if (status != JSONSuccess) {
markrad 3:c0556ff7b8e3 582 return NULL;
markrad 3:c0556ff7b8e3 583 }
markrad 3:c0556ff7b8e3 584 string_len = *string - string_start - 2; /* length without quotes */
markrad 3:c0556ff7b8e3 585 return process_string(string_start + 1, string_len);
markrad 3:c0556ff7b8e3 586 }
markrad 3:c0556ff7b8e3 587
markrad 3:c0556ff7b8e3 588 static JSON_Value * parse_value(const char **string, size_t nesting) {
markrad 3:c0556ff7b8e3 589 if (nesting > MAX_NESTING) {
markrad 3:c0556ff7b8e3 590 return NULL;
markrad 3:c0556ff7b8e3 591 }
markrad 3:c0556ff7b8e3 592 SKIP_WHITESPACES(string);
markrad 3:c0556ff7b8e3 593 switch (**string) {
markrad 3:c0556ff7b8e3 594 case '{':
markrad 3:c0556ff7b8e3 595 return parse_object_value(string, nesting + 1);
markrad 3:c0556ff7b8e3 596 case '[':
markrad 3:c0556ff7b8e3 597 return parse_array_value(string, nesting + 1);
markrad 3:c0556ff7b8e3 598 case '\"':
markrad 3:c0556ff7b8e3 599 return parse_string_value(string);
markrad 3:c0556ff7b8e3 600 case 'f': case 't':
markrad 3:c0556ff7b8e3 601 return parse_boolean_value(string);
markrad 3:c0556ff7b8e3 602 case '-':
markrad 3:c0556ff7b8e3 603 case '0': case '1': case '2': case '3': case '4':
markrad 3:c0556ff7b8e3 604 case '5': case '6': case '7': case '8': case '9':
markrad 3:c0556ff7b8e3 605 return parse_number_value(string);
markrad 3:c0556ff7b8e3 606 case 'n':
markrad 3:c0556ff7b8e3 607 return parse_null_value(string);
markrad 3:c0556ff7b8e3 608 default:
markrad 3:c0556ff7b8e3 609 return NULL;
markrad 3:c0556ff7b8e3 610 }
markrad 3:c0556ff7b8e3 611 }
markrad 3:c0556ff7b8e3 612
markrad 3:c0556ff7b8e3 613 static JSON_Value * parse_object_value(const char **string, size_t nesting) {
markrad 3:c0556ff7b8e3 614 JSON_Value *output_value = json_value_init_object(), *new_value = NULL;
markrad 3:c0556ff7b8e3 615 JSON_Object *output_object = json_value_get_object(output_value);
markrad 3:c0556ff7b8e3 616 char *new_key = NULL;
markrad 3:c0556ff7b8e3 617 if (output_value == NULL || **string != '{') {
markrad 3:c0556ff7b8e3 618 return NULL;
markrad 3:c0556ff7b8e3 619 }
markrad 3:c0556ff7b8e3 620 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 621 SKIP_WHITESPACES(string);
markrad 3:c0556ff7b8e3 622 if (**string == '}') { /* empty object */
markrad 3:c0556ff7b8e3 623 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 624 return output_value;
markrad 3:c0556ff7b8e3 625 }
markrad 3:c0556ff7b8e3 626 while (**string != '\0') {
markrad 3:c0556ff7b8e3 627 new_key = get_quoted_string(string);
markrad 3:c0556ff7b8e3 628 SKIP_WHITESPACES(string);
markrad 3:c0556ff7b8e3 629 if (new_key == NULL || **string != ':') {
markrad 3:c0556ff7b8e3 630 json_value_free(output_value);
markrad 3:c0556ff7b8e3 631 return NULL;
markrad 3:c0556ff7b8e3 632 }
markrad 3:c0556ff7b8e3 633 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 634 new_value = parse_value(string, nesting);
markrad 3:c0556ff7b8e3 635 if (new_value == NULL) {
markrad 3:c0556ff7b8e3 636 parson_free(new_key);
markrad 3:c0556ff7b8e3 637 json_value_free(output_value);
markrad 3:c0556ff7b8e3 638 return NULL;
markrad 3:c0556ff7b8e3 639 }
markrad 3:c0556ff7b8e3 640 if(json_object_add(output_object, new_key, new_value) == JSONFailure) {
markrad 3:c0556ff7b8e3 641 parson_free(new_key);
markrad 3:c0556ff7b8e3 642 parson_free(new_value);
markrad 3:c0556ff7b8e3 643 json_value_free(output_value);
markrad 3:c0556ff7b8e3 644 return NULL;
markrad 3:c0556ff7b8e3 645 }
markrad 3:c0556ff7b8e3 646 parson_free(new_key);
markrad 3:c0556ff7b8e3 647 SKIP_WHITESPACES(string);
markrad 3:c0556ff7b8e3 648 if (**string != ',') {
markrad 3:c0556ff7b8e3 649 break;
markrad 3:c0556ff7b8e3 650 }
markrad 3:c0556ff7b8e3 651 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 652 SKIP_WHITESPACES(string);
markrad 3:c0556ff7b8e3 653 }
markrad 3:c0556ff7b8e3 654 SKIP_WHITESPACES(string);
markrad 3:c0556ff7b8e3 655 if (**string != '}' || /* Trim object after parsing is over */
markrad 3:c0556ff7b8e3 656 json_object_resize(output_object, json_object_get_count(output_object)) == JSONFailure) {
markrad 3:c0556ff7b8e3 657 json_value_free(output_value);
markrad 3:c0556ff7b8e3 658 return NULL;
markrad 3:c0556ff7b8e3 659 }
markrad 3:c0556ff7b8e3 660 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 661 return output_value;
markrad 3:c0556ff7b8e3 662 }
markrad 3:c0556ff7b8e3 663
markrad 3:c0556ff7b8e3 664 static JSON_Value * parse_array_value(const char **string, size_t nesting) {
markrad 3:c0556ff7b8e3 665 JSON_Value *output_value = json_value_init_array(), *new_array_value = NULL;
markrad 3:c0556ff7b8e3 666 JSON_Array *output_array = json_value_get_array(output_value);
markrad 3:c0556ff7b8e3 667 if (!output_value || **string != '[') {
markrad 3:c0556ff7b8e3 668 return NULL;
markrad 3:c0556ff7b8e3 669 }
markrad 3:c0556ff7b8e3 670 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 671 SKIP_WHITESPACES(string);
markrad 3:c0556ff7b8e3 672 if (**string == ']') { /* empty array */
markrad 3:c0556ff7b8e3 673 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 674 return output_value;
markrad 3:c0556ff7b8e3 675 }
markrad 3:c0556ff7b8e3 676 while (**string != '\0') {
markrad 3:c0556ff7b8e3 677 new_array_value = parse_value(string, nesting);
markrad 3:c0556ff7b8e3 678 if (!new_array_value) {
markrad 3:c0556ff7b8e3 679 json_value_free(output_value);
markrad 3:c0556ff7b8e3 680 return NULL;
markrad 3:c0556ff7b8e3 681 }
markrad 3:c0556ff7b8e3 682 if (json_array_add(output_array, new_array_value) == JSONFailure) {
markrad 3:c0556ff7b8e3 683 parson_free(new_array_value);
markrad 3:c0556ff7b8e3 684 json_value_free(output_value);
markrad 3:c0556ff7b8e3 685 return NULL;
markrad 3:c0556ff7b8e3 686 }
markrad 3:c0556ff7b8e3 687 SKIP_WHITESPACES(string);
markrad 3:c0556ff7b8e3 688 if (**string != ',') {
markrad 3:c0556ff7b8e3 689 break;
markrad 3:c0556ff7b8e3 690 }
markrad 3:c0556ff7b8e3 691 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 692 SKIP_WHITESPACES(string);
markrad 3:c0556ff7b8e3 693 }
markrad 3:c0556ff7b8e3 694 SKIP_WHITESPACES(string);
markrad 3:c0556ff7b8e3 695 if (**string != ']' || /* Trim array after parsing is over */
markrad 3:c0556ff7b8e3 696 json_array_resize(output_array, json_array_get_count(output_array)) == JSONFailure) {
markrad 3:c0556ff7b8e3 697 json_value_free(output_value);
markrad 3:c0556ff7b8e3 698 return NULL;
markrad 3:c0556ff7b8e3 699 }
markrad 3:c0556ff7b8e3 700 SKIP_CHAR(string);
markrad 3:c0556ff7b8e3 701 return output_value;
markrad 3:c0556ff7b8e3 702 }
markrad 3:c0556ff7b8e3 703
markrad 3:c0556ff7b8e3 704 static JSON_Value * parse_string_value(const char **string) {
markrad 3:c0556ff7b8e3 705 JSON_Value *value = NULL;
markrad 3:c0556ff7b8e3 706 char *new_string = get_quoted_string(string);
markrad 3:c0556ff7b8e3 707 if (new_string == NULL) {
markrad 3:c0556ff7b8e3 708 return NULL;
markrad 3:c0556ff7b8e3 709 }
markrad 3:c0556ff7b8e3 710 value = json_value_init_string_no_copy(new_string);
markrad 3:c0556ff7b8e3 711 if (value == NULL) {
markrad 3:c0556ff7b8e3 712 parson_free(new_string);
markrad 3:c0556ff7b8e3 713 return NULL;
markrad 3:c0556ff7b8e3 714 }
markrad 3:c0556ff7b8e3 715 return value;
markrad 3:c0556ff7b8e3 716 }
markrad 3:c0556ff7b8e3 717
markrad 3:c0556ff7b8e3 718 static JSON_Value * parse_boolean_value(const char **string) {
markrad 3:c0556ff7b8e3 719 size_t true_token_size = SIZEOF_TOKEN("true");
markrad 3:c0556ff7b8e3 720 size_t false_token_size = SIZEOF_TOKEN("false");
markrad 3:c0556ff7b8e3 721 if (strncmp("true", *string, true_token_size) == 0) {
markrad 3:c0556ff7b8e3 722 *string += true_token_size;
markrad 3:c0556ff7b8e3 723 return json_value_init_boolean(1);
markrad 3:c0556ff7b8e3 724 } else if (strncmp("false", *string, false_token_size) == 0) {
markrad 3:c0556ff7b8e3 725 *string += false_token_size;
markrad 3:c0556ff7b8e3 726 return json_value_init_boolean(0);
markrad 3:c0556ff7b8e3 727 }
markrad 3:c0556ff7b8e3 728 return NULL;
markrad 3:c0556ff7b8e3 729 }
markrad 3:c0556ff7b8e3 730
markrad 3:c0556ff7b8e3 731 static JSON_Value * parse_number_value(const char **string) {
markrad 3:c0556ff7b8e3 732 char *end;
markrad 3:c0556ff7b8e3 733 double number = strtod(*string, &end);
markrad 3:c0556ff7b8e3 734 JSON_Value *output_value;
markrad 3:c0556ff7b8e3 735 if (is_decimal(*string, end - *string)) {
markrad 3:c0556ff7b8e3 736 *string = end;
markrad 3:c0556ff7b8e3 737 output_value = json_value_init_number(number);
markrad 3:c0556ff7b8e3 738 } else {
markrad 3:c0556ff7b8e3 739 output_value = NULL;
markrad 3:c0556ff7b8e3 740 }
markrad 3:c0556ff7b8e3 741 return output_value;
markrad 3:c0556ff7b8e3 742 }
markrad 3:c0556ff7b8e3 743
markrad 3:c0556ff7b8e3 744 static JSON_Value * parse_null_value(const char **string) {
markrad 3:c0556ff7b8e3 745 size_t token_size = SIZEOF_TOKEN("null");
markrad 3:c0556ff7b8e3 746 if (strncmp("null", *string, token_size) == 0) {
markrad 3:c0556ff7b8e3 747 *string += token_size;
markrad 3:c0556ff7b8e3 748 return json_value_init_null();
markrad 3:c0556ff7b8e3 749 }
markrad 3:c0556ff7b8e3 750 return NULL;
markrad 3:c0556ff7b8e3 751 }
markrad 3:c0556ff7b8e3 752
markrad 3:c0556ff7b8e3 753 /* Serialization */
markrad 3:c0556ff7b8e3 754 #define APPEND_STRING(str) do { written = append_string(buf, (str));\
markrad 3:c0556ff7b8e3 755 if (written < 0) { return -1; }\
markrad 3:c0556ff7b8e3 756 if (buf != NULL) { buf += written; }\
markrad 3:c0556ff7b8e3 757 written_total += written; } while(0)
markrad 3:c0556ff7b8e3 758
markrad 3:c0556ff7b8e3 759 #define APPEND_INDENT(level) do { written = append_indent(buf, (level));\
markrad 3:c0556ff7b8e3 760 if (written < 0) { return -1; }\
markrad 3:c0556ff7b8e3 761 if (buf != NULL) { buf += written; }\
markrad 3:c0556ff7b8e3 762 written_total += written; } while(0)
markrad 3:c0556ff7b8e3 763
markrad 3:c0556ff7b8e3 764 static int json_serialize_to_buffer_r(const JSON_Value *value, char *buf, int level, int is_pretty, char *num_buf)
markrad 3:c0556ff7b8e3 765 {
markrad 3:c0556ff7b8e3 766 const char *key = NULL, *string = NULL;
markrad 3:c0556ff7b8e3 767 JSON_Value *temp_value = NULL;
markrad 3:c0556ff7b8e3 768 JSON_Array *array = NULL;
markrad 3:c0556ff7b8e3 769 JSON_Object *object = NULL;
markrad 3:c0556ff7b8e3 770 size_t i = 0, count = 0;
markrad 3:c0556ff7b8e3 771 double num = 0.0;
markrad 3:c0556ff7b8e3 772 int written = -1, written_total = 0;
markrad 3:c0556ff7b8e3 773
markrad 3:c0556ff7b8e3 774 switch (json_value_get_type(value)) {
markrad 3:c0556ff7b8e3 775 case JSONArray:
markrad 3:c0556ff7b8e3 776 array = json_value_get_array(value);
markrad 3:c0556ff7b8e3 777 count = json_array_get_count(array);
markrad 3:c0556ff7b8e3 778 APPEND_STRING("[");
markrad 3:c0556ff7b8e3 779 if (count > 0 && is_pretty) {
markrad 3:c0556ff7b8e3 780 APPEND_STRING("\n");
markrad 3:c0556ff7b8e3 781 }
markrad 3:c0556ff7b8e3 782 for (i = 0; i < count; i++) {
markrad 3:c0556ff7b8e3 783 if (is_pretty) {
markrad 3:c0556ff7b8e3 784 APPEND_INDENT(level+1);
markrad 3:c0556ff7b8e3 785 }
markrad 3:c0556ff7b8e3 786 temp_value = json_array_get_value(array, i);
markrad 3:c0556ff7b8e3 787 written = json_serialize_to_buffer_r(temp_value, buf, level+1, is_pretty, num_buf);
markrad 3:c0556ff7b8e3 788 if (written < 0) {
markrad 3:c0556ff7b8e3 789 return -1;
markrad 3:c0556ff7b8e3 790 }
markrad 3:c0556ff7b8e3 791 if (buf != NULL) {
markrad 3:c0556ff7b8e3 792 buf += written;
markrad 3:c0556ff7b8e3 793 }
markrad 3:c0556ff7b8e3 794 written_total += written;
markrad 3:c0556ff7b8e3 795 if (i < (count - 1)) {
markrad 3:c0556ff7b8e3 796 APPEND_STRING(",");
markrad 3:c0556ff7b8e3 797 }
markrad 3:c0556ff7b8e3 798 if (is_pretty) {
markrad 3:c0556ff7b8e3 799 APPEND_STRING("\n");
markrad 3:c0556ff7b8e3 800 }
markrad 3:c0556ff7b8e3 801 }
markrad 3:c0556ff7b8e3 802 if (count > 0 && is_pretty) {
markrad 3:c0556ff7b8e3 803 APPEND_INDENT(level);
markrad 3:c0556ff7b8e3 804 }
markrad 3:c0556ff7b8e3 805 APPEND_STRING("]");
markrad 3:c0556ff7b8e3 806 return written_total;
markrad 3:c0556ff7b8e3 807 case JSONObject:
markrad 3:c0556ff7b8e3 808 object = json_value_get_object(value);
markrad 3:c0556ff7b8e3 809 count = json_object_get_count(object);
markrad 3:c0556ff7b8e3 810 APPEND_STRING("{");
markrad 3:c0556ff7b8e3 811 if (count > 0 && is_pretty) {
markrad 3:c0556ff7b8e3 812 APPEND_STRING("\n");
markrad 3:c0556ff7b8e3 813 }
markrad 3:c0556ff7b8e3 814 for (i = 0; i < count; i++) {
markrad 3:c0556ff7b8e3 815 key = json_object_get_name(object, i);
markrad 3:c0556ff7b8e3 816 if (is_pretty) {
markrad 3:c0556ff7b8e3 817 APPEND_INDENT(level+1);
markrad 3:c0556ff7b8e3 818 }
markrad 3:c0556ff7b8e3 819 written = json_serialize_string(key, buf);
markrad 3:c0556ff7b8e3 820 if (written < 0) {
markrad 3:c0556ff7b8e3 821 return -1;
markrad 3:c0556ff7b8e3 822 }
markrad 3:c0556ff7b8e3 823 if (buf != NULL) {
markrad 3:c0556ff7b8e3 824 buf += written;
markrad 3:c0556ff7b8e3 825 }
markrad 3:c0556ff7b8e3 826 written_total += written;
markrad 3:c0556ff7b8e3 827 APPEND_STRING(":");
markrad 3:c0556ff7b8e3 828 if (is_pretty) {
markrad 3:c0556ff7b8e3 829 APPEND_STRING(" ");
markrad 3:c0556ff7b8e3 830 }
markrad 3:c0556ff7b8e3 831 temp_value = json_object_get_value(object, key);
markrad 3:c0556ff7b8e3 832 written = json_serialize_to_buffer_r(temp_value, buf, level+1, is_pretty, num_buf);
markrad 3:c0556ff7b8e3 833 if (written < 0) {
markrad 3:c0556ff7b8e3 834 return -1;
markrad 3:c0556ff7b8e3 835 }
markrad 3:c0556ff7b8e3 836 if (buf != NULL) {
markrad 3:c0556ff7b8e3 837 buf += written;
markrad 3:c0556ff7b8e3 838 }
markrad 3:c0556ff7b8e3 839 written_total += written;
markrad 3:c0556ff7b8e3 840 if (i < (count - 1)) {
markrad 3:c0556ff7b8e3 841 APPEND_STRING(",");
markrad 3:c0556ff7b8e3 842 }
markrad 3:c0556ff7b8e3 843 if (is_pretty) {
markrad 3:c0556ff7b8e3 844 APPEND_STRING("\n");
markrad 3:c0556ff7b8e3 845 }
markrad 3:c0556ff7b8e3 846 }
markrad 3:c0556ff7b8e3 847 if (count > 0 && is_pretty) {
markrad 3:c0556ff7b8e3 848 APPEND_INDENT(level);
markrad 3:c0556ff7b8e3 849 }
markrad 3:c0556ff7b8e3 850 APPEND_STRING("}");
markrad 3:c0556ff7b8e3 851 return written_total;
markrad 3:c0556ff7b8e3 852 case JSONString:
markrad 3:c0556ff7b8e3 853 string = json_value_get_string(value);
markrad 3:c0556ff7b8e3 854 written = json_serialize_string(string, buf);
markrad 3:c0556ff7b8e3 855 if (written < 0) {
markrad 3:c0556ff7b8e3 856 return -1;
markrad 3:c0556ff7b8e3 857 }
markrad 3:c0556ff7b8e3 858 if (buf != NULL) {
markrad 3:c0556ff7b8e3 859 buf += written;
markrad 3:c0556ff7b8e3 860 }
markrad 3:c0556ff7b8e3 861 written_total += written;
markrad 3:c0556ff7b8e3 862 return written_total;
markrad 3:c0556ff7b8e3 863 case JSONBoolean:
markrad 3:c0556ff7b8e3 864 if (json_value_get_boolean(value)) {
markrad 3:c0556ff7b8e3 865 APPEND_STRING("true");
markrad 3:c0556ff7b8e3 866 } else {
markrad 3:c0556ff7b8e3 867 APPEND_STRING("false");
markrad 3:c0556ff7b8e3 868 }
markrad 3:c0556ff7b8e3 869 return written_total;
markrad 3:c0556ff7b8e3 870 case JSONNumber:
markrad 3:c0556ff7b8e3 871 num = json_value_get_number(value);
markrad 3:c0556ff7b8e3 872 if (buf != NULL) {
markrad 3:c0556ff7b8e3 873 num_buf = buf;
markrad 3:c0556ff7b8e3 874 }
markrad 3:c0556ff7b8e3 875 if (num == ((double)(int)num)) { /* check if num is integer */
markrad 3:c0556ff7b8e3 876 written = sprintf(num_buf, "%d", (int)num);
markrad 3:c0556ff7b8e3 877 } else {
markrad 3:c0556ff7b8e3 878 written = sprintf(num_buf, DOUBLE_SERIALIZATION_FORMAT, num);
markrad 3:c0556ff7b8e3 879 }
markrad 3:c0556ff7b8e3 880 if (written < 0) {
markrad 3:c0556ff7b8e3 881 return -1;
markrad 3:c0556ff7b8e3 882 }
markrad 3:c0556ff7b8e3 883 if (buf != NULL) {
markrad 3:c0556ff7b8e3 884 buf += written;
markrad 3:c0556ff7b8e3 885 }
markrad 3:c0556ff7b8e3 886 written_total += written;
markrad 3:c0556ff7b8e3 887 return written_total;
markrad 3:c0556ff7b8e3 888 case JSONNull:
markrad 3:c0556ff7b8e3 889 APPEND_STRING("null");
markrad 3:c0556ff7b8e3 890 return written_total;
markrad 3:c0556ff7b8e3 891 case JSONError:
markrad 3:c0556ff7b8e3 892 return -1;
markrad 3:c0556ff7b8e3 893 default:
markrad 3:c0556ff7b8e3 894 return -1;
markrad 3:c0556ff7b8e3 895 }
markrad 3:c0556ff7b8e3 896 }
markrad 3:c0556ff7b8e3 897
markrad 3:c0556ff7b8e3 898 static int json_serialize_string(const char *string, char *buf) {
markrad 3:c0556ff7b8e3 899 size_t i = 0, len = strlen(string);
markrad 3:c0556ff7b8e3 900 char c = '\0';
markrad 3:c0556ff7b8e3 901 int written = -1, written_total = 0;
markrad 3:c0556ff7b8e3 902 APPEND_STRING("\"");
markrad 3:c0556ff7b8e3 903 for (i = 0; i < len; i++) {
markrad 3:c0556ff7b8e3 904 c = string[i];
markrad 3:c0556ff7b8e3 905 switch (c) {
markrad 3:c0556ff7b8e3 906 case '\"': APPEND_STRING("\\\""); break;
markrad 3:c0556ff7b8e3 907 case '\\': APPEND_STRING("\\\\"); break;
markrad 3:c0556ff7b8e3 908 case '/': APPEND_STRING("\\/"); break; /* to make json embeddable in xml\/html */
markrad 3:c0556ff7b8e3 909 case '\b': APPEND_STRING("\\b"); break;
markrad 3:c0556ff7b8e3 910 case '\f': APPEND_STRING("\\f"); break;
markrad 3:c0556ff7b8e3 911 case '\n': APPEND_STRING("\\n"); break;
markrad 3:c0556ff7b8e3 912 case '\r': APPEND_STRING("\\r"); break;
markrad 3:c0556ff7b8e3 913 case '\t': APPEND_STRING("\\t"); break;
markrad 3:c0556ff7b8e3 914 default:
markrad 3:c0556ff7b8e3 915 if (buf != NULL) {
markrad 3:c0556ff7b8e3 916 buf[0] = c;
markrad 3:c0556ff7b8e3 917 buf += 1;
markrad 3:c0556ff7b8e3 918 }
markrad 3:c0556ff7b8e3 919 written_total += 1;
markrad 3:c0556ff7b8e3 920 break;
markrad 3:c0556ff7b8e3 921 }
markrad 3:c0556ff7b8e3 922 }
markrad 3:c0556ff7b8e3 923 APPEND_STRING("\"");
markrad 3:c0556ff7b8e3 924 return written_total;
markrad 3:c0556ff7b8e3 925 }
markrad 3:c0556ff7b8e3 926
markrad 3:c0556ff7b8e3 927 static int append_indent(char *buf, int level) {
markrad 3:c0556ff7b8e3 928 int i;
markrad 3:c0556ff7b8e3 929 int written = -1, written_total = 0;
markrad 3:c0556ff7b8e3 930 for (i = 0; i < level; i++) {
markrad 3:c0556ff7b8e3 931 APPEND_STRING(" ");
markrad 3:c0556ff7b8e3 932 }
markrad 3:c0556ff7b8e3 933 return written_total;
markrad 3:c0556ff7b8e3 934 }
markrad 3:c0556ff7b8e3 935
markrad 3:c0556ff7b8e3 936 static int append_string(char *buf, const char *string) {
markrad 3:c0556ff7b8e3 937 if (buf == NULL) {
markrad 3:c0556ff7b8e3 938 return (int)strlen(string);
markrad 3:c0556ff7b8e3 939 }
markrad 3:c0556ff7b8e3 940 return sprintf(buf, "%s", string);
markrad 3:c0556ff7b8e3 941 }
markrad 3:c0556ff7b8e3 942
markrad 3:c0556ff7b8e3 943 #undef APPEND_STRING
markrad 3:c0556ff7b8e3 944 #undef APPEND_INDENT
markrad 3:c0556ff7b8e3 945
markrad 3:c0556ff7b8e3 946 /* Parser API */
markrad 3:c0556ff7b8e3 947 JSON_Value * json_parse_file(const char *filename) {
markrad 3:c0556ff7b8e3 948 char *file_contents = read_file(filename);
markrad 3:c0556ff7b8e3 949 JSON_Value *output_value = NULL;
markrad 3:c0556ff7b8e3 950 if (file_contents == NULL) {
markrad 3:c0556ff7b8e3 951 return NULL;
markrad 3:c0556ff7b8e3 952 }
markrad 3:c0556ff7b8e3 953 output_value = json_parse_string(file_contents);
markrad 3:c0556ff7b8e3 954 parson_free(file_contents);
markrad 3:c0556ff7b8e3 955 return output_value;
markrad 3:c0556ff7b8e3 956 }
markrad 3:c0556ff7b8e3 957
markrad 3:c0556ff7b8e3 958 JSON_Value * json_parse_file_with_comments(const char *filename) {
markrad 3:c0556ff7b8e3 959 char *file_contents = read_file(filename);
markrad 3:c0556ff7b8e3 960 JSON_Value *output_value = NULL;
markrad 3:c0556ff7b8e3 961 if (file_contents == NULL) {
markrad 3:c0556ff7b8e3 962 return NULL;
markrad 3:c0556ff7b8e3 963 }
markrad 3:c0556ff7b8e3 964 output_value = json_parse_string_with_comments(file_contents);
markrad 3:c0556ff7b8e3 965 parson_free(file_contents);
markrad 3:c0556ff7b8e3 966 return output_value;
markrad 3:c0556ff7b8e3 967 }
markrad 3:c0556ff7b8e3 968
markrad 3:c0556ff7b8e3 969 JSON_Value * json_parse_string(const char *string) {
markrad 3:c0556ff7b8e3 970 if (string == NULL) {
markrad 3:c0556ff7b8e3 971 return NULL;
markrad 3:c0556ff7b8e3 972 }
markrad 3:c0556ff7b8e3 973 return parse_value((const char**)&string, 0);
markrad 3:c0556ff7b8e3 974 }
markrad 3:c0556ff7b8e3 975
markrad 3:c0556ff7b8e3 976 JSON_Value * json_parse_string_with_comments(const char *string) {
markrad 3:c0556ff7b8e3 977 JSON_Value *result = NULL;
markrad 3:c0556ff7b8e3 978 char *string_mutable_copy = NULL, *string_mutable_copy_ptr = NULL;
markrad 3:c0556ff7b8e3 979 string_mutable_copy = parson_strdup(string);
markrad 3:c0556ff7b8e3 980 if (string_mutable_copy == NULL) {
markrad 3:c0556ff7b8e3 981 return NULL;
markrad 3:c0556ff7b8e3 982 }
markrad 3:c0556ff7b8e3 983 remove_comments(string_mutable_copy, "/*", "*/");
markrad 3:c0556ff7b8e3 984 remove_comments(string_mutable_copy, "//", "\n");
markrad 3:c0556ff7b8e3 985 string_mutable_copy_ptr = string_mutable_copy;
markrad 3:c0556ff7b8e3 986 result = parse_value((const char**)&string_mutable_copy_ptr, 0);
markrad 3:c0556ff7b8e3 987 parson_free(string_mutable_copy);
markrad 3:c0556ff7b8e3 988 return result;
markrad 3:c0556ff7b8e3 989 }
markrad 3:c0556ff7b8e3 990
markrad 3:c0556ff7b8e3 991 /* JSON Object API */
markrad 3:c0556ff7b8e3 992
markrad 3:c0556ff7b8e3 993 JSON_Value * json_object_get_value(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 994 if (object == NULL || name == NULL) {
markrad 3:c0556ff7b8e3 995 return NULL;
markrad 3:c0556ff7b8e3 996 }
markrad 3:c0556ff7b8e3 997 return json_object_nget_value(object, name, strlen(name));
markrad 3:c0556ff7b8e3 998 }
markrad 3:c0556ff7b8e3 999
markrad 3:c0556ff7b8e3 1000 const char * json_object_get_string(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1001 return json_value_get_string(json_object_get_value(object, name));
markrad 3:c0556ff7b8e3 1002 }
markrad 3:c0556ff7b8e3 1003
markrad 3:c0556ff7b8e3 1004 double json_object_get_number(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1005 return json_value_get_number(json_object_get_value(object, name));
markrad 3:c0556ff7b8e3 1006 }
markrad 3:c0556ff7b8e3 1007
markrad 3:c0556ff7b8e3 1008 JSON_Object * json_object_get_object(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1009 return json_value_get_object(json_object_get_value(object, name));
markrad 3:c0556ff7b8e3 1010 }
markrad 3:c0556ff7b8e3 1011
markrad 3:c0556ff7b8e3 1012 JSON_Array * json_object_get_array(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1013 return json_value_get_array(json_object_get_value(object, name));
markrad 3:c0556ff7b8e3 1014 }
markrad 3:c0556ff7b8e3 1015
markrad 3:c0556ff7b8e3 1016 int json_object_get_boolean(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1017 return json_value_get_boolean(json_object_get_value(object, name));
markrad 3:c0556ff7b8e3 1018 }
markrad 3:c0556ff7b8e3 1019
markrad 3:c0556ff7b8e3 1020 JSON_Value * json_object_dotget_value(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1021 const char *dot_position = strchr(name, '.');
markrad 3:c0556ff7b8e3 1022 if (!dot_position) {
markrad 3:c0556ff7b8e3 1023 return json_object_get_value(object, name);
markrad 3:c0556ff7b8e3 1024 }
markrad 3:c0556ff7b8e3 1025 object = json_value_get_object(json_object_nget_value(object, name, dot_position - name));
markrad 3:c0556ff7b8e3 1026 return json_object_dotget_value(object, dot_position + 1);
markrad 3:c0556ff7b8e3 1027 }
markrad 3:c0556ff7b8e3 1028
markrad 3:c0556ff7b8e3 1029 const char * json_object_dotget_string(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1030 return json_value_get_string(json_object_dotget_value(object, name));
markrad 3:c0556ff7b8e3 1031 }
markrad 3:c0556ff7b8e3 1032
markrad 3:c0556ff7b8e3 1033 double json_object_dotget_number(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1034 return json_value_get_number(json_object_dotget_value(object, name));
markrad 3:c0556ff7b8e3 1035 }
markrad 3:c0556ff7b8e3 1036
markrad 3:c0556ff7b8e3 1037 JSON_Object * json_object_dotget_object(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1038 return json_value_get_object(json_object_dotget_value(object, name));
markrad 3:c0556ff7b8e3 1039 }
markrad 3:c0556ff7b8e3 1040
markrad 3:c0556ff7b8e3 1041 JSON_Array * json_object_dotget_array(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1042 return json_value_get_array(json_object_dotget_value(object, name));
markrad 3:c0556ff7b8e3 1043 }
markrad 3:c0556ff7b8e3 1044
markrad 3:c0556ff7b8e3 1045 int json_object_dotget_boolean(const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1046 return json_value_get_boolean(json_object_dotget_value(object, name));
markrad 3:c0556ff7b8e3 1047 }
markrad 3:c0556ff7b8e3 1048
markrad 3:c0556ff7b8e3 1049 size_t json_object_get_count(const JSON_Object *object) {
markrad 3:c0556ff7b8e3 1050 return object ? object->count : 0;
markrad 3:c0556ff7b8e3 1051 }
markrad 3:c0556ff7b8e3 1052
markrad 3:c0556ff7b8e3 1053 const char * json_object_get_name(const JSON_Object *object, size_t index) {
markrad 3:c0556ff7b8e3 1054 if (object == NULL || index >= json_object_get_count(object)) {
markrad 3:c0556ff7b8e3 1055 return NULL;
markrad 3:c0556ff7b8e3 1056 }
markrad 3:c0556ff7b8e3 1057 return object->names[index];
markrad 3:c0556ff7b8e3 1058 }
markrad 3:c0556ff7b8e3 1059
markrad 3:c0556ff7b8e3 1060 JSON_Value * json_object_get_value_at(const JSON_Object *object, size_t index) {
markrad 3:c0556ff7b8e3 1061 if (object == NULL || index >= json_object_get_count(object)) {
markrad 3:c0556ff7b8e3 1062 return NULL;
markrad 3:c0556ff7b8e3 1063 }
markrad 3:c0556ff7b8e3 1064 return object->values[index];
markrad 3:c0556ff7b8e3 1065 }
markrad 3:c0556ff7b8e3 1066
markrad 3:c0556ff7b8e3 1067 int json_object_has_value (const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1068 return json_object_get_value(object, name) != NULL;
markrad 3:c0556ff7b8e3 1069 }
markrad 3:c0556ff7b8e3 1070
markrad 3:c0556ff7b8e3 1071 int json_object_has_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type) {
markrad 3:c0556ff7b8e3 1072 JSON_Value *val = json_object_get_value(object, name);
markrad 3:c0556ff7b8e3 1073 return val != NULL && json_value_get_type(val) == type;
markrad 3:c0556ff7b8e3 1074 }
markrad 3:c0556ff7b8e3 1075
markrad 3:c0556ff7b8e3 1076 int json_object_dothas_value (const JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1077 return json_object_dotget_value(object, name) != NULL;
markrad 3:c0556ff7b8e3 1078 }
markrad 3:c0556ff7b8e3 1079
markrad 3:c0556ff7b8e3 1080 int json_object_dothas_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type) {
markrad 3:c0556ff7b8e3 1081 JSON_Value *val = json_object_dotget_value(object, name);
markrad 3:c0556ff7b8e3 1082 return val != NULL && json_value_get_type(val) == type;
markrad 3:c0556ff7b8e3 1083 }
markrad 3:c0556ff7b8e3 1084
markrad 3:c0556ff7b8e3 1085 /* JSON Array API */
markrad 3:c0556ff7b8e3 1086 JSON_Value * json_array_get_value(const JSON_Array *array, size_t index) {
markrad 3:c0556ff7b8e3 1087 if (array == NULL || index >= json_array_get_count(array)) {
markrad 3:c0556ff7b8e3 1088 return NULL;
markrad 3:c0556ff7b8e3 1089 }
markrad 3:c0556ff7b8e3 1090 return array->items[index];
markrad 3:c0556ff7b8e3 1091 }
markrad 3:c0556ff7b8e3 1092
markrad 3:c0556ff7b8e3 1093 const char * json_array_get_string(const JSON_Array *array, size_t index) {
markrad 3:c0556ff7b8e3 1094 return json_value_get_string(json_array_get_value(array, index));
markrad 3:c0556ff7b8e3 1095 }
markrad 3:c0556ff7b8e3 1096
markrad 3:c0556ff7b8e3 1097 double json_array_get_number(const JSON_Array *array, size_t index) {
markrad 3:c0556ff7b8e3 1098 return json_value_get_number(json_array_get_value(array, index));
markrad 3:c0556ff7b8e3 1099 }
markrad 3:c0556ff7b8e3 1100
markrad 3:c0556ff7b8e3 1101 JSON_Object * json_array_get_object(const JSON_Array *array, size_t index) {
markrad 3:c0556ff7b8e3 1102 return json_value_get_object(json_array_get_value(array, index));
markrad 3:c0556ff7b8e3 1103 }
markrad 3:c0556ff7b8e3 1104
markrad 3:c0556ff7b8e3 1105 JSON_Array * json_array_get_array(const JSON_Array *array, size_t index) {
markrad 3:c0556ff7b8e3 1106 return json_value_get_array(json_array_get_value(array, index));
markrad 3:c0556ff7b8e3 1107 }
markrad 3:c0556ff7b8e3 1108
markrad 3:c0556ff7b8e3 1109 int json_array_get_boolean(const JSON_Array *array, size_t index) {
markrad 3:c0556ff7b8e3 1110 return json_value_get_boolean(json_array_get_value(array, index));
markrad 3:c0556ff7b8e3 1111 }
markrad 3:c0556ff7b8e3 1112
markrad 3:c0556ff7b8e3 1113 size_t json_array_get_count(const JSON_Array *array) {
markrad 3:c0556ff7b8e3 1114 return array ? array->count : 0;
markrad 3:c0556ff7b8e3 1115 }
markrad 3:c0556ff7b8e3 1116
markrad 3:c0556ff7b8e3 1117 /* JSON Value API */
markrad 3:c0556ff7b8e3 1118 JSON_Value_Type json_value_get_type(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1119 return value ? value->type : JSONError;
markrad 3:c0556ff7b8e3 1120 }
markrad 3:c0556ff7b8e3 1121
markrad 3:c0556ff7b8e3 1122 JSON_Object * json_value_get_object(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1123 return json_value_get_type(value) == JSONObject ? value->value.object : NULL;
markrad 3:c0556ff7b8e3 1124 }
markrad 3:c0556ff7b8e3 1125
markrad 3:c0556ff7b8e3 1126 JSON_Array * json_value_get_array(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1127 return json_value_get_type(value) == JSONArray ? value->value.array : NULL;
markrad 3:c0556ff7b8e3 1128 }
markrad 3:c0556ff7b8e3 1129
markrad 3:c0556ff7b8e3 1130 const char * json_value_get_string(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1131 return json_value_get_type(value) == JSONString ? value->value.string : NULL;
markrad 3:c0556ff7b8e3 1132 }
markrad 3:c0556ff7b8e3 1133
markrad 3:c0556ff7b8e3 1134 double json_value_get_number(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1135 return json_value_get_type(value) == JSONNumber ? value->value.number : 0;
markrad 3:c0556ff7b8e3 1136 }
markrad 3:c0556ff7b8e3 1137
markrad 3:c0556ff7b8e3 1138 int json_value_get_boolean(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1139 return json_value_get_type(value) == JSONBoolean ? value->value.boolean : -1;
markrad 3:c0556ff7b8e3 1140 }
markrad 3:c0556ff7b8e3 1141
markrad 3:c0556ff7b8e3 1142 void json_value_free(JSON_Value *value) {
markrad 3:c0556ff7b8e3 1143 switch (json_value_get_type(value)) {
markrad 3:c0556ff7b8e3 1144 case JSONObject:
markrad 3:c0556ff7b8e3 1145 json_object_free(value->value.object);
markrad 3:c0556ff7b8e3 1146 break;
markrad 3:c0556ff7b8e3 1147 case JSONString:
markrad 3:c0556ff7b8e3 1148 if (value->value.string) {
markrad 3:c0556ff7b8e3 1149 parson_free(value->value.string);
markrad 3:c0556ff7b8e3 1150 }
markrad 3:c0556ff7b8e3 1151 break;
markrad 3:c0556ff7b8e3 1152 case JSONArray:
markrad 3:c0556ff7b8e3 1153 json_array_free(value->value.array);
markrad 3:c0556ff7b8e3 1154 break;
markrad 3:c0556ff7b8e3 1155 default:
markrad 3:c0556ff7b8e3 1156 break;
markrad 3:c0556ff7b8e3 1157 }
markrad 3:c0556ff7b8e3 1158 parson_free(value);
markrad 3:c0556ff7b8e3 1159 }
markrad 3:c0556ff7b8e3 1160
markrad 3:c0556ff7b8e3 1161 JSON_Value * json_value_init_object(void) {
markrad 3:c0556ff7b8e3 1162 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
markrad 3:c0556ff7b8e3 1163 if (!new_value) {
markrad 3:c0556ff7b8e3 1164 return NULL;
markrad 3:c0556ff7b8e3 1165 }
markrad 3:c0556ff7b8e3 1166 new_value->type = JSONObject;
markrad 3:c0556ff7b8e3 1167 new_value->value.object = json_object_init();
markrad 3:c0556ff7b8e3 1168 if (!new_value->value.object) {
markrad 3:c0556ff7b8e3 1169 parson_free(new_value);
markrad 3:c0556ff7b8e3 1170 return NULL;
markrad 3:c0556ff7b8e3 1171 }
markrad 3:c0556ff7b8e3 1172 return new_value;
markrad 3:c0556ff7b8e3 1173 }
markrad 3:c0556ff7b8e3 1174
markrad 3:c0556ff7b8e3 1175 JSON_Value * json_value_init_array(void) {
markrad 3:c0556ff7b8e3 1176 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
markrad 3:c0556ff7b8e3 1177 if (!new_value) {
markrad 3:c0556ff7b8e3 1178 return NULL;
markrad 3:c0556ff7b8e3 1179 }
markrad 3:c0556ff7b8e3 1180 new_value->type = JSONArray;
markrad 3:c0556ff7b8e3 1181 new_value->value.array = json_array_init();
markrad 3:c0556ff7b8e3 1182 if (!new_value->value.array) {
markrad 3:c0556ff7b8e3 1183 parson_free(new_value);
markrad 3:c0556ff7b8e3 1184 return NULL;
markrad 3:c0556ff7b8e3 1185 }
markrad 3:c0556ff7b8e3 1186 return new_value;
markrad 3:c0556ff7b8e3 1187 }
markrad 3:c0556ff7b8e3 1188
markrad 3:c0556ff7b8e3 1189 JSON_Value * json_value_init_string(const char *string) {
markrad 3:c0556ff7b8e3 1190 char *copy = NULL;
markrad 3:c0556ff7b8e3 1191 JSON_Value *value;
markrad 3:c0556ff7b8e3 1192 size_t string_len = 0;
markrad 3:c0556ff7b8e3 1193 if (string == NULL) {
markrad 3:c0556ff7b8e3 1194 return NULL;
markrad 3:c0556ff7b8e3 1195 }
markrad 3:c0556ff7b8e3 1196 string_len = strlen(string);
markrad 3:c0556ff7b8e3 1197 if (!is_valid_utf8(string, string_len)) {
markrad 3:c0556ff7b8e3 1198 return NULL;
markrad 3:c0556ff7b8e3 1199 }
markrad 3:c0556ff7b8e3 1200 copy = parson_strndup(string, string_len);
markrad 3:c0556ff7b8e3 1201 if (copy == NULL) {
markrad 3:c0556ff7b8e3 1202 return NULL;
markrad 3:c0556ff7b8e3 1203 }
markrad 3:c0556ff7b8e3 1204 value = json_value_init_string_no_copy(copy);
markrad 3:c0556ff7b8e3 1205 if (value == NULL) {
markrad 3:c0556ff7b8e3 1206 parson_free(copy);
markrad 3:c0556ff7b8e3 1207 }
markrad 3:c0556ff7b8e3 1208 return value;
markrad 3:c0556ff7b8e3 1209 }
markrad 3:c0556ff7b8e3 1210
markrad 3:c0556ff7b8e3 1211 JSON_Value * json_value_init_number(double number) {
markrad 3:c0556ff7b8e3 1212 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
markrad 3:c0556ff7b8e3 1213 if (!new_value) {
markrad 3:c0556ff7b8e3 1214 return NULL;
markrad 3:c0556ff7b8e3 1215 }
markrad 3:c0556ff7b8e3 1216 new_value->type = JSONNumber;
markrad 3:c0556ff7b8e3 1217 new_value->value.number = number;
markrad 3:c0556ff7b8e3 1218 return new_value;
markrad 3:c0556ff7b8e3 1219 }
markrad 3:c0556ff7b8e3 1220
markrad 3:c0556ff7b8e3 1221 JSON_Value * json_value_init_boolean(int boolean) {
markrad 3:c0556ff7b8e3 1222 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
markrad 3:c0556ff7b8e3 1223 if (!new_value) {
markrad 3:c0556ff7b8e3 1224 return NULL;
markrad 3:c0556ff7b8e3 1225 }
markrad 3:c0556ff7b8e3 1226 new_value->type = JSONBoolean;
markrad 3:c0556ff7b8e3 1227 new_value->value.boolean = boolean ? 1 : 0;
markrad 3:c0556ff7b8e3 1228 return new_value;
markrad 3:c0556ff7b8e3 1229 }
markrad 3:c0556ff7b8e3 1230
markrad 3:c0556ff7b8e3 1231 JSON_Value * json_value_init_null(void) {
markrad 3:c0556ff7b8e3 1232 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
markrad 3:c0556ff7b8e3 1233 if (!new_value) {
markrad 3:c0556ff7b8e3 1234 return NULL;
markrad 3:c0556ff7b8e3 1235 }
markrad 3:c0556ff7b8e3 1236 new_value->type = JSONNull;
markrad 3:c0556ff7b8e3 1237 return new_value;
markrad 3:c0556ff7b8e3 1238 }
markrad 3:c0556ff7b8e3 1239
markrad 3:c0556ff7b8e3 1240 JSON_Value * json_value_deep_copy(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1241 size_t i = 0;
markrad 3:c0556ff7b8e3 1242 JSON_Value *return_value = NULL, *temp_value_copy = NULL, *temp_value = NULL;
markrad 3:c0556ff7b8e3 1243 const char *temp_string = NULL, *temp_key = NULL;
markrad 3:c0556ff7b8e3 1244 char *temp_string_copy = NULL;
markrad 3:c0556ff7b8e3 1245 JSON_Array *temp_array = NULL, *temp_array_copy = NULL;
markrad 3:c0556ff7b8e3 1246 JSON_Object *temp_object = NULL, *temp_object_copy = NULL;
markrad 3:c0556ff7b8e3 1247
markrad 3:c0556ff7b8e3 1248 switch (json_value_get_type(value)) {
markrad 3:c0556ff7b8e3 1249 case JSONArray:
markrad 3:c0556ff7b8e3 1250 temp_array = json_value_get_array(value);
markrad 3:c0556ff7b8e3 1251 return_value = json_value_init_array();
markrad 3:c0556ff7b8e3 1252 if (return_value == NULL) {
markrad 3:c0556ff7b8e3 1253 return NULL;
markrad 3:c0556ff7b8e3 1254 }
markrad 3:c0556ff7b8e3 1255 temp_array_copy = json_value_get_array(return_value);
markrad 3:c0556ff7b8e3 1256 for (i = 0; i < json_array_get_count(temp_array); i++) {
markrad 3:c0556ff7b8e3 1257 temp_value = json_array_get_value(temp_array, i);
markrad 3:c0556ff7b8e3 1258 temp_value_copy = json_value_deep_copy(temp_value);
markrad 3:c0556ff7b8e3 1259 if (temp_value_copy == NULL) {
markrad 3:c0556ff7b8e3 1260 json_value_free(return_value);
markrad 3:c0556ff7b8e3 1261 return NULL;
markrad 3:c0556ff7b8e3 1262 }
markrad 3:c0556ff7b8e3 1263 if (json_array_add(temp_array_copy, temp_value_copy) == JSONFailure) {
markrad 3:c0556ff7b8e3 1264 json_value_free(return_value);
markrad 3:c0556ff7b8e3 1265 json_value_free(temp_value_copy);
markrad 3:c0556ff7b8e3 1266 return NULL;
markrad 3:c0556ff7b8e3 1267 }
markrad 3:c0556ff7b8e3 1268 }
markrad 3:c0556ff7b8e3 1269 return return_value;
markrad 3:c0556ff7b8e3 1270 case JSONObject:
markrad 3:c0556ff7b8e3 1271 temp_object = json_value_get_object(value);
markrad 3:c0556ff7b8e3 1272 return_value = json_value_init_object();
markrad 3:c0556ff7b8e3 1273 if (return_value == NULL) {
markrad 3:c0556ff7b8e3 1274 return NULL;
markrad 3:c0556ff7b8e3 1275 }
markrad 3:c0556ff7b8e3 1276 temp_object_copy = json_value_get_object(return_value);
markrad 3:c0556ff7b8e3 1277 for (i = 0; i < json_object_get_count(temp_object); i++) {
markrad 3:c0556ff7b8e3 1278 temp_key = json_object_get_name(temp_object, i);
markrad 3:c0556ff7b8e3 1279 temp_value = json_object_get_value(temp_object, temp_key);
markrad 3:c0556ff7b8e3 1280 temp_value_copy = json_value_deep_copy(temp_value);
markrad 3:c0556ff7b8e3 1281 if (temp_value_copy == NULL) {
markrad 3:c0556ff7b8e3 1282 json_value_free(return_value);
markrad 3:c0556ff7b8e3 1283 return NULL;
markrad 3:c0556ff7b8e3 1284 }
markrad 3:c0556ff7b8e3 1285 if (json_object_add(temp_object_copy, temp_key, temp_value_copy) == JSONFailure) {
markrad 3:c0556ff7b8e3 1286 json_value_free(return_value);
markrad 3:c0556ff7b8e3 1287 json_value_free(temp_value_copy);
markrad 3:c0556ff7b8e3 1288 return NULL;
markrad 3:c0556ff7b8e3 1289 }
markrad 3:c0556ff7b8e3 1290 }
markrad 3:c0556ff7b8e3 1291 return return_value;
markrad 3:c0556ff7b8e3 1292 case JSONBoolean:
markrad 3:c0556ff7b8e3 1293 return json_value_init_boolean(json_value_get_boolean(value));
markrad 3:c0556ff7b8e3 1294 case JSONNumber:
markrad 3:c0556ff7b8e3 1295 return json_value_init_number(json_value_get_number(value));
markrad 3:c0556ff7b8e3 1296 case JSONString:
markrad 3:c0556ff7b8e3 1297 temp_string = json_value_get_string(value);
markrad 3:c0556ff7b8e3 1298 temp_string_copy = parson_strdup(temp_string);
markrad 3:c0556ff7b8e3 1299 if (temp_string_copy == NULL) {
markrad 3:c0556ff7b8e3 1300 return NULL;
markrad 3:c0556ff7b8e3 1301 }
markrad 3:c0556ff7b8e3 1302 return_value = json_value_init_string_no_copy(temp_string_copy);
markrad 3:c0556ff7b8e3 1303 if (return_value == NULL) {
markrad 3:c0556ff7b8e3 1304 parson_free(temp_string_copy);
markrad 3:c0556ff7b8e3 1305 }
markrad 3:c0556ff7b8e3 1306 return return_value;
markrad 3:c0556ff7b8e3 1307 case JSONNull:
markrad 3:c0556ff7b8e3 1308 return json_value_init_null();
markrad 3:c0556ff7b8e3 1309 case JSONError:
markrad 3:c0556ff7b8e3 1310 return NULL;
markrad 3:c0556ff7b8e3 1311 default:
markrad 3:c0556ff7b8e3 1312 return NULL;
markrad 3:c0556ff7b8e3 1313 }
markrad 3:c0556ff7b8e3 1314 }
markrad 3:c0556ff7b8e3 1315
markrad 3:c0556ff7b8e3 1316 size_t json_serialization_size(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1317 char num_buf[1100]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
markrad 3:c0556ff7b8e3 1318 int res = json_serialize_to_buffer_r(value, NULL, 0, 0, num_buf);
markrad 3:c0556ff7b8e3 1319 return res < 0 ? 0 : (size_t)(res + 1);
markrad 3:c0556ff7b8e3 1320 }
markrad 3:c0556ff7b8e3 1321
markrad 3:c0556ff7b8e3 1322 JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes) {
markrad 3:c0556ff7b8e3 1323 int written = -1;
markrad 3:c0556ff7b8e3 1324 size_t needed_size_in_bytes = json_serialization_size(value);
markrad 3:c0556ff7b8e3 1325 if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) {
markrad 3:c0556ff7b8e3 1326 return JSONFailure;
markrad 3:c0556ff7b8e3 1327 }
markrad 3:c0556ff7b8e3 1328 written = json_serialize_to_buffer_r(value, buf, 0, 0, NULL);
markrad 3:c0556ff7b8e3 1329 if (written < 0) {
markrad 3:c0556ff7b8e3 1330 return JSONFailure;
markrad 3:c0556ff7b8e3 1331 }
markrad 3:c0556ff7b8e3 1332 return JSONSuccess;
markrad 3:c0556ff7b8e3 1333 }
markrad 3:c0556ff7b8e3 1334
markrad 3:c0556ff7b8e3 1335 JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename) {
markrad 3:c0556ff7b8e3 1336 JSON_Status return_code = JSONSuccess;
markrad 3:c0556ff7b8e3 1337 FILE *fp = NULL;
markrad 3:c0556ff7b8e3 1338 char *serialized_string = json_serialize_to_string(value);
markrad 3:c0556ff7b8e3 1339 if (serialized_string == NULL) {
markrad 3:c0556ff7b8e3 1340 return JSONFailure;
markrad 3:c0556ff7b8e3 1341 }
markrad 3:c0556ff7b8e3 1342 fp = fopen (filename, "w");
markrad 3:c0556ff7b8e3 1343 if (fp == NULL) {
markrad 3:c0556ff7b8e3 1344 json_free_serialized_string(serialized_string);
markrad 3:c0556ff7b8e3 1345 return JSONFailure;
markrad 3:c0556ff7b8e3 1346 }
markrad 3:c0556ff7b8e3 1347 if (fputs(serialized_string, fp) == EOF) {
markrad 3:c0556ff7b8e3 1348 return_code = JSONFailure;
markrad 3:c0556ff7b8e3 1349 }
markrad 3:c0556ff7b8e3 1350 if (fclose(fp) == EOF) {
markrad 3:c0556ff7b8e3 1351 return_code = JSONFailure;
markrad 3:c0556ff7b8e3 1352 }
markrad 3:c0556ff7b8e3 1353 json_free_serialized_string(serialized_string);
markrad 3:c0556ff7b8e3 1354 return return_code;
markrad 3:c0556ff7b8e3 1355 }
markrad 3:c0556ff7b8e3 1356
markrad 3:c0556ff7b8e3 1357 char * json_serialize_to_string(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1358 JSON_Status serialization_result = JSONFailure;
markrad 3:c0556ff7b8e3 1359 size_t buf_size_bytes = json_serialization_size(value);
markrad 3:c0556ff7b8e3 1360 char *buf = NULL;
markrad 3:c0556ff7b8e3 1361 if (buf_size_bytes == 0) {
markrad 3:c0556ff7b8e3 1362 return NULL;
markrad 3:c0556ff7b8e3 1363 }
markrad 3:c0556ff7b8e3 1364 buf = (char*)parson_malloc(buf_size_bytes);
markrad 3:c0556ff7b8e3 1365 if (buf == NULL) {
markrad 3:c0556ff7b8e3 1366 return NULL;
markrad 3:c0556ff7b8e3 1367 }
markrad 3:c0556ff7b8e3 1368 serialization_result = json_serialize_to_buffer(value, buf, buf_size_bytes);
markrad 3:c0556ff7b8e3 1369 if (serialization_result == JSONFailure) {
markrad 3:c0556ff7b8e3 1370 json_free_serialized_string(buf);
markrad 3:c0556ff7b8e3 1371 return NULL;
markrad 3:c0556ff7b8e3 1372 }
markrad 3:c0556ff7b8e3 1373 return buf;
markrad 3:c0556ff7b8e3 1374 }
markrad 3:c0556ff7b8e3 1375
markrad 3:c0556ff7b8e3 1376 size_t json_serialization_size_pretty(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1377 char num_buf[1100]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
markrad 3:c0556ff7b8e3 1378 int res = json_serialize_to_buffer_r(value, NULL, 0, 1, num_buf);
markrad 3:c0556ff7b8e3 1379 return res < 0 ? 0 : (size_t)(res + 1);
markrad 3:c0556ff7b8e3 1380 }
markrad 3:c0556ff7b8e3 1381
markrad 3:c0556ff7b8e3 1382 JSON_Status json_serialize_to_buffer_pretty(const JSON_Value *value, char *buf, size_t buf_size_in_bytes) {
markrad 3:c0556ff7b8e3 1383 int written = -1;
markrad 3:c0556ff7b8e3 1384 size_t needed_size_in_bytes = json_serialization_size_pretty(value);
markrad 3:c0556ff7b8e3 1385 if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) {
markrad 3:c0556ff7b8e3 1386 return JSONFailure;
markrad 3:c0556ff7b8e3 1387 }
markrad 3:c0556ff7b8e3 1388 written = json_serialize_to_buffer_r(value, buf, 0, 1, NULL);
markrad 3:c0556ff7b8e3 1389 if (written < 0) {
markrad 3:c0556ff7b8e3 1390 return JSONFailure;
markrad 3:c0556ff7b8e3 1391 }
markrad 3:c0556ff7b8e3 1392 return JSONSuccess;
markrad 3:c0556ff7b8e3 1393 }
markrad 3:c0556ff7b8e3 1394
markrad 3:c0556ff7b8e3 1395 JSON_Status json_serialize_to_file_pretty(const JSON_Value *value, const char *filename) {
markrad 3:c0556ff7b8e3 1396 JSON_Status return_code = JSONSuccess;
markrad 3:c0556ff7b8e3 1397 FILE *fp = NULL;
markrad 3:c0556ff7b8e3 1398 char *serialized_string = json_serialize_to_string_pretty(value);
markrad 3:c0556ff7b8e3 1399 if (serialized_string == NULL) {
markrad 3:c0556ff7b8e3 1400 return JSONFailure;
markrad 3:c0556ff7b8e3 1401 }
markrad 3:c0556ff7b8e3 1402 fp = fopen (filename, "w");
markrad 3:c0556ff7b8e3 1403 if (fp == NULL) {
markrad 3:c0556ff7b8e3 1404 json_free_serialized_string(serialized_string);
markrad 3:c0556ff7b8e3 1405 return JSONFailure;
markrad 3:c0556ff7b8e3 1406 }
markrad 3:c0556ff7b8e3 1407 if (fputs(serialized_string, fp) == EOF) {
markrad 3:c0556ff7b8e3 1408 return_code = JSONFailure;
markrad 3:c0556ff7b8e3 1409 }
markrad 3:c0556ff7b8e3 1410 if (fclose(fp) == EOF) {
markrad 3:c0556ff7b8e3 1411 return_code = JSONFailure;
markrad 3:c0556ff7b8e3 1412 }
markrad 3:c0556ff7b8e3 1413 json_free_serialized_string(serialized_string);
markrad 3:c0556ff7b8e3 1414 return return_code;
markrad 3:c0556ff7b8e3 1415 }
markrad 3:c0556ff7b8e3 1416
markrad 3:c0556ff7b8e3 1417 char * json_serialize_to_string_pretty(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1418 JSON_Status serialization_result = JSONFailure;
markrad 3:c0556ff7b8e3 1419 size_t buf_size_bytes = json_serialization_size_pretty(value);
markrad 3:c0556ff7b8e3 1420 char *buf = NULL;
markrad 3:c0556ff7b8e3 1421 if (buf_size_bytes == 0) {
markrad 3:c0556ff7b8e3 1422 return NULL;
markrad 3:c0556ff7b8e3 1423 }
markrad 3:c0556ff7b8e3 1424 buf = (char*)parson_malloc(buf_size_bytes);
markrad 3:c0556ff7b8e3 1425 if (buf == NULL) {
markrad 3:c0556ff7b8e3 1426 return NULL;
markrad 3:c0556ff7b8e3 1427 }
markrad 3:c0556ff7b8e3 1428 serialization_result = json_serialize_to_buffer_pretty(value, buf, buf_size_bytes);
markrad 3:c0556ff7b8e3 1429 if (serialization_result == JSONFailure) {
markrad 3:c0556ff7b8e3 1430 json_free_serialized_string(buf);
markrad 3:c0556ff7b8e3 1431 return NULL;
markrad 3:c0556ff7b8e3 1432 }
markrad 3:c0556ff7b8e3 1433 return buf;
markrad 3:c0556ff7b8e3 1434 }
markrad 3:c0556ff7b8e3 1435
markrad 3:c0556ff7b8e3 1436 void json_free_serialized_string(char *string) {
markrad 3:c0556ff7b8e3 1437 parson_free(string);
markrad 3:c0556ff7b8e3 1438 }
markrad 3:c0556ff7b8e3 1439
markrad 3:c0556ff7b8e3 1440 JSON_Status json_array_remove(JSON_Array *array, size_t ix) {
markrad 3:c0556ff7b8e3 1441 JSON_Value *temp_value = NULL;
markrad 3:c0556ff7b8e3 1442 size_t last_element_ix = 0;
markrad 3:c0556ff7b8e3 1443 if (array == NULL || ix >= json_array_get_count(array)) {
markrad 3:c0556ff7b8e3 1444 return JSONFailure;
markrad 3:c0556ff7b8e3 1445 }
markrad 3:c0556ff7b8e3 1446 last_element_ix = json_array_get_count(array) - 1;
markrad 3:c0556ff7b8e3 1447 json_value_free(json_array_get_value(array, ix));
markrad 3:c0556ff7b8e3 1448 if (ix != last_element_ix) { /* Replace value with one from the end of array */
markrad 3:c0556ff7b8e3 1449 temp_value = json_array_get_value(array, last_element_ix);
markrad 3:c0556ff7b8e3 1450 if (temp_value == NULL) {
markrad 3:c0556ff7b8e3 1451 return JSONFailure;
markrad 3:c0556ff7b8e3 1452 }
markrad 3:c0556ff7b8e3 1453 array->items[ix] = temp_value;
markrad 3:c0556ff7b8e3 1454 }
markrad 3:c0556ff7b8e3 1455 array->count -= 1;
markrad 3:c0556ff7b8e3 1456 return JSONSuccess;
markrad 3:c0556ff7b8e3 1457 }
markrad 3:c0556ff7b8e3 1458
markrad 3:c0556ff7b8e3 1459 JSON_Status json_array_replace_value(JSON_Array *array, size_t ix, JSON_Value *value) {
markrad 3:c0556ff7b8e3 1460 if (array == NULL || value == NULL || ix >= json_array_get_count(array)) {
markrad 3:c0556ff7b8e3 1461 return JSONFailure;
markrad 3:c0556ff7b8e3 1462 }
markrad 3:c0556ff7b8e3 1463 json_value_free(json_array_get_value(array, ix));
markrad 3:c0556ff7b8e3 1464 array->items[ix] = value;
markrad 3:c0556ff7b8e3 1465 return JSONSuccess;
markrad 3:c0556ff7b8e3 1466 }
markrad 3:c0556ff7b8e3 1467
markrad 3:c0556ff7b8e3 1468 JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* string) {
markrad 3:c0556ff7b8e3 1469 JSON_Value *value = json_value_init_string(string);
markrad 3:c0556ff7b8e3 1470 if (value == NULL) {
markrad 3:c0556ff7b8e3 1471 return JSONFailure;
markrad 3:c0556ff7b8e3 1472 }
markrad 3:c0556ff7b8e3 1473 if (json_array_replace_value(array, i, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1474 json_value_free(value);
markrad 3:c0556ff7b8e3 1475 return JSONFailure;
markrad 3:c0556ff7b8e3 1476 }
markrad 3:c0556ff7b8e3 1477 return JSONSuccess;
markrad 3:c0556ff7b8e3 1478 }
markrad 3:c0556ff7b8e3 1479
markrad 3:c0556ff7b8e3 1480 JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number) {
markrad 3:c0556ff7b8e3 1481 JSON_Value *value = json_value_init_number(number);
markrad 3:c0556ff7b8e3 1482 if (value == NULL) {
markrad 3:c0556ff7b8e3 1483 return JSONFailure;
markrad 3:c0556ff7b8e3 1484 }
markrad 3:c0556ff7b8e3 1485 if (json_array_replace_value(array, i, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1486 json_value_free(value);
markrad 3:c0556ff7b8e3 1487 return JSONFailure;
markrad 3:c0556ff7b8e3 1488 }
markrad 3:c0556ff7b8e3 1489 return JSONSuccess;
markrad 3:c0556ff7b8e3 1490 }
markrad 3:c0556ff7b8e3 1491
markrad 3:c0556ff7b8e3 1492 JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean) {
markrad 3:c0556ff7b8e3 1493 JSON_Value *value = json_value_init_boolean(boolean);
markrad 3:c0556ff7b8e3 1494 if (value == NULL) {
markrad 3:c0556ff7b8e3 1495 return JSONFailure;
markrad 3:c0556ff7b8e3 1496 }
markrad 3:c0556ff7b8e3 1497 if (json_array_replace_value(array, i, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1498 json_value_free(value);
markrad 3:c0556ff7b8e3 1499 return JSONFailure;
markrad 3:c0556ff7b8e3 1500 }
markrad 3:c0556ff7b8e3 1501 return JSONSuccess;
markrad 3:c0556ff7b8e3 1502 }
markrad 3:c0556ff7b8e3 1503
markrad 3:c0556ff7b8e3 1504 JSON_Status json_array_replace_null(JSON_Array *array, size_t i) {
markrad 3:c0556ff7b8e3 1505 JSON_Value *value = json_value_init_null();
markrad 3:c0556ff7b8e3 1506 if (value == NULL) {
markrad 3:c0556ff7b8e3 1507 return JSONFailure;
markrad 3:c0556ff7b8e3 1508 }
markrad 3:c0556ff7b8e3 1509 if (json_array_replace_value(array, i, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1510 json_value_free(value);
markrad 3:c0556ff7b8e3 1511 return JSONFailure;
markrad 3:c0556ff7b8e3 1512 }
markrad 3:c0556ff7b8e3 1513 return JSONSuccess;
markrad 3:c0556ff7b8e3 1514 }
markrad 3:c0556ff7b8e3 1515
markrad 3:c0556ff7b8e3 1516 JSON_Status json_array_clear(JSON_Array *array) {
markrad 3:c0556ff7b8e3 1517 size_t i = 0;
markrad 3:c0556ff7b8e3 1518 if (array == NULL) {
markrad 3:c0556ff7b8e3 1519 return JSONFailure;
markrad 3:c0556ff7b8e3 1520 }
markrad 3:c0556ff7b8e3 1521 for (i = 0; i < json_array_get_count(array); i++) {
markrad 3:c0556ff7b8e3 1522 json_value_free(json_array_get_value(array, i));
markrad 3:c0556ff7b8e3 1523 }
markrad 3:c0556ff7b8e3 1524 array->count = 0;
markrad 3:c0556ff7b8e3 1525 return JSONSuccess;
markrad 3:c0556ff7b8e3 1526 }
markrad 3:c0556ff7b8e3 1527
markrad 3:c0556ff7b8e3 1528 JSON_Status json_array_append_value(JSON_Array *array, JSON_Value *value) {
markrad 3:c0556ff7b8e3 1529 if (array == NULL || value == NULL) {
markrad 3:c0556ff7b8e3 1530 return JSONFailure;
markrad 3:c0556ff7b8e3 1531 }
markrad 3:c0556ff7b8e3 1532 return json_array_add(array, value);
markrad 3:c0556ff7b8e3 1533 }
markrad 3:c0556ff7b8e3 1534
markrad 3:c0556ff7b8e3 1535 JSON_Status json_array_append_string(JSON_Array *array, const char *string) {
markrad 3:c0556ff7b8e3 1536 JSON_Value *value = json_value_init_string(string);
markrad 3:c0556ff7b8e3 1537 if (value == NULL) {
markrad 3:c0556ff7b8e3 1538 return JSONFailure;
markrad 3:c0556ff7b8e3 1539 }
markrad 3:c0556ff7b8e3 1540 if (json_array_append_value(array, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1541 json_value_free(value);
markrad 3:c0556ff7b8e3 1542 return JSONFailure;
markrad 3:c0556ff7b8e3 1543 }
markrad 3:c0556ff7b8e3 1544 return JSONSuccess;
markrad 3:c0556ff7b8e3 1545 }
markrad 3:c0556ff7b8e3 1546
markrad 3:c0556ff7b8e3 1547 JSON_Status json_array_append_number(JSON_Array *array, double number) {
markrad 3:c0556ff7b8e3 1548 JSON_Value *value = json_value_init_number(number);
markrad 3:c0556ff7b8e3 1549 if (value == NULL) {
markrad 3:c0556ff7b8e3 1550 return JSONFailure;
markrad 3:c0556ff7b8e3 1551 }
markrad 3:c0556ff7b8e3 1552 if (json_array_append_value(array, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1553 json_value_free(value);
markrad 3:c0556ff7b8e3 1554 return JSONFailure;
markrad 3:c0556ff7b8e3 1555 }
markrad 3:c0556ff7b8e3 1556 return JSONSuccess;
markrad 3:c0556ff7b8e3 1557 }
markrad 3:c0556ff7b8e3 1558
markrad 3:c0556ff7b8e3 1559 JSON_Status json_array_append_boolean(JSON_Array *array, int boolean) {
markrad 3:c0556ff7b8e3 1560 JSON_Value *value = json_value_init_boolean(boolean);
markrad 3:c0556ff7b8e3 1561 if (value == NULL) {
markrad 3:c0556ff7b8e3 1562 return JSONFailure;
markrad 3:c0556ff7b8e3 1563 }
markrad 3:c0556ff7b8e3 1564 if (json_array_append_value(array, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1565 json_value_free(value);
markrad 3:c0556ff7b8e3 1566 return JSONFailure;
markrad 3:c0556ff7b8e3 1567 }
markrad 3:c0556ff7b8e3 1568 return JSONSuccess;
markrad 3:c0556ff7b8e3 1569 }
markrad 3:c0556ff7b8e3 1570
markrad 3:c0556ff7b8e3 1571 JSON_Status json_array_append_null(JSON_Array *array) {
markrad 3:c0556ff7b8e3 1572 JSON_Value *value = json_value_init_null();
markrad 3:c0556ff7b8e3 1573 if (value == NULL) {
markrad 3:c0556ff7b8e3 1574 return JSONFailure;
markrad 3:c0556ff7b8e3 1575 }
markrad 3:c0556ff7b8e3 1576 if (json_array_append_value(array, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1577 json_value_free(value);
markrad 3:c0556ff7b8e3 1578 return JSONFailure;
markrad 3:c0556ff7b8e3 1579 }
markrad 3:c0556ff7b8e3 1580 return JSONSuccess;
markrad 3:c0556ff7b8e3 1581 }
markrad 3:c0556ff7b8e3 1582
markrad 3:c0556ff7b8e3 1583 JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value) {
markrad 3:c0556ff7b8e3 1584 size_t i = 0;
markrad 3:c0556ff7b8e3 1585 JSON_Value *old_value;
markrad 3:c0556ff7b8e3 1586 if (object == NULL || name == NULL || value == NULL) {
markrad 3:c0556ff7b8e3 1587 return JSONFailure;
markrad 3:c0556ff7b8e3 1588 }
markrad 3:c0556ff7b8e3 1589 old_value = json_object_get_value(object, name);
markrad 3:c0556ff7b8e3 1590 if (old_value != NULL) { /* free and overwrite old value */
markrad 3:c0556ff7b8e3 1591 json_value_free(old_value);
markrad 3:c0556ff7b8e3 1592 for (i = 0; i < json_object_get_count(object); i++) {
markrad 3:c0556ff7b8e3 1593 if (strcmp(object->names[i], name) == 0) {
markrad 3:c0556ff7b8e3 1594 object->values[i] = value;
markrad 3:c0556ff7b8e3 1595 return JSONSuccess;
markrad 3:c0556ff7b8e3 1596 }
markrad 3:c0556ff7b8e3 1597 }
markrad 3:c0556ff7b8e3 1598 }
markrad 3:c0556ff7b8e3 1599 /* add new key value pair */
markrad 3:c0556ff7b8e3 1600 return json_object_add(object, name, value);
markrad 3:c0556ff7b8e3 1601 }
markrad 3:c0556ff7b8e3 1602
markrad 3:c0556ff7b8e3 1603 JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string) {
markrad 3:c0556ff7b8e3 1604 return json_object_set_value(object, name, json_value_init_string(string));
markrad 3:c0556ff7b8e3 1605 }
markrad 3:c0556ff7b8e3 1606
markrad 3:c0556ff7b8e3 1607 JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number) {
markrad 3:c0556ff7b8e3 1608 return json_object_set_value(object, name, json_value_init_number(number));
markrad 3:c0556ff7b8e3 1609 }
markrad 3:c0556ff7b8e3 1610
markrad 3:c0556ff7b8e3 1611 JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean) {
markrad 3:c0556ff7b8e3 1612 return json_object_set_value(object, name, json_value_init_boolean(boolean));
markrad 3:c0556ff7b8e3 1613 }
markrad 3:c0556ff7b8e3 1614
markrad 3:c0556ff7b8e3 1615 JSON_Status json_object_set_null(JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1616 return json_object_set_value(object, name, json_value_init_null());
markrad 3:c0556ff7b8e3 1617 }
markrad 3:c0556ff7b8e3 1618
markrad 3:c0556ff7b8e3 1619 JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value) {
markrad 3:c0556ff7b8e3 1620 const char *dot_pos = NULL;
markrad 3:c0556ff7b8e3 1621 char *current_name = NULL;
markrad 3:c0556ff7b8e3 1622 JSON_Object *temp_obj = NULL;
markrad 3:c0556ff7b8e3 1623 JSON_Value *new_value = NULL;
markrad 3:c0556ff7b8e3 1624 if (value == NULL || name == NULL || value == NULL) {
markrad 3:c0556ff7b8e3 1625 return JSONFailure;
markrad 3:c0556ff7b8e3 1626 }
markrad 3:c0556ff7b8e3 1627 dot_pos = strchr(name, '.');
markrad 3:c0556ff7b8e3 1628 if (dot_pos == NULL) {
markrad 3:c0556ff7b8e3 1629 return json_object_set_value(object, name, value);
markrad 3:c0556ff7b8e3 1630 } else {
markrad 3:c0556ff7b8e3 1631 current_name = parson_strndup(name, dot_pos - name);
markrad 3:c0556ff7b8e3 1632 temp_obj = json_object_get_object(object, current_name);
markrad 3:c0556ff7b8e3 1633 if (temp_obj == NULL) {
markrad 3:c0556ff7b8e3 1634 new_value = json_value_init_object();
markrad 3:c0556ff7b8e3 1635 if (new_value == NULL) {
markrad 3:c0556ff7b8e3 1636 parson_free(current_name);
markrad 3:c0556ff7b8e3 1637 return JSONFailure;
markrad 3:c0556ff7b8e3 1638 }
markrad 3:c0556ff7b8e3 1639 if (json_object_add(object, current_name, new_value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1640 json_value_free(new_value);
markrad 3:c0556ff7b8e3 1641 parson_free(current_name);
markrad 3:c0556ff7b8e3 1642 return JSONFailure;
markrad 3:c0556ff7b8e3 1643 }
markrad 3:c0556ff7b8e3 1644 temp_obj = json_object_get_object(object, current_name);
markrad 3:c0556ff7b8e3 1645 }
markrad 3:c0556ff7b8e3 1646 parson_free(current_name);
markrad 3:c0556ff7b8e3 1647 return json_object_dotset_value(temp_obj, dot_pos + 1, value);
markrad 3:c0556ff7b8e3 1648 }
markrad 3:c0556ff7b8e3 1649 }
markrad 3:c0556ff7b8e3 1650
markrad 3:c0556ff7b8e3 1651 JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string) {
markrad 3:c0556ff7b8e3 1652 JSON_Value *value = json_value_init_string(string);
markrad 3:c0556ff7b8e3 1653 if (value == NULL) {
markrad 3:c0556ff7b8e3 1654 return JSONFailure;
markrad 3:c0556ff7b8e3 1655 }
markrad 3:c0556ff7b8e3 1656 if (json_object_dotset_value(object, name, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1657 json_value_free(value);
markrad 3:c0556ff7b8e3 1658 return JSONFailure;
markrad 3:c0556ff7b8e3 1659 }
markrad 3:c0556ff7b8e3 1660 return JSONSuccess;
markrad 3:c0556ff7b8e3 1661 }
markrad 3:c0556ff7b8e3 1662
markrad 3:c0556ff7b8e3 1663 JSON_Status json_object_dotset_number(JSON_Object *object, const char *name, double number) {
markrad 3:c0556ff7b8e3 1664 JSON_Value *value = json_value_init_number(number);
markrad 3:c0556ff7b8e3 1665 if (value == NULL) {
markrad 3:c0556ff7b8e3 1666 return JSONFailure;
markrad 3:c0556ff7b8e3 1667 }
markrad 3:c0556ff7b8e3 1668 if (json_object_dotset_value(object, name, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1669 json_value_free(value);
markrad 3:c0556ff7b8e3 1670 return JSONFailure;
markrad 3:c0556ff7b8e3 1671 }
markrad 3:c0556ff7b8e3 1672 return JSONSuccess;
markrad 3:c0556ff7b8e3 1673 }
markrad 3:c0556ff7b8e3 1674
markrad 3:c0556ff7b8e3 1675 JSON_Status json_object_dotset_boolean(JSON_Object *object, const char *name, int boolean) {
markrad 3:c0556ff7b8e3 1676 JSON_Value *value = json_value_init_boolean(boolean);
markrad 3:c0556ff7b8e3 1677 if (value == NULL) {
markrad 3:c0556ff7b8e3 1678 return JSONFailure;
markrad 3:c0556ff7b8e3 1679 }
markrad 3:c0556ff7b8e3 1680 if (json_object_dotset_value(object, name, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1681 json_value_free(value);
markrad 3:c0556ff7b8e3 1682 return JSONFailure;
markrad 3:c0556ff7b8e3 1683 }
markrad 3:c0556ff7b8e3 1684 return JSONSuccess;
markrad 3:c0556ff7b8e3 1685 }
markrad 3:c0556ff7b8e3 1686
markrad 3:c0556ff7b8e3 1687 JSON_Status json_object_dotset_null(JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1688 JSON_Value *value = json_value_init_null();
markrad 3:c0556ff7b8e3 1689 if (value == NULL) {
markrad 3:c0556ff7b8e3 1690 return JSONFailure;
markrad 3:c0556ff7b8e3 1691 }
markrad 3:c0556ff7b8e3 1692 if (json_object_dotset_value(object, name, value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1693 json_value_free(value);
markrad 3:c0556ff7b8e3 1694 return JSONFailure;
markrad 3:c0556ff7b8e3 1695 }
markrad 3:c0556ff7b8e3 1696 return JSONSuccess;
markrad 3:c0556ff7b8e3 1697 }
markrad 3:c0556ff7b8e3 1698
markrad 3:c0556ff7b8e3 1699 JSON_Status json_object_remove(JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1700 size_t i = 0, last_item_index = 0;
markrad 3:c0556ff7b8e3 1701 if (object == NULL || json_object_get_value(object, name) == NULL) {
markrad 3:c0556ff7b8e3 1702 return JSONFailure;
markrad 3:c0556ff7b8e3 1703 }
markrad 3:c0556ff7b8e3 1704 last_item_index = json_object_get_count(object) - 1;
markrad 3:c0556ff7b8e3 1705 for (i = 0; i < json_object_get_count(object); i++) {
markrad 3:c0556ff7b8e3 1706 if (strcmp(object->names[i], name) == 0) {
markrad 3:c0556ff7b8e3 1707 parson_free(object->names[i]);
markrad 3:c0556ff7b8e3 1708 json_value_free(object->values[i]);
markrad 3:c0556ff7b8e3 1709 if (i != last_item_index) { /* Replace key value pair with one from the end */
markrad 3:c0556ff7b8e3 1710 object->names[i] = object->names[last_item_index];
markrad 3:c0556ff7b8e3 1711 object->values[i] = object->values[last_item_index];
markrad 3:c0556ff7b8e3 1712 }
markrad 3:c0556ff7b8e3 1713 object->count -= 1;
markrad 3:c0556ff7b8e3 1714 return JSONSuccess;
markrad 3:c0556ff7b8e3 1715 }
markrad 3:c0556ff7b8e3 1716 }
markrad 3:c0556ff7b8e3 1717 return JSONFailure; /* No execution path should end here */
markrad 3:c0556ff7b8e3 1718 }
markrad 3:c0556ff7b8e3 1719
markrad 3:c0556ff7b8e3 1720 JSON_Status json_object_dotremove(JSON_Object *object, const char *name) {
markrad 3:c0556ff7b8e3 1721 const char *dot_pos = strchr(name, '.');
markrad 3:c0556ff7b8e3 1722 char *current_name = NULL;
markrad 3:c0556ff7b8e3 1723 JSON_Object *temp_obj = NULL;
markrad 3:c0556ff7b8e3 1724 if (dot_pos == NULL) {
markrad 3:c0556ff7b8e3 1725 return json_object_remove(object, name);
markrad 3:c0556ff7b8e3 1726 } else {
markrad 3:c0556ff7b8e3 1727 current_name = parson_strndup(name, dot_pos - name);
markrad 3:c0556ff7b8e3 1728 temp_obj = json_object_get_object(object, current_name);
markrad 3:c0556ff7b8e3 1729 if (temp_obj == NULL) {
markrad 3:c0556ff7b8e3 1730 parson_free(current_name);
markrad 3:c0556ff7b8e3 1731 return JSONFailure;
markrad 3:c0556ff7b8e3 1732 }
markrad 3:c0556ff7b8e3 1733 parson_free(current_name);
markrad 3:c0556ff7b8e3 1734 return json_object_dotremove(temp_obj, dot_pos + 1);
markrad 3:c0556ff7b8e3 1735 }
markrad 3:c0556ff7b8e3 1736 }
markrad 3:c0556ff7b8e3 1737
markrad 3:c0556ff7b8e3 1738 JSON_Status json_object_clear(JSON_Object *object) {
markrad 3:c0556ff7b8e3 1739 size_t i = 0;
markrad 3:c0556ff7b8e3 1740 if (object == NULL) {
markrad 3:c0556ff7b8e3 1741 return JSONFailure;
markrad 3:c0556ff7b8e3 1742 }
markrad 3:c0556ff7b8e3 1743 for (i = 0; i < json_object_get_count(object); i++) {
markrad 3:c0556ff7b8e3 1744 parson_free(object->names[i]);
markrad 3:c0556ff7b8e3 1745 json_value_free(object->values[i]);
markrad 3:c0556ff7b8e3 1746 }
markrad 3:c0556ff7b8e3 1747 object->count = 0;
markrad 3:c0556ff7b8e3 1748 return JSONSuccess;
markrad 3:c0556ff7b8e3 1749 }
markrad 3:c0556ff7b8e3 1750
markrad 3:c0556ff7b8e3 1751 JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1752 JSON_Value *temp_schema_value = NULL, *temp_value = NULL;
markrad 3:c0556ff7b8e3 1753 JSON_Array *schema_array = NULL, *value_array = NULL;
markrad 3:c0556ff7b8e3 1754 JSON_Object *schema_object = NULL, *value_object = NULL;
markrad 3:c0556ff7b8e3 1755 JSON_Value_Type schema_type = JSONError, value_type = JSONError;
markrad 3:c0556ff7b8e3 1756 const char *key = NULL;
markrad 3:c0556ff7b8e3 1757 size_t i = 0, count = 0;
markrad 3:c0556ff7b8e3 1758 if (schema == NULL || value == NULL) {
markrad 3:c0556ff7b8e3 1759 return JSONFailure;
markrad 3:c0556ff7b8e3 1760 }
markrad 3:c0556ff7b8e3 1761 schema_type = json_value_get_type(schema);
markrad 3:c0556ff7b8e3 1762 value_type = json_value_get_type(value);
markrad 3:c0556ff7b8e3 1763 if (schema_type != value_type && schema_type != JSONNull) { /* null represents all values */
markrad 3:c0556ff7b8e3 1764 return JSONFailure;
markrad 3:c0556ff7b8e3 1765 }
markrad 3:c0556ff7b8e3 1766 switch (schema_type) {
markrad 3:c0556ff7b8e3 1767 case JSONArray:
markrad 3:c0556ff7b8e3 1768 schema_array = json_value_get_array(schema);
markrad 3:c0556ff7b8e3 1769 value_array = json_value_get_array(value);
markrad 3:c0556ff7b8e3 1770 count = json_array_get_count(schema_array);
markrad 3:c0556ff7b8e3 1771 if (count == 0) {
markrad 3:c0556ff7b8e3 1772 return JSONSuccess; /* Empty array allows all types */
markrad 3:c0556ff7b8e3 1773 }
markrad 3:c0556ff7b8e3 1774 /* Get first value from array, rest is ignored */
markrad 3:c0556ff7b8e3 1775 temp_schema_value = json_array_get_value(schema_array, 0);
markrad 3:c0556ff7b8e3 1776 for (i = 0; i < json_array_get_count(value_array); i++) {
markrad 3:c0556ff7b8e3 1777 temp_value = json_array_get_value(value_array, i);
markrad 3:c0556ff7b8e3 1778 if (json_validate(temp_schema_value, temp_value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1779 return JSONFailure;
markrad 3:c0556ff7b8e3 1780 }
markrad 3:c0556ff7b8e3 1781 }
markrad 3:c0556ff7b8e3 1782 return JSONSuccess;
markrad 3:c0556ff7b8e3 1783 case JSONObject:
markrad 3:c0556ff7b8e3 1784 schema_object = json_value_get_object(schema);
markrad 3:c0556ff7b8e3 1785 value_object = json_value_get_object(value);
markrad 3:c0556ff7b8e3 1786 count = json_object_get_count(schema_object);
markrad 3:c0556ff7b8e3 1787 if (count == 0) {
markrad 3:c0556ff7b8e3 1788 return JSONSuccess; /* Empty object allows all objects */
markrad 3:c0556ff7b8e3 1789 } else if (json_object_get_count(value_object) < count) {
markrad 3:c0556ff7b8e3 1790 return JSONFailure; /* Tested object mustn't have less name-value pairs than schema */
markrad 3:c0556ff7b8e3 1791 }
markrad 3:c0556ff7b8e3 1792 for (i = 0; i < count; i++) {
markrad 3:c0556ff7b8e3 1793 key = json_object_get_name(schema_object, i);
markrad 3:c0556ff7b8e3 1794 temp_schema_value = json_object_get_value(schema_object, key);
markrad 3:c0556ff7b8e3 1795 temp_value = json_object_get_value(value_object, key);
markrad 3:c0556ff7b8e3 1796 if (temp_value == NULL) {
markrad 3:c0556ff7b8e3 1797 return JSONFailure;
markrad 3:c0556ff7b8e3 1798 }
markrad 3:c0556ff7b8e3 1799 if (json_validate(temp_schema_value, temp_value) == JSONFailure) {
markrad 3:c0556ff7b8e3 1800 return JSONFailure;
markrad 3:c0556ff7b8e3 1801 }
markrad 3:c0556ff7b8e3 1802 }
markrad 3:c0556ff7b8e3 1803 return JSONSuccess;
markrad 3:c0556ff7b8e3 1804 case JSONString: case JSONNumber: case JSONBoolean: case JSONNull:
markrad 3:c0556ff7b8e3 1805 return JSONSuccess; /* equality already tested before switch */
markrad 3:c0556ff7b8e3 1806 case JSONError: default:
markrad 3:c0556ff7b8e3 1807 return JSONFailure;
markrad 3:c0556ff7b8e3 1808 }
markrad 3:c0556ff7b8e3 1809 }
markrad 3:c0556ff7b8e3 1810
markrad 3:c0556ff7b8e3 1811 JSON_Status json_value_equals(const JSON_Value *a, const JSON_Value *b) {
markrad 3:c0556ff7b8e3 1812 JSON_Object *a_object = NULL, *b_object = NULL;
markrad 3:c0556ff7b8e3 1813 JSON_Array *a_array = NULL, *b_array = NULL;
markrad 3:c0556ff7b8e3 1814 const char *a_string = NULL, *b_string = NULL;
markrad 3:c0556ff7b8e3 1815 const char *key = NULL;
markrad 3:c0556ff7b8e3 1816 size_t a_count = 0, b_count = 0, i = 0;
markrad 3:c0556ff7b8e3 1817 JSON_Value_Type a_type, b_type;
markrad 3:c0556ff7b8e3 1818 a_type = json_value_get_type(a);
markrad 3:c0556ff7b8e3 1819 b_type = json_value_get_type(b);
markrad 3:c0556ff7b8e3 1820 if (a_type != b_type) {
markrad 3:c0556ff7b8e3 1821 return 0;
markrad 3:c0556ff7b8e3 1822 }
markrad 3:c0556ff7b8e3 1823 switch (a_type) {
markrad 3:c0556ff7b8e3 1824 case JSONArray:
markrad 3:c0556ff7b8e3 1825 a_array = json_value_get_array(a);
markrad 3:c0556ff7b8e3 1826 b_array = json_value_get_array(b);
markrad 3:c0556ff7b8e3 1827 a_count = json_array_get_count(a_array);
markrad 3:c0556ff7b8e3 1828 b_count = json_array_get_count(b_array);
markrad 3:c0556ff7b8e3 1829 if (a_count != b_count) {
markrad 3:c0556ff7b8e3 1830 return 0;
markrad 3:c0556ff7b8e3 1831 }
markrad 3:c0556ff7b8e3 1832 for (i = 0; i < a_count; i++) {
markrad 3:c0556ff7b8e3 1833 if (!json_value_equals(json_array_get_value(a_array, i),
markrad 3:c0556ff7b8e3 1834 json_array_get_value(b_array, i))) {
markrad 3:c0556ff7b8e3 1835 return 0;
markrad 3:c0556ff7b8e3 1836 }
markrad 3:c0556ff7b8e3 1837 }
markrad 3:c0556ff7b8e3 1838 return 1;
markrad 3:c0556ff7b8e3 1839 case JSONObject:
markrad 3:c0556ff7b8e3 1840 a_object = json_value_get_object(a);
markrad 3:c0556ff7b8e3 1841 b_object = json_value_get_object(b);
markrad 3:c0556ff7b8e3 1842 a_count = json_object_get_count(a_object);
markrad 3:c0556ff7b8e3 1843 b_count = json_object_get_count(b_object);
markrad 3:c0556ff7b8e3 1844 if (a_count != b_count) {
markrad 3:c0556ff7b8e3 1845 return 0;
markrad 3:c0556ff7b8e3 1846 }
markrad 3:c0556ff7b8e3 1847 for (i = 0; i < a_count; i++) {
markrad 3:c0556ff7b8e3 1848 key = json_object_get_name(a_object, i);
markrad 3:c0556ff7b8e3 1849 if (!json_value_equals(json_object_get_value(a_object, key),
markrad 3:c0556ff7b8e3 1850 json_object_get_value(b_object, key))) {
markrad 3:c0556ff7b8e3 1851 return 0;
markrad 3:c0556ff7b8e3 1852 }
markrad 3:c0556ff7b8e3 1853 }
markrad 3:c0556ff7b8e3 1854 return 1;
markrad 3:c0556ff7b8e3 1855 case JSONString:
markrad 3:c0556ff7b8e3 1856 a_string = json_value_get_string(a);
markrad 3:c0556ff7b8e3 1857 b_string = json_value_get_string(b);
markrad 3:c0556ff7b8e3 1858 return strcmp(a_string, b_string) == 0;
markrad 3:c0556ff7b8e3 1859 case JSONBoolean:
markrad 3:c0556ff7b8e3 1860 return json_value_get_boolean(a) == json_value_get_boolean(b);
markrad 3:c0556ff7b8e3 1861 case JSONNumber:
markrad 3:c0556ff7b8e3 1862 return fabs(json_value_get_number(a) - json_value_get_number(b)) < 0.000001; /* EPSILON */
markrad 3:c0556ff7b8e3 1863 case JSONError:
markrad 3:c0556ff7b8e3 1864 return 1;
markrad 3:c0556ff7b8e3 1865 case JSONNull:
markrad 3:c0556ff7b8e3 1866 return 1;
markrad 3:c0556ff7b8e3 1867 default:
markrad 3:c0556ff7b8e3 1868 return 1;
markrad 3:c0556ff7b8e3 1869 }
markrad 3:c0556ff7b8e3 1870 }
markrad 3:c0556ff7b8e3 1871
markrad 3:c0556ff7b8e3 1872 JSON_Value_Type json_type(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1873 return json_value_get_type(value);
markrad 3:c0556ff7b8e3 1874 }
markrad 3:c0556ff7b8e3 1875
markrad 3:c0556ff7b8e3 1876 JSON_Object * json_object (const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1877 return json_value_get_object(value);
markrad 3:c0556ff7b8e3 1878 }
markrad 3:c0556ff7b8e3 1879
markrad 3:c0556ff7b8e3 1880 JSON_Array * json_array (const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1881 return json_value_get_array(value);
markrad 3:c0556ff7b8e3 1882 }
markrad 3:c0556ff7b8e3 1883
markrad 3:c0556ff7b8e3 1884 const char * json_string (const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1885 return json_value_get_string(value);
markrad 3:c0556ff7b8e3 1886 }
markrad 3:c0556ff7b8e3 1887
markrad 3:c0556ff7b8e3 1888 double json_number (const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1889 return json_value_get_number(value);
markrad 3:c0556ff7b8e3 1890 }
markrad 3:c0556ff7b8e3 1891
markrad 3:c0556ff7b8e3 1892 int json_boolean(const JSON_Value *value) {
markrad 3:c0556ff7b8e3 1893 return json_value_get_boolean(value);
markrad 3:c0556ff7b8e3 1894 }
markrad 3:c0556ff7b8e3 1895
markrad 3:c0556ff7b8e3 1896 void json_set_allocation_functions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun) {
markrad 3:c0556ff7b8e3 1897 parson_malloc = malloc_fun;
markrad 3:c0556ff7b8e3 1898 parson_free = free_fun;
markrad 3:c0556ff7b8e3 1899 }