1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
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. This structure is generally 8 bytes wide (as double is 64bit). */
13         bool boolean;
14         double real;
15         int64_t integer;
16         uint64_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) == 8U);
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 enum
30 {
31  _JSON_VARIANT_MAGIC_TRUE = 1,
32 #define JSON_VARIANT_MAGIC_TRUE ((JsonVariant*) _JSON_VARIANT_MAGIC_TRUE)
33  _JSON_VARIANT_MAGIC_FALSE,
34 #define JSON_VARIANT_MAGIC_FALSE ((JsonVariant*) _JSON_VARIANT_MAGIC_FALSE)
35  _JSON_VARIANT_MAGIC_NULL,
36 #define JSON_VARIANT_MAGIC_NULL ((JsonVariant*) _JSON_VARIANT_MAGIC_NULL)
37  _JSON_VARIANT_MAGIC_ZERO_INTEGER,
38 #define JSON_VARIANT_MAGIC_ZERO_INTEGER ((JsonVariant*) _JSON_VARIANT_MAGIC_ZERO_INTEGER)
39  _JSON_VARIANT_MAGIC_ZERO_UNSIGNED,
40 #define JSON_VARIANT_MAGIC_ZERO_UNSIGNED ((JsonVariant*) _JSON_VARIANT_MAGIC_ZERO_UNSIGNED)
41  _JSON_VARIANT_MAGIC_ZERO_REAL,
42 #define JSON_VARIANT_MAGIC_ZERO_REAL ((JsonVariant*) _JSON_VARIANT_MAGIC_ZERO_REAL)
43  _JSON_VARIANT_MAGIC_EMPTY_STRING,
44 #define JSON_VARIANT_MAGIC_EMPTY_STRING ((JsonVariant*) _JSON_VARIANT_MAGIC_EMPTY_STRING)
45  _JSON_VARIANT_MAGIC_EMPTY_ARRAY,
46 #define JSON_VARIANT_MAGIC_EMPTY_ARRAY ((JsonVariant*) _JSON_VARIANT_MAGIC_EMPTY_ARRAY)
47  _JSON_VARIANT_MAGIC_EMPTY_OBJECT,
48 #define JSON_VARIANT_MAGIC_EMPTY_OBJECT ((JsonVariant*) _JSON_VARIANT_MAGIC_EMPTY_OBJECT)
49  __JSON_VARIANT_MAGIC_MAX
50 #define _JSON_VARIANT_MAGIC_MAX ((JsonVariant*) __JSON_VARIANT_MAGIC_MAX)
51 };
52 
53 /* This is only safe as long as we don't define more than 4K magic pointers, i.e. the page size of the simplest
54  * architectures we support. That's because we rely on the fact that malloc() will never allocate from the first memory
55  * page, as it is a faulting page for catching NULL pointer dereferences. */
56 assert_cc((unsigned) __JSON_VARIANT_MAGIC_MAX < 4096U);
57 
58 enum { /* JSON tokens */
59         JSON_TOKEN_END,
60         JSON_TOKEN_COLON,
61         JSON_TOKEN_COMMA,
62         JSON_TOKEN_OBJECT_OPEN,
63         JSON_TOKEN_OBJECT_CLOSE,
64         JSON_TOKEN_ARRAY_OPEN,
65         JSON_TOKEN_ARRAY_CLOSE,
66         JSON_TOKEN_STRING,
67         JSON_TOKEN_REAL,
68         JSON_TOKEN_INTEGER,
69         JSON_TOKEN_UNSIGNED,
70         JSON_TOKEN_BOOLEAN,
71         JSON_TOKEN_NULL,
72         _JSON_TOKEN_MAX,
73         _JSON_TOKEN_INVALID = -EINVAL,
74 };
75 
76 int json_tokenize(const char **p, char **ret_string, JsonValue *ret_value, unsigned *ret_line, unsigned *ret_column, void **state, unsigned *line, unsigned *column);
77