json.c (4493B)
1 #include <errno.h> 2 #include <stdio.h> 3 #include <string.h> 4 #include "json.h" 5 6 enum mode { 7 MODE_NONE = 0, 8 MODE_OBJECT_FIRST, 9 MODE_OBJECT, 10 MODE_OBJECT_VALUE, 11 MODE_ARRAY_FIRST, 12 MODE_ARRAY, 13 }; 14 15 static enum mode _json_mode(struct json *j) 16 { 17 if (j->depth == 0) 18 return MODE_NONE; 19 return j->modes[j->depth - 1]; 20 } 21 22 static int _json_kw(struct json *j, const char *value, size_t vl) 23 { 24 int r; 25 26 switch (_json_mode(j)) { 27 case MODE_ARRAY: 28 if ((r = buf_char(&j->b, ','))) 29 return r; 30 break; 31 32 case MODE_ARRAY_FIRST: 33 j->modes[j->depth - 1] = MODE_ARRAY; 34 break; 35 36 case MODE_OBJECT_VALUE: 37 j->modes[j->depth - 1] = MODE_OBJECT; 38 break; 39 40 default: 41 return EINVAL; 42 } 43 44 if (j->b.data + vl >= j->b.end) 45 return ENOMEM; 46 memcpy(j->b.data, value, vl); 47 j->b.data += vl; 48 49 return 0; 50 } 51 52 int _json_string(struct json *j, const char *value) 53 { 54 int r; 55 56 switch (_json_mode(j)) { 57 case MODE_ARRAY: 58 case MODE_OBJECT: 59 if ((r = buf_char(&j->b, ','))) 60 return r; 61 break; 62 63 case MODE_ARRAY_FIRST: 64 j->modes[j->depth - 1] = MODE_ARRAY; 65 break; 66 67 case MODE_OBJECT_FIRST: 68 case MODE_OBJECT_VALUE: 69 break; 70 71 default: 72 return EINVAL; 73 } 74 75 if ((r = buf_char(&j->b, '"'))) 76 return r; 77 for (; *value; value++) { 78 char c; 79 switch (*value) { 80 case '\r': 81 c = 'r'; 82 break; 83 case '\n': 84 c = 'n'; 85 break; 86 case '\b': 87 c = 'b'; 88 break; 89 case '\f': 90 c = 'f'; 91 break; 92 93 case '\\': 94 case '"': 95 c = *value; 96 break; 97 98 default: 99 if ((r = buf_char(&j->b, *value))) 100 return ENOMEM; 101 continue; 102 } 103 if ((r = buf_char(&j->b, '\\')) || 104 (r = buf_char(&j->b, c))) 105 return ENOMEM; 106 } 107 108 return buf_char(&j->b, '"'); 109 } 110 111 int json_init(struct json *j, struct buf *b) 112 { 113 j->b = *b; 114 j->buffer = b->data; 115 j->depth = 0; 116 117 return 0; 118 } 119 120 int json_obj_open(struct json *j) 121 { 122 int r; 123 124 switch (_json_mode(j)) { 125 case MODE_OBJECT_FIRST: 126 case MODE_OBJECT: 127 return EINVAL; 128 129 case MODE_ARRAY: 130 if ((r = buf_char(&j->b, ','))) 131 return r; 132 break; 133 134 default: 135 break; 136 } 137 138 if (&j->modes[j->depth] == 1[&j->modes]) 139 return ENOMEM; 140 j->modes[j->depth++] = MODE_OBJECT_FIRST; 141 return buf_char(&j->b, '{'); 142 } 143 144 int json_obj_close(struct json *j) 145 { 146 switch (_json_mode(j)) { 147 case MODE_OBJECT_FIRST: 148 case MODE_OBJECT: 149 break; 150 151 default: 152 return EINVAL; 153 } 154 155 j->depth--; 156 if (_json_mode(j) == MODE_OBJECT_VALUE) 157 j->modes[j->depth - 1] = MODE_OBJECT; 158 return buf_char(&j->b, '}'); 159 } 160 161 int json_string(struct json *j, const char *value) 162 { 163 int r; 164 165 switch (_json_mode(j)) { 166 case MODE_OBJECT_FIRST: 167 case MODE_OBJECT: 168 return EINVAL; 169 170 default: 171 break; 172 } 173 174 if ((r = _json_string(j, value))) 175 return r; 176 if (_json_mode(j) == MODE_OBJECT_VALUE) 177 j->modes[j->depth - 1] = MODE_OBJECT; 178 return 0; 179 } 180 181 int json_obj_key(struct json *j, const char *key) 182 { 183 int r; 184 185 switch (_json_mode(j)) { 186 case MODE_OBJECT: 187 case MODE_OBJECT_FIRST: 188 break; 189 190 default: 191 return EINVAL; 192 } 193 194 if ((r = _json_string(j, key))) 195 return r; 196 j->modes[j->depth - 1] = MODE_OBJECT_VALUE; 197 return buf_char(&j->b, ':'); 198 } 199 200 int json_arr_open(struct json *j) { 201 int r; 202 203 switch (_json_mode(j)) { 204 case MODE_OBJECT_FIRST: 205 case MODE_OBJECT: 206 return EINVAL; 207 208 case MODE_ARRAY: 209 if ((r = buf_char(&j->b, ','))) 210 return r; 211 break; 212 213 default: 214 break; 215 } 216 217 if (&j->modes[j->depth] == 1[&j->modes]) 218 return ENOMEM; 219 j->modes[j->depth++] = MODE_ARRAY_FIRST; 220 return buf_char(&j->b, '['); 221 } 222 223 int json_arr_close(struct json *j) 224 { 225 switch (_json_mode(j)) { 226 case MODE_ARRAY_FIRST: 227 case MODE_ARRAY: 228 break; 229 230 default: 231 return EINVAL; 232 } 233 234 j->depth--; 235 if (_json_mode(j) == MODE_OBJECT_VALUE) 236 j->modes[j->depth - 1] = MODE_OBJECT; 237 return buf_char(&j->b, ']'); 238 } 239 240 int json_bool(struct json *j, int v) 241 { 242 if (v) 243 return _json_kw(j, "true", sizeof("true") - 1); 244 return _json_kw(j, "false", sizeof("false") - 1); 245 } 246 247 int json_null(struct json *j) 248 { 249 return _json_kw(j, "null", sizeof("null") - 1); 250 } 251 252 int json_int(struct json *j, intmax_t val) 253 { 254 int r; 255 256 switch (_json_mode(j)) { 257 case MODE_ARRAY: 258 if ((r = buf_char(&j->b, ','))) 259 return r; 260 break; 261 262 case MODE_ARRAY_FIRST: 263 j->modes[j->depth - 1] = MODE_ARRAY; 264 break; 265 266 case MODE_OBJECT_VALUE: 267 j->modes[j->depth - 1] = MODE_OBJECT; 268 break; 269 270 default: 271 return EINVAL; 272 } 273 274 r = snprintf(j->b.data, j->b.end - j->b.data, "%jd", val); 275 if (j->b.data + r >= j->b.end - 1) 276 return ENOMEM; 277 j->b.data += r; 278 279 return 0; 280 } 281 282 int json_fini(struct json *j, struct buf *b) 283 { 284 if (j->depth != 0) 285 return EINVAL; 286 b->data = j->buffer; 287 b->end = j->b.data; 288 289 return 0; 290 } 291