Home | History | Annotate | Download | only in fio
      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