| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- #include "JSONNode.h"
- #define IMPLEMENT_CTOR(type)\
- JSONNode::JSONNode(const json_string & name_t, type value_t) json_nothrow : internal(internalJSONNode::newInternal()){\
- internal -> Set(value_t);\
- internal -> setname(name_t);\
- LIBJSON_CTOR;\
- }
- IMPLEMENT_FOR_ALL_TYPES(IMPLEMENT_CTOR)
- #ifndef JSON_LIBRARY
- JSONNode::JSONNode(const json_string & name_t, const json_char * value_t) json_nothrow : internal(internalJSONNode::newInternal()){
- internal -> Set(json_string(value_t));
- internal -> setname(name_t);
- LIBJSON_CTOR;
- }
- #endif
- #if (defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY))
- #include "JSONWorker.h"
- JSONNode JSONNode::stringType(const json_string & str){
- JSONNode res;
- res.set_name(json_global(EMPTY_JSON_STRING));
- #ifdef JSON_LESS_MEMORY
- res = JSONWorker::FixString(str, res.internal, false);
- #else
- res = JSONWorker::FixString(str, res.internal -> _string_encoded);
- #endif
- return res;
- }
- void JSONNode::set_name_(const json_string & newname) json_nothrow {
- #ifdef JSON_LESS_MEMORY
- json_string _newname = JSONWorker::FixString(newname, internal, true);
- #else
- json_string _newname = JSONWorker::FixString(newname, internal -> _name_encoded);
- #endif
- set_name(_newname);
- }
- #endif
- #ifdef JSON_CASTABLE
- JSONNode JSONNode::as_node(void) const json_nothrow {
- JSON_CHECK_INTERNAL();
- if (type() == JSON_NODE){
- return *this;
- } else if (type() == JSON_ARRAY){
- JSONNode res(duplicate());
- res.internal -> _type = JSON_NODE;
- return res;
- }
- #ifdef JSON_MUTEX_CALLBACKS
- if (internal -> mylock != 0){
- JSONNode res(JSON_NODE);
- res.set_mutex(internal -> mylock);
- return res;
- }
- #endif
- return JSONNode(JSON_NODE);
- }
- JSONNode JSONNode::as_array(void) const json_nothrow {
- JSON_CHECK_INTERNAL();
- if (type() == JSON_ARRAY){
- return *this;
- } else if (type() == JSON_NODE){
- JSONNode res(duplicate());
- res.internal -> _type = JSON_ARRAY;
- json_foreach(res.internal -> CHILDREN, runner){
- (*runner) -> clear_name();
- }
- return res;
- }
- #ifdef JSON_MUTEX_CALLBACKS
- if (internal -> mylock != 0){
- JSONNode res(JSON_ARRAY);
- res.set_mutex(internal -> mylock);
- return res;
- }
- #endif
- return JSONNode(JSON_ARRAY);
- }
- void JSONNode::cast(char newtype) json_nothrow {
- JSON_CHECK_INTERNAL();
- if (newtype == type()) return;
- switch(newtype){
- case JSON_NULL:
- nullify();
- return;
- case JSON_STRING:
- *this = as_string();
- return;
- case JSON_NUMBER:
- *this = as_float();
- return;
- case JSON_BOOL:
- *this = as_bool();
- return;
- case JSON_ARRAY:
- *this = as_array();
- return;
- case JSON_NODE:
- *this = as_node();
- return;
- }
- JSON_FAIL(JSON_TEXT("cast to unknown type"));
- }
- #endif
- //different just to supress the warning
- #ifdef JSON_REF_COUNT
- void JSONNode::merge(JSONNode & other) json_nothrow {
- #else
- void JSONNode::merge(JSONNode &) json_nothrow {
- #endif
- JSON_CHECK_INTERNAL();
- #ifdef JSON_REF_COUNT
- if (internal == other.internal) return;
- JSON_ASSERT(*this == other, JSON_TEXT("merging two nodes that aren't equal"));
- if (internal -> refcount < other.internal -> refcount){
- *this = other;
- } else {
- other = *this;
- }
- #endif
- }
- #ifdef JSON_REF_COUNT
- void JSONNode::merge(JSONNode * other) json_nothrow {
- JSON_CHECK_INTERNAL();
- if (internal == other -> internal) return;
- *other = *this;
- }
- //different just to supress the warning
- void JSONNode::merge(unsigned int num, ...) json_nothrow {
- #else
- void JSONNode::merge(unsigned int, ...) json_nothrow {
- #endif
- JSON_CHECK_INTERNAL();
- #ifdef JSON_REF_COUNT
- va_list args;
- va_start(args, num);
- for(unsigned int i = 0; i < num; ++i){
- merge(va_arg(args, JSONNode*));
- }
- va_end(args);
- #endif
- }
- JSONNode JSONNode::duplicate(void) const json_nothrow {
- JSON_CHECK_INTERNAL();
- JSONNode mycopy(*this);
- #ifdef JSON_REF_COUNT
- JSON_ASSERT(internal == mycopy.internal, JSON_TEXT("copy ctor failed to ref count correctly"));
- mycopy.makeUniqueInternal();
- #endif
- JSON_ASSERT(internal != mycopy.internal, JSON_TEXT("makeUniqueInternal failed"));
- return mycopy;
- }
- JSONNode & JSONNode::at(json_index_t pos) json_throws(std::out_of_range) {
- JSON_CHECK_INTERNAL();
- if (json_unlikely(pos >= internal -> size())){
- JSON_FAIL(JSON_TEXT("at() out of bounds"));
- json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
- }
- return (*this)[pos];
- }
- const JSONNode & JSONNode::at(json_index_t pos) const json_throws(std::out_of_range) {
- JSON_CHECK_INTERNAL();
- if (json_unlikely(pos >= internal -> size())){
- JSON_FAIL(JSON_TEXT("at() const out of bounds"));
- json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
- }
- return (*this)[pos];
- }
- JSONNode & JSONNode::operator[](json_index_t pos) json_nothrow {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(pos < internal -> size(), JSON_TEXT("[] out of bounds"));
- makeUniqueInternal();
- return *(internal -> at(pos));
- }
- const JSONNode & JSONNode::operator[](json_index_t pos) const json_nothrow {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(pos < internal -> size(), JSON_TEXT("[] const out of bounds"));
- return *(internal -> at(pos));
- }
- JSONNode & JSONNode::at(const json_string & name_t) json_throws(std::out_of_range) {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at"));
- makeUniqueInternal();
- if (JSONNode ** res = internal -> at(name_t)){
- return *(*res);
- }
- JSON_FAIL(json_string(JSON_TEXT("at could not find child by name: ")) + name_t);
- json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
- }
- const JSONNode & JSONNode::at(const json_string & name_t) const json_throws(std::out_of_range) {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at"));
- if (JSONNode ** res = internal -> at(name_t)){
- return *(*res);
- }
- JSON_FAIL(json_string(JSON_TEXT("at const could not find child by name: ")) + name_t);
- json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
- }
- #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
- JSONNode & JSONNode::at_nocase(const json_string & name_t) json_throws(std::out_of_range) {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at_nocase"));
- makeUniqueInternal();
- if (JSONNode ** res = internal -> at_nocase(name_t)){
- return *(*res);
- }
- JSON_FAIL(json_string(JSON_TEXT("at_nocase could not find child by name: ")) + name_t);
- json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
- }
- const JSONNode & JSONNode::at_nocase(const json_string & name_t) const json_throws(std::out_of_range) {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("at_nocase"));
- if (JSONNode ** res = internal -> at_nocase(name_t)){
- return *(*res);
- }
- JSON_FAIL(json_string(JSON_TEXT("at_nocase const could not find child by name: ")) + name_t);
- json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
- }
- #endif
- #ifndef JSON_LIBRARY
- struct auto_delete {
- public:
- auto_delete(JSONNode * node) json_nothrow : mynode(node){};
- ~auto_delete(void) json_nothrow { JSONNode::deleteJSONNode(mynode); };
- JSONNode * mynode;
- private:
- auto_delete(const auto_delete &);
- auto_delete & operator = (const auto_delete &);
- };
- #endif
- JSONNode JSON_PTR_LIB JSONNode::pop_back(json_index_t pos) json_throws(std::out_of_range) {
- JSON_CHECK_INTERNAL();
- if (json_unlikely(pos >= internal -> size())){
- JSON_FAIL(JSON_TEXT("pop_back out of bounds"));
- json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
- }
- makeUniqueInternal();
- #ifdef JSON_LIBRARY
- return internal -> pop_back(pos);
- #else
- auto_delete temp(internal -> pop_back(pos));
- return *temp.mynode;
- #endif
- }
- JSONNode JSON_PTR_LIB JSONNode::pop_back(const json_string & name_t) json_throws(std::out_of_range) {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("pop_back"));
- #ifdef JSON_LIBRARY
- return internal -> pop_back(name_t);
- #else
- if (JSONNode * res = internal -> pop_back(name_t)){
- auto_delete temp(res);
- return *(temp.mynode);
- }
- JSON_FAIL(json_string(JSON_TEXT("pop_back const could not find child by name: ")) + name_t);
- json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
- #endif
- }
- #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
- JSONNode JSON_PTR_LIB JSONNode::pop_back_nocase(const json_string & name_t) json_throws(std::out_of_range) {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, json_global(ERROR_NON_ITERATABLE) + JSON_TEXT("pop_back_no_case"));
- #ifdef JSON_LIBRARY
- return internal -> pop_back_nocase(name_t);
- #else
- if (JSONNode * res = internal -> pop_back_nocase(name_t)){
- auto_delete temp(res);
- return *(temp.mynode);
- }
- JSON_FAIL(json_string(JSON_TEXT("pop_back_nocase could not find child by name: ")) + name_t);
- json_throw(std::out_of_range(json_global(EMPTY_STD_STRING)));
- #endif
- }
- #endif
-
- #ifdef JSON_MEMORY_POOL
- #include "JSONMemoryPool.h"
- memory_pool<NODEPOOL> json_node_mempool;
- #endif
-
- void JSONNode::deleteJSONNode(JSONNode * ptr) json_nothrow {
- #ifdef JSON_MEMORY_POOL
- ptr -> ~JSONNode();
- json_node_mempool.deallocate((void*)ptr);
- #elif defined(JSON_MEMORY_CALLBACKS)
- ptr -> ~JSONNode();
- libjson_free<JSONNode>(ptr);
- #else
- delete ptr;
- #endif
- }
-
- inline JSONNode * _newJSONNode(const JSONNode & orig) {
- #ifdef JSON_MEMORY_POOL
- return new((JSONNode*)json_node_mempool.allocate()) JSONNode(orig);
- #elif defined(JSON_MEMORY_CALLBACKS)
- return new(json_malloc<JSONNode>(1)) JSONNode(orig);
- #else
- return new JSONNode(orig);
- #endif
- }
-
- JSONNode * JSONNode::newJSONNode(const JSONNode & orig JSON_MUTEX_COPY_DECL) {
- #ifdef JSON_MUTEX_CALLBACKS
- if (parentMutex != 0){
- JSONNode * temp = _newJSONNode(orig);
- temp -> set_mutex(parentMutex);
- return temp;
- }
- #endif
- return _newJSONNode(orig);
- }
-
- JSONNode * JSONNode::newJSONNode(internalJSONNode * internal_t) {
- #ifdef JSON_MEMORY_POOL
- return new((JSONNode*)json_node_mempool.allocate()) JSONNode(internal_t);
- #elif defined(JSON_MEMORY_CALLBACKS)
- return new(json_malloc<JSONNode>(1)) JSONNode(internal_t);
- #else
- return new JSONNode(internal_t);
- #endif
- }
-
- JSONNode * JSONNode::newJSONNode_Shallow(const JSONNode & orig) {
- #ifdef JSON_MEMORY_POOL
- return new((JSONNode*)json_node_mempool.allocate()) JSONNode(true, const_cast<JSONNode &>(orig));
- #elif defined(JSON_MEMORY_CALLBACKS)
- return new(json_malloc<JSONNode>(1)) JSONNode(true, const_cast<JSONNode &>(orig));
- #else
- return new JSONNode(true, const_cast<JSONNode &>(orig));
- #endif
- }
-
|