Spaces:
Sleeping
Sleeping
// https://github.com/vivkin/gason - pulled January 10, 2016 | |
enum JsonTag { | |
JSON_NUMBER = 0, | |
JSON_STRING, | |
JSON_ARRAY, | |
JSON_OBJECT, | |
JSON_TRUE, | |
JSON_FALSE, | |
JSON_NULL = 0xF | |
}; | |
struct JsonNode; | |
union JsonValue { | |
uint64_t ival; | |
double fval; | |
JsonValue(double x) | |
: fval(x) { | |
} | |
JsonValue(JsonTag tag = JSON_NULL, void *payload = nullptr) { | |
assert((uintptr_t)payload <= JSON_VALUE_PAYLOAD_MASK); | |
ival = JSON_VALUE_NAN_MASK | ((uint64_t)tag << JSON_VALUE_TAG_SHIFT) | (uintptr_t)payload; | |
} | |
bool isDouble() const { | |
return (int64_t)ival <= (int64_t)JSON_VALUE_NAN_MASK; | |
} | |
JsonTag getTag() const { | |
return isDouble() ? JSON_NUMBER : JsonTag((ival >> JSON_VALUE_TAG_SHIFT) & JSON_VALUE_TAG_MASK); | |
} | |
uint64_t getPayload() const { | |
assert(!isDouble()); | |
return ival & JSON_VALUE_PAYLOAD_MASK; | |
} | |
double toNumber() const { | |
assert(getTag() == JSON_NUMBER); | |
return fval; | |
} | |
char *toString() const { | |
assert(getTag() == JSON_STRING); | |
return (char *)getPayload(); | |
} | |
JsonNode *toNode() const { | |
assert(getTag() == JSON_ARRAY || getTag() == JSON_OBJECT); | |
return (JsonNode *)getPayload(); | |
} | |
}; | |
struct JsonNode { | |
JsonValue value; | |
JsonNode *next; | |
char *key; | |
}; | |
struct JsonIterator { | |
JsonNode *p; | |
void operator++() { | |
p = p->next; | |
} | |
bool operator!=(const JsonIterator &x) const { | |
return p != x.p; | |
} | |
JsonNode *operator*() const { | |
return p; | |
} | |
JsonNode *operator->() const { | |
return p; | |
} | |
}; | |
inline JsonIterator begin(JsonValue o) { | |
return JsonIterator{o.toNode()}; | |
} | |
inline JsonIterator end(JsonValue) { | |
return JsonIterator{nullptr}; | |
} | |
enum JsonErrno { | |
JSON_ERRNO_MAP(XX) | |
}; | |
const char *jsonStrError(int err); | |
class JsonAllocator { | |
struct Zone { | |
Zone *next; | |
size_t used; | |
} *head = nullptr; | |
public: | |
JsonAllocator() = default; | |
JsonAllocator(const JsonAllocator &) = delete; | |
JsonAllocator &operator=(const JsonAllocator &) = delete; | |
JsonAllocator(JsonAllocator &&x) : head(x.head) { | |
x.head = nullptr; | |
} | |
JsonAllocator &operator=(JsonAllocator &&x) { | |
head = x.head; | |
x.head = nullptr; | |
return *this; | |
} | |
~JsonAllocator() { | |
deallocate(); | |
} | |
void *allocate(size_t size); | |
void deallocate(); | |
}; | |
int jsonParse(char *str, char **endptr, JsonValue *value, JsonAllocator &allocator); | |