GCC Code Coverage Report


Directory: src/
File: src/json.c
Date: 2023-08-28 07:33:56
Exec Total Coverage
Lines: 91 126 72.2%
Branches: 19 58 32.8%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
3 * This file is part of the "cimple" project.
4 * For details, see https://github.com/egor-tensin/cimple.
5 * Distributed under the MIT License.
6 */
7
8 #include "json.h"
9 #include "log.h"
10 #include "net.h"
11
12 #include <json-c/json_object.h>
13 #include <json-c/json_tokener.h>
14
15 #include <errno.h>
16 #include <stdint.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 45954 const char *json_to_string(struct json_object *obj)
21 {
22 45954 const char *result = json_object_to_json_string(obj);
23
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45954 times.
45954 if (!result) {
24 json_errno("json_object_to_json_string");
25 return NULL;
26 }
27 45954 return result;
28 }
29
30 45954 struct json_object *json_from_string(const char *src)
31 {
32 enum json_tokener_error error;
33
34 45954 struct json_object *result = json_tokener_parse_verbose(src, &error);
35
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45954 times.
45954 if (!result) {
36 json_errno("json_tokener_parse_verbose");
37 log_err("JSON: parsing failed: %s\n", json_tokener_error_desc(error));
38 return NULL;
39 }
40
41 45954 return result;
42 }
43
44 27540 int json_clone(const struct json_object *obj, const char *key, struct json_object **_value)
45 {
46 27540 int ret = 0;
47
48 27540 struct json_object *old_value = NULL;
49 27540 ret = json_get(obj, key, &old_value);
50
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27540 times.
27540 if (ret < 0)
51 return ret;
52
53 27540 struct json_object *new_value = NULL;
54 27540 ret = json_object_deep_copy(old_value, &new_value, NULL);
55
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27540 times.
27540 if (ret < 0)
56 return ret;
57
58 27540 *_value = new_value;
59 27540 return ret;
60 }
61
62 45954 int json_send(struct json_object *obj, int fd)
63 {
64 45954 int ret = 0;
65
66 45954 const char *str = json_to_string(obj);
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45954 times.
45954 if (!str)
68 return -1;
69
70 45954 struct buf *buf = NULL;
71 45954 ret = buf_create_from_string(&buf, str);
72
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45954 times.
45954 if (ret < 0)
73 return ret;
74
75 45954 ret = net_send_buf(fd, buf);
76 45954 buf_destroy(buf);
77 45954 return ret;
78 }
79
80 45954 struct json_object *json_recv(int fd)
81 {
82 45954 struct json_object *result = NULL;
83 45954 int ret = 0;
84
85 45954 struct buf *buf = NULL;
86 45954 ret = net_recv_buf(fd, &buf);
87
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45954 times.
45954 if (ret < 0)
88 return NULL;
89
90 45954 result = json_from_string((const char *)buf_get_data(buf));
91
1/2
✓ Branch 0 taken 45954 times.
✗ Branch 1 not taken.
45954 if (!result)
92 goto destroy_buf;
93
94 45954 destroy_buf:
95 45954 free((void *)buf_get_data(buf));
96 45954 buf_destroy(buf);
97
98 45954 return result;
99 }
100
101 606204 int json_has(const struct json_object *obj, const char *key)
102 {
103 606204 return json_object_object_get_ex(obj, key, NULL);
104 }
105
106 385722 int json_get(const struct json_object *obj, const char *key, struct json_object **value)
107 {
108
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 385722 times.
385722 if (!json_has(obj, key)) {
109 log_err("JSON: key is missing: %s\n", key);
110 return -1;
111 }
112
113 385722 return json_object_object_get_ex(obj, key, value);
114 }
115
116 165402 int json_get_string(const struct json_object *obj, const char *key, const char **_value)
117 {
118 165402 struct json_object *value = NULL;
119
120 165402 int ret = json_get(obj, key, &value);
121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 165402 times.
165402 if (ret < 0)
122 return ret;
123
124
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 165402 times.
165402 if (!json_object_is_type(value, json_type_string)) {
125 log_err("JSON: key is not a string: %s\n", key);
126 return -1;
127 }
128
129 165402 *_value = json_object_get_string(value);
130 165402 return 0;
131 }
132
133 27540 int json_get_int(const struct json_object *obj, const char *key, int64_t *_value)
134 {
135 27540 struct json_object *value = NULL;
136
137 27540 int ret = json_get(obj, key, &value);
138
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27540 times.
27540 if (ret < 0)
139 return ret;
140
141
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 27540 times.
27540 if (!json_object_is_type(value, json_type_int)) {
142 log_err("JSON: key is not an integer: %s\n", key);
143 return -1;
144 }
145
146 27540 errno = 0;
147 27540 int64_t tmp = json_object_get_int64(value);
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27540 times.
27540 if (errno) {
149 log_err("JSON: failed to parse integer from key: %s\n", key);
150 return -1;
151 }
152
153 27540 *_value = tmp;
154 27540 return 0;
155 }
156
157 284688 static int json_set_internal(struct json_object *obj, const char *key, struct json_object *value,
158 unsigned flags)
159 {
160 284688 int ret = 0;
161
162 284688 ret = json_object_object_add_ex(obj, key, value, flags);
163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 284688 times.
284688 if (ret < 0) {
164 json_errno("json_object_object_add_ex");
165 return ret;
166 }
167
168 284688 return 0;
169 }
170
171 156168 static int json_set_string_internal(struct json_object *obj, const char *key, const char *_value,
172 unsigned flags)
173 {
174 156168 struct json_object *value = json_object_new_string(_value);
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156168 times.
156168 if (!value) {
176 json_errno("json_object_new_string");
177 return -1;
178 }
179
180 156168 int ret = json_set_internal(obj, key, value, flags);
181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156168 times.
156168 if (ret < 0)
182 goto free_value;
183
184 156168 return ret;
185
186 free_value:
187 json_object_put(value);
188
189 return ret;
190 }
191
192 45900 static int json_set_int_internal(struct json_object *obj, const char *key, int64_t _value,
193 unsigned flags)
194 {
195 45900 struct json_object *value = json_object_new_int64(_value);
196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45900 times.
45900 if (!value) {
197 json_errno("json_object_new_int");
198 return -1;
199 }
200
201 45900 int ret = json_set_internal(obj, key, value, flags);
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45900 times.
45900 if (ret < 0)
203 goto free_value;
204
205 45900 return ret;
206
207 free_value:
208 json_object_put(value);
209
210 return ret;
211 }
212
213 55080 int json_set(struct json_object *obj, const char *key, struct json_object *value)
214 {
215 55080 return json_set_internal(obj, key, value, 0);
216 }
217
218 45900 int json_set_string(struct json_object *obj, const char *key, const char *value)
219 {
220 45900 return json_set_string_internal(obj, key, value, 0);
221 }
222
223 27540 int json_set_int(struct json_object *obj, const char *key, int64_t value)
224 {
225 27540 return json_set_int_internal(obj, key, value, 0);
226 }
227
228 #ifndef JSON_C_OBJECT_ADD_CONSTANT_KEY
229 #define JSON_C_OBJECT_ADD_CONSTANT_KEY JSON_C_OBJECT_KEY_IS_CONSTANT
230 #endif
231 static const unsigned json_const_key_flags = JSON_C_OBJECT_ADD_CONSTANT_KEY;
232
233 27540 int json_set_const_key(struct json_object *obj, const char *key, struct json_object *value)
234 {
235 27540 return json_set_internal(obj, key, value, json_const_key_flags);
236 }
237
238 110268 int json_set_string_const_key(struct json_object *obj, const char *key, const char *value)
239 {
240 110268 return json_set_string_internal(obj, key, value, json_const_key_flags);
241 }
242
243 18360 int json_set_int_const_key(struct json_object *obj, const char *key, int64_t value)
244 {
245 18360 return json_set_int_internal(obj, key, value, json_const_key_flags);
246 }
247