summaryrefslogtreecommitdiff
path: root/handler.h
blob: e940d91bf5aad0a5f3b87003611541ae742230a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#ifdef DEBUG
#include <stdio.h>
#endif
#include <string.h>
#include <json.h>
#include "pikul.h"

extern json_tokener *tokener;
void recurse(struct json_object *, const char *[], struct json_object **);

enum type { SERVICES, ORDER };

inline void handle(enum type type, const char *contents, size_t num_bytes, const char *status_trail[],
		const char *trail[], const char *attributes[], void *data)
{
#ifdef DEBUG
	((char *)contents)[num_bytes] = '\0';
	fprintf(stderr, "%s\n", contents);
#endif
	json_object *response = json_tokener_parse_ex(tokener, contents, num_bytes);
	enum json_tokener_error error = json_tokener_get_error(tokener);
	if (!response) {
		if (error == json_tokener_continue)
			return;
		else {
			json_tokener_reset(tokener);
			return;
		}
	} else if (!json_object_is_type(response, json_type_object) || error != json_tokener_success)
		return;
	struct json_object *status = NULL;
	recurse(response, status_trail, &status);
	if (json_object_get_int(status) != 200)
		return;
	switch (type) {
		case SERVICES:
			;
			struct json_object *array = NULL;
			recurse(response, trail, &array);
			size_t length = json_object_array_length(array);
			struct pikul_services **services  = (struct pikul_services **)data;
			*services = malloc(sizeof(struct pikul_services)
					+ sizeof(struct pikul_service *[length]));
			(*services)->length = length;
			enum { CODE, NAME, ETD, COST };
			for (size_t i = 0; i < length; i++) {
				(*services)->list[i] = malloc(sizeof(struct pikul_service));
				struct pikul_service *service = (*services)->list[i];
				json_object *object = json_object_array_get_idx(array, i);
				struct json_object_iterator iterator = json_object_iter_begin(object);
				struct json_object_iterator iterator_end = json_object_iter_end(object);
				while (!json_object_iter_equal(&iterator, &iterator_end)) {
					const char *name = json_object_iter_peek_name(&iterator);
					json_object *value = json_object_iter_peek_value(&iterator);
					if (!strcmp(name, attributes[COST]))
						service->cost = json_object_get_double(value);
					else {
						int len = json_object_get_string_len(value);
						if (len) {
							char *string = malloc(len + 1);
							strcpy(string, json_object_get_string(value));
							if (!strcmp(name, attributes[CODE]))
								service->code = string;
							else if (!strcmp(name, attributes[NAME]))
								service->name = string;
							else if (!strcmp(name, attributes[ETD]))
								service->etd = string;
						}
					}
					json_object_iter_next(&iterator);
				}
			}
			break;
		case ORDER:
			;
			struct json_object *string = NULL;
			recurse(response, trail, &string);
			char **waybill = (char **)data;
			*waybill = malloc(json_object_get_string_len(string) + 1);
			strcpy(*waybill, json_object_get_string(string));
			break;
		default:
			break;
	}
}