#include "jsonobj.h" #include "inner_storage.h" #include #include #include "utf8.h" #define constr_begin try { #define constr_end } catch (const std::bad_alloc& ba) { nullify(*this); throw; } namespace json { misuse::misuse(const char *string): runtime_error(string) {} JSON::JSON(json_t type): type(type) { if (type == integer) { value = new Integer(); } else if (type == string) { value = new std::string(); } else if (type == array) { value = new ArrayData(); } else if (type == dictionary) { value = new DictionaryData(); } } JSON::JSON(bool V) { type = V ? true_symbol : false_symbol; } JSON::JSON(int64_t val): type(integer) { value = new Integer(val); } JSON::JSON(const Integer &V): type(integer) { value = new Integer(V); } JSON::JSON(const char *str): type(string) { value = new std::string(str); } JSON::JSON(const std::string &V): type(string) { value = new std::string(V); } JSON::JSON(const std::vector &V): type(array) { ArrayData* dataPtr = new ArrayData(); value = dataPtr; // Now the object is in correct state, with allocated memory constr_begin /* std::vector invokes one of those really serious JSON non-recursive copy operators */ dataPtr->data = V; constr_end } JSON::JSON(const std::map &V): type(dictionary) { DictionaryData* dataPtr = new DictionaryData(); value = dataPtr; constr_begin /* std::map will invoke non-recursive JSON copy */ dataPtr->data = V; constr_end } JSON::JSON(const JSON &other) { constr_begin /* This is a very serious function. It must not be implemented recursively */ copy_json(*this, other); constr_end } JSON& JSON::operator=(const JSON &other) { /* This is another one of those super serious functions that must not be recursive no matter what */ if (is_subtree_of(*this, other)) throw misuse("Copying json tree to it's subtree"); if (is_subtree_of(other, *this)) throw misuse("Copying json-subtree to json object"); nullify(*this); copy_json(*this, other); return *this; } JSON::~JSON() { /* This is by far the most serious function I have ever written */ nullify(*this); } JSON_reference JSON::r() noexcept { return {*this, {}}; } JSON_reference_const JSON::r() const noexcept { return {*this, false}; } }