1 // https://github.com/vivkin/gason - pulled January 10, 2016
20 #define JSON_VALUE_PAYLOAD_MASK 0x00007FFFFFFFFFFFULL
21 #define JSON_VALUE_NAN_MASK 0x7FF8000000000000ULL
22 #define JSON_VALUE_TAG_MASK 0xF
23 #define JSON_VALUE_TAG_SHIFT 47
32 JsonValue(JsonTag tag = JSON_NULL, void *payload = nullptr) {
33 assert((uintptr_t)payload <= JSON_VALUE_PAYLOAD_MASK);
34 ival = JSON_VALUE_NAN_MASK | ((uint64_t)tag << JSON_VALUE_TAG_SHIFT) | (uintptr_t)payload;
36 bool isDouble() const {
37 return (int64_t)ival <= (int64_t)JSON_VALUE_NAN_MASK;
39 JsonTag getTag() const {
40 return isDouble() ? JSON_NUMBER : JsonTag((ival >> JSON_VALUE_TAG_SHIFT) & JSON_VALUE_TAG_MASK);
42 uint64_t getPayload() const {
44 return ival & JSON_VALUE_PAYLOAD_MASK;
46 double toNumber() const {
47 assert(getTag() == JSON_NUMBER);
50 char *toString() const {
51 assert(getTag() == JSON_STRING);
52 return (char *)getPayload();
54 JsonNode *toNode() const {
55 assert(getTag() == JSON_ARRAY || getTag() == JSON_OBJECT);
56 return (JsonNode *)getPayload();
72 bool operator!=(const JsonIterator &x) const {
75 JsonNode *operator*() const {
78 JsonNode *operator->() const {
83 inline JsonIterator begin(JsonValue o) {
84 return JsonIterator{o.toNode()};
86 inline JsonIterator end(JsonValue) {
87 return JsonIterator{nullptr};
90 #define JSON_ERRNO_MAP(XX) \
92 XX(BAD_NUMBER, "bad number") \
93 XX(BAD_STRING, "bad string") \
94 XX(BAD_IDENTIFIER, "bad identifier") \
95 XX(STACK_OVERFLOW, "stack overflow") \
96 XX(STACK_UNDERFLOW, "stack underflow") \
97 XX(MISMATCH_BRACKET, "mismatch bracket") \
98 XX(UNEXPECTED_CHARACTER, "unexpected character") \
99 XX(UNQUOTED_KEY, "unquoted key") \
100 XX(BREAKING_BAD, "breaking bad") \
101 XX(ALLOCATION_FAILURE, "allocation failure")
104 #define XX(no, str) JSON_##no,
109 const char *jsonStrError(int err);
111 class JsonAllocator {
118 JsonAllocator() = default;
119 JsonAllocator(const JsonAllocator &) = delete;
120 JsonAllocator &operator=(const JsonAllocator &) = delete;
121 JsonAllocator(JsonAllocator &&x) : head(x.head) {
124 JsonAllocator &operator=(JsonAllocator &&x) {
132 void *allocate(size_t size);
136 int jsonParse(char *str, char **endptr, JsonValue *value, JsonAllocator &allocator);