]>
Commit | Line | Data |
---|---|---|
cd0b6c53 LP |
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | ||
3 | #pragma once | |
4 | ||
5 | #include "json.h" | |
6 | ||
7 | /* This header should include all prototypes only the JSON parser itself and | |
8 | * its tests need access to. Normal code consuming the JSON parser should not | |
9 | * interface with this. */ | |
10 | ||
11 | typedef union JsonValue { | |
12 | /* Encodes a simple value. On x86-64 this structure is 16 bytes wide (as long double is 128bit). */ | |
13 | bool boolean; | |
14 | long double real; | |
15 | intmax_t integer; | |
16 | uintmax_t unsig; | |
17 | } JsonValue; | |
18 | ||
19 | /* Let's protect us against accidental structure size changes on our most relevant arch */ | |
20 | #ifdef __x86_64__ | |
21 | assert_cc(sizeof(JsonValue) == 16U); | |
22 | #endif | |
23 | ||
24 | #define JSON_VALUE_NULL ((JsonValue) {}) | |
25 | ||
26 | /* We use fake JsonVariant objects for some special values, in order to avoid memory allocations for them. Note that | |
27 | * effectively this means that there are multiple ways to encode the same objects: via these magic values or as | |
28 | * properly allocated JsonVariant. We convert between both on-the-fly as necessary. */ | |
29 | #define JSON_VARIANT_MAGIC_TRUE ((JsonVariant*) 1) | |
30 | #define JSON_VARIANT_MAGIC_FALSE ((JsonVariant*) 2) | |
31 | #define JSON_VARIANT_MAGIC_NULL ((JsonVariant*) 3) | |
32 | #define JSON_VARIANT_MAGIC_ZERO_INTEGER ((JsonVariant*) 4) | |
33 | #define JSON_VARIANT_MAGIC_ZERO_UNSIGNED ((JsonVariant*) 5) | |
34 | #define JSON_VARIANT_MAGIC_ZERO_REAL ((JsonVariant*) 6) | |
35 | #define JSON_VARIANT_MAGIC_EMPTY_STRING ((JsonVariant*) 7) | |
36 | #define JSON_VARIANT_MAGIC_EMPTY_ARRAY ((JsonVariant*) 8) | |
37 | #define JSON_VARIANT_MAGIC_EMPTY_OBJECT ((JsonVariant*) 9) | |
4fcb507a | 38 | #define _JSON_VARIANT_MAGIC_MAX ((JsonVariant*) 10) |
cd0b6c53 | 39 | |
085f3d64 LP |
40 | /* This is only safe as long as we don't define more than 4K magic pointers, i.e. the page size of the simplest |
41 | * architectures we support. That's because we rely on the fact that malloc() will never allocate from the first memory | |
42 | * page, as it is a faulting page for catching NULL pointer dereferences. */ | |
43 | assert_cc((uintptr_t) _JSON_VARIANT_MAGIC_MAX < 4096U); | |
44 | ||
cd0b6c53 LP |
45 | enum { /* JSON tokens */ |
46 | JSON_TOKEN_END, | |
47 | JSON_TOKEN_COLON, | |
48 | JSON_TOKEN_COMMA, | |
49 | JSON_TOKEN_OBJECT_OPEN, | |
50 | JSON_TOKEN_OBJECT_CLOSE, | |
51 | JSON_TOKEN_ARRAY_OPEN, | |
52 | JSON_TOKEN_ARRAY_CLOSE, | |
53 | JSON_TOKEN_STRING, | |
54 | JSON_TOKEN_REAL, | |
55 | JSON_TOKEN_INTEGER, | |
56 | JSON_TOKEN_UNSIGNED, | |
57 | JSON_TOKEN_BOOLEAN, | |
58 | JSON_TOKEN_NULL, | |
59 | _JSON_TOKEN_MAX, | |
60 | _JSON_TOKEN_INVALID = -1, | |
61 | }; | |
62 | ||
63 | int json_tokenize(const char **p, char **ret_string, JsonValue *ret_value, unsigned *ret_line, unsigned *ret_column, void **state, unsigned *line, unsigned *column); |