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