Spaces:
Runtime error
Runtime error
| // 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); | |