CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/ext/gason/gason.h
Views: 1401
1
#pragma once
2
3
#include <stdint.h>
4
#include <stddef.h>
5
#include <assert.h>
6
7
enum JsonTag {
8
JSON_NUMBER = 0,
9
JSON_STRING,
10
JSON_ARRAY,
11
JSON_OBJECT,
12
JSON_TRUE,
13
JSON_FALSE,
14
JSON_NULL = 0xF
15
};
16
17
struct JsonNode;
18
19
struct JsonValue {
20
union {
21
uint64_t ival_;
22
double fval_;
23
};
24
uint8_t tag_ = JSON_NULL;
25
26
JsonValue(double x)
27
: fval_(x), tag_(JSON_NUMBER) {
28
}
29
JsonValue(JsonTag tag = JSON_NULL, void *payload = nullptr)
30
: ival_((uintptr_t)payload), tag_(tag) {
31
}
32
bool isDouble() const {
33
return tag_ == JSON_NUMBER;
34
}
35
JsonTag getTag() const {
36
return JsonTag(tag_);
37
}
38
uint64_t getPayload() const {
39
assert(!isDouble());
40
return ival_;
41
}
42
double toNumber() const {
43
assert(getTag() == JSON_NUMBER);
44
return fval_;
45
}
46
char *toString() const {
47
assert(getTag() == JSON_STRING);
48
return (char *)getPayload();
49
}
50
JsonNode *toNode() const {
51
assert(getTag() == JSON_ARRAY || getTag() == JSON_OBJECT);
52
return (JsonNode *)getPayload();
53
}
54
};
55
56
struct JsonNode {
57
JsonValue value;
58
JsonNode *next;
59
char *key;
60
};
61
62
struct JsonIterator {
63
JsonNode *p;
64
65
void operator++() {
66
p = p->next;
67
}
68
bool operator!=(const JsonIterator &x) const {
69
return p != x.p;
70
}
71
JsonNode *operator*() const {
72
return p;
73
}
74
JsonNode *operator->() const {
75
return p;
76
}
77
};
78
79
inline JsonIterator begin(JsonValue o) {
80
return JsonIterator{o.toNode()};
81
}
82
inline JsonIterator end(JsonValue) {
83
return JsonIterator{nullptr};
84
}
85
86
#define JSON_ERRNO_MAP(XX) \
87
XX(OK, "ok") \
88
XX(BAD_NUMBER, "bad number") \
89
XX(BAD_STRING, "bad string") \
90
XX(BAD_IDENTIFIER, "bad identifier") \
91
XX(STACK_OVERFLOW, "stack overflow") \
92
XX(STACK_UNDERFLOW, "stack underflow") \
93
XX(MISMATCH_BRACKET, "mismatch bracket") \
94
XX(UNEXPECTED_CHARACTER, "unexpected character") \
95
XX(UNQUOTED_KEY, "unquoted key") \
96
XX(BREAKING_BAD, "breaking bad") \
97
XX(ALLOCATION_FAILURE, "allocation failure")
98
99
enum JsonErrno {
100
#define XX(no, str) JSON_##no,
101
JSON_ERRNO_MAP(XX)
102
#undef XX
103
};
104
105
const char *jsonStrError(int err);
106
107
class JsonAllocator {
108
struct Zone {
109
Zone *next;
110
size_t used;
111
} *head;
112
113
public:
114
JsonAllocator() : head(nullptr) {};
115
JsonAllocator(const JsonAllocator &) = delete;
116
JsonAllocator &operator=(const JsonAllocator &) = delete;
117
JsonAllocator(JsonAllocator &&x) noexcept : head(x.head) {
118
x.head = nullptr;
119
}
120
JsonAllocator &operator=(JsonAllocator &&x) noexcept {
121
head = x.head;
122
x.head = nullptr;
123
return *this;
124
}
125
~JsonAllocator() {
126
deallocate();
127
}
128
void *allocate(size_t size);
129
void deallocate();
130
};
131
132
int jsonParse(char *str, char **endptr, JsonValue *value, JsonAllocator &allocator);
133
134