1 #include <stdlib.h> 2 #include <string.h> 3 #include <stdio.h> 4 #include <errno.h> 5 #include <stdarg.h> 6 #include "json.h" 7 #include "log.h" 8 9 struct json_object *json_create_object(void) 10 { 11 struct json_object *obj = malloc(sizeof(struct json_object)); 12 if (obj) 13 memset(obj, 0, sizeof(struct json_object)); 14 return obj; 15 } 16 17 struct json_array *json_create_array(void) 18 { 19 struct json_array *array = malloc(sizeof(struct json_array)); 20 if (array) 21 memset(array, 0, sizeof(struct json_array)); 22 return array; 23 } 24 25 static struct json_pair *json_create_pair(const char *name, struct json_value *value) 26 { 27 struct json_pair *pair = malloc(sizeof(struct json_pair)); 28 if (pair) { 29 pair->name = strdup(name); 30 pair->value = value; 31 32 value->parent_type = JSON_PARENT_TYPE_PAIR; 33 value->parent_pair = pair; 34 } 35 return pair; 36 } 37 38 static struct json_value *json_create_value_int(long long number) 39 { 40 struct json_value *value = malloc(sizeof(struct json_value)); 41 42 if (value) { 43 value->type = JSON_TYPE_INTEGER; 44 value->integer_number = number; 45 } 46 return value; 47 } 48 49 static struct json_value *json_create_value_float(float number) 50 { 51 struct json_value *value = malloc(sizeof(struct json_value)); 52 53 if (value) { 54 value->type = JSON_TYPE_FLOAT; 55 value->float_number = number; 56 } 57 return value; 58 } 59 60 static char *strdup_escape(const char *str) 61 { 62 const char *input = str; 63 char *p, *ret; 64 int escapes; 65 66 if (!strlen(str)) 67 return NULL; 68 69 escapes = 0; 70 while ((input = strpbrk(input, "\\\"")) != NULL) { 71 escapes++; 72 input++; 73 } 74 75 p = ret = malloc(strlen(str) + escapes + 1); 76 while (*str) { 77 if (*str == '\\' || *str == '\"') 78 *p++ = '\\'; 79 *p++ = *str++; 80 } 81 *p = '\0'; 82 83 return ret; 84 } 85 86 /* 87 * Valid JSON strings must escape '"' and '/' with a preceding '/' 88 */ 89 static struct json_value *json_create_value_string(const char *str) 90 { 91 struct json_value *value = malloc(sizeof(struct json_value)); 92 93 if (value) { 94 value->type = JSON_TYPE_STRING; 95 value->string = strdup_escape(str); 96 if (!value->string) { 97 free(value); 98 value = NULL; 99 } 100 } 101 return value; 102 } 103 104 static struct json_value *json_create_value_object(struct json_object *obj) 105 { 106 struct json_value *value = malloc(sizeof(struct json_value)); 107 108 if (value) { 109 value->type = JSON_TYPE_OBJECT; 110 value->object = obj; 111 obj->parent = value; 112 } 113 return value; 114 } 115 116 static struct json_value *json_create_value_array(struct json_array *array) 117 { 118 struct json_value *value = malloc(sizeof(struct json_value)); 119 120 if (value) { 121 value->type = JSON_TYPE_ARRAY; 122 value->array = array; 123 array->parent = value; 124 } 125 return value; 126 } 127 128 static void json_free_pair(struct json_pair *pair); 129 static void json_free_value(struct json_value *value); 130 131 void json_free_object(struct json_object *obj) 132 { 133 int i; 134 135 for (i = 0; i < obj->pair_cnt; i++) 136 json_free_pair(obj->pairs[i]); 137 free(obj->pairs); 138 free(obj); 139 } 140 141 static void json_free_array(struct json_array *array) 142 { 143 int i; 144 145 for (i = 0; i < array->value_cnt; i++) 146 json_free_value(array->values[i]); 147 free(array->values); 148 free(array); 149 } 150 151 static void json_free_pair(struct json_pair *pair) 152 { 153 json_free_value(pair->value); 154 free(pair->name); 155 free(pair); 156 } 157 158 static void json_free_value(struct json_value *value) 159 { 160 switch (value->type) { 161 case JSON_TYPE_STRING: 162 free(value->string); 163 break; 164 case JSON_TYPE_OBJECT: 165 json_free_object(value->object); 166 break; 167 case JSON_TYPE_ARRAY: 168 json_free_array(value->array); 169 break; 170 } 171 free(value); 172 } 173 174 static int json_array_add_value(struct json_array *array, struct json_value *value) 175 { 176 struct json_value **values = realloc(array->values, 177 sizeof(struct json_value *) * (array->value_cnt + 1)); 178 179 if (!values) 180 return ENOMEM; 181 values[array->value_cnt] = value; 182 array->value_cnt++; 183 array->values = values; 184 185 value->parent_type = JSON_PARENT_TYPE_ARRAY; 186 value->parent_array = array; 187 return 0; 188 } 189 190 static int json_object_add_pair(struct json_object *obj, struct json_pair *pair) 191 { 192 struct json_pair **pairs = realloc(obj->pairs, 193 sizeof(struct json_pair *) * (obj->pair_cnt + 1)); 194 if (!pairs) 195 return ENOMEM; 196 pairs[obj->pair_cnt] = pair; 197 obj->pair_cnt++; 198 obj->pairs = pairs; 199 200 pair->parent = obj; 201 return 0; 202 } 203 204 int json_object_add_value_type(struct json_object *obj, const char *name, int type, ...) 205 { 206 struct json_value *value; 207 struct json_pair *pair; 208 va_list args; 209 int ret; 210 211 va_start(args, type); 212 if (type == JSON_TYPE_STRING) 213 value = json_create_value_string(va_arg(args, char *)); 214 else if (type == JSON_TYPE_INTEGER) 215 value = json_create_value_int(va_arg(args, long long)); 216 else if (type == JSON_TYPE_FLOAT) 217 value = json_create_value_float(va_arg(args, double)); 218 else if (type == JSON_TYPE_OBJECT) 219 value = json_create_value_object(va_arg(args, struct json_object *)); 220 else 221 value = json_create_value_array(va_arg(args, struct json_array *)); 222 va_end(args); 223 224 if (!value) 225 return ENOMEM; 226 227 pair = json_create_pair(name, value); 228 if (!pair) { 229 json_free_value(value); 230 return ENOMEM; 231 } 232 ret = json_object_add_pair(obj, pair); 233 if (ret) { 234 json_free_pair(pair); 235 return ENOMEM; 236 } 237 return 0; 238 } 239 240 static void json_print_array(struct json_array *array); 241 int json_array_add_value_type(struct json_array *array, int type, ...) 242 { 243 struct json_value *value; 244 va_list args; 245 int ret; 246 247 va_start(args, type); 248 if (type == JSON_TYPE_STRING) 249 value = json_create_value_string(va_arg(args, char *)); 250 else if (type == JSON_TYPE_INTEGER) 251 value = json_create_value_int(va_arg(args, long long)); 252 else if (type == JSON_TYPE_FLOAT) 253 value = json_create_value_float(va_arg(args, double)); 254 else if (type == JSON_TYPE_OBJECT) 255 value = json_create_value_object(va_arg(args, struct json_object *)); 256 else 257 value = json_create_value_array(va_arg(args, struct json_array *)); 258 va_end(args); 259 260 if (!value) 261 return ENOMEM; 262 263 ret = json_array_add_value(array, value); 264 if (ret) { 265 json_free_value(value); 266 return ENOMEM; 267 } 268 return 0; 269 } 270 271 static int json_value_level(struct json_value *value); 272 static int json_pair_level(struct json_pair *pair); 273 static int json_array_level(struct json_array *array); 274 static int json_object_level(struct json_object *object) 275 { 276 if (object->parent == NULL) 277 return 0; 278 return json_value_level(object->parent); 279 } 280 281 static int json_pair_level(struct json_pair *pair) 282 { 283 return json_object_level(pair->parent) + 1; 284 } 285 286 static int json_array_level(struct json_array *array) 287 { 288 return json_value_level(array->parent); 289 } 290 291 static int json_value_level(struct json_value *value) 292 { 293 if (value->parent_type == JSON_PARENT_TYPE_PAIR) 294 return json_pair_level(value->parent_pair); 295 else 296 return json_array_level(value->parent_array) + 1; 297 } 298 299 static void json_print_level(int level) 300 { 301 while (level-- > 0) 302 log_info(" "); 303 } 304 305 static void json_print_pair(struct json_pair *pair); 306 static void json_print_array(struct json_array *array); 307 static void json_print_value(struct json_value *value); 308 void json_print_object(struct json_object *obj) 309 { 310 int i; 311 312 log_info("{\n"); 313 for (i = 0; i < obj->pair_cnt; i++) { 314 if (i > 0) 315 log_info(",\n"); 316 json_print_pair(obj->pairs[i]); 317 } 318 log_info("\n"); 319 json_print_level(json_object_level(obj)); 320 log_info("}"); 321 } 322 323 static void json_print_pair(struct json_pair *pair) 324 { 325 json_print_level(json_pair_level(pair)); 326 log_info("\"%s\" : ", pair->name); 327 json_print_value(pair->value); 328 } 329 330 static void json_print_array(struct json_array *array) 331 { 332 int i; 333 334 log_info("[\n"); 335 for (i = 0; i < array->value_cnt; i++) { 336 if (i > 0) 337 log_info(",\n"); 338 json_print_level(json_value_level(array->values[i])); 339 json_print_value(array->values[i]); 340 } 341 log_info("\n"); 342 json_print_level(json_array_level(array)); 343 log_info("]"); 344 } 345 346 static void json_print_value(struct json_value *value) 347 { 348 switch (value->type) { 349 case JSON_TYPE_STRING: 350 log_info("\"%s\"", value->string); 351 break; 352 case JSON_TYPE_INTEGER: 353 log_info("%lld", value->integer_number); 354 break; 355 case JSON_TYPE_FLOAT: 356 log_info("%.2f", value->float_number); 357 break; 358 case JSON_TYPE_OBJECT: 359 json_print_object(value->object); 360 break; 361 case JSON_TYPE_ARRAY: 362 json_print_array(value->array); 363 break; 364 } 365 } 366