| JSONNode.h | | JSONNode.h | |
|
| #ifndef libJSON_NODE_H | | #ifndef JSONNODE_H | |
| #define libJSON_NODE_H | | #define JSONNODE_H | |
| | | | |
|
| #include <string> | | #include "JSONDefs.h" //for string type | |
| #include "JSON_Strings.h" | | #include "internalJSONNode.h" //internal structure for json value | |
| #include "JSONChildren.h" | | #include <stdexcept> | |
| | | #include <cstdarg> //for the ... parameter | |
| | | | |
|
| #define foreach(iterator, container)\ | | #ifdef JSON_BINARY | |
| for (typeof(container.begin()) iterator = container.begin(), iterator## | | #include "JSON_Base64.h" | |
| _end = container.end();\ | | #endif | |
| iterator != iterator##_end;\ | | | |
| ++iterator) | | | |
| | | | |
|
| using namespace std; | | #ifndef JSON_REF_COUNT | |
| | | #define makeUniqueInternal() (void)0 | |
| | | #endif | |
| | | | |
|
| union value_union_t { | | #define JSON_CHECK_INTERNAL() JSON_ASSERT(internal, JSON_TEXT("no internal" | |
| bool _bool; | | )) | |
| #ifdef JSON_LESS_MEMORY | | | |
| float _number; | | #ifdef JSON_MUTEX_CALLBACKS | |
| size_t lastreal: 20; | | #define JSON_MUTEX_COPY_DECL ,void * parentMutex | |
| | | #define JSON_MUTEX_COPY_DECL2 ,void * parentMutex = 0 | |
| | | #else | |
| | | #define JSON_MUTEX_COPY_DECL | |
| | | #define JSON_MUTEX_COPY_DECL2 | |
| | | #endif | |
| | | | |
| | | #ifdef JSON_LIBRARY | |
| | | #define JSON_PTR_LIB * | |
| | | #define JSON_NEW(x) JSONNode::newJSONNode_Shallow(x) | |
| | | #define DECLARE_FOR_ALL_TYPES(foo)\ | |
| | | foo(long);\ | |
| | | foo(json_number);\ | |
| | | foo(bool);\ | |
| | | foo(const json_string &); | |
| | | | |
| | | #define DECLARE_FOR_ALL_TYPES_CONST(foo)\ | |
| | | foo(long) const;\ | |
| | | foo(json_number) const;\ | |
| | | foo(bool) const;\ | |
| | | foo(const json_string &) const;\ | |
| | | foo(const JSONNode &) const; | |
| | | | |
| | | #define IMPLEMENT_FOR_ALL_NUMBERS(foo)\ | |
| | | foo(long)\ | |
| | | foo(json_number) | |
| | | | |
| | | #else | |
| | | #define JSON_PTR_LIB | |
| | | #define JSON_NEW(x) x | |
| | | #define DECLARE_FOR_ALL_TYPES(foo)\ | |
| | | foo(char); foo(unsigned char);\ | |
| | | foo(short); foo(unsigned short);\ | |
| | | foo(int); foo(unsigned int);\ | |
| | | foo(long); foo(unsigned long);\ | |
| | | foo(float); foo(double);\ | |
| | | foo(bool);\ | |
| | | foo(const json_string &);\ | |
| | | foo(const json_char *); | |
| | | | |
| | | #define DECLARE_FOR_ALL_TYPES_CONST(foo)\ | |
| | | foo(char) const; foo(unsigned char) const;\ | |
| | | foo(short) const; foo(unsigned short) const;\ | |
| | | foo(int) const; foo(unsigned int) const;\ | |
| | | foo(long) const; foo(unsigned long) const;\ | |
| | | foo(float) const; foo(double) const;\ | |
| | | foo(bool) const;\ | |
| | | foo(const json_string &) const;\ | |
| | | foo(const JSONNode &) const;\ | |
| | | foo(const json_char *) const; | |
| | | | |
| | | #define IMPLEMENT_FOR_ALL_NUMBERS(foo)\ | |
| | | foo(char) foo(unsigned char)\ | |
| | | foo(short) foo(unsigned short)\ | |
| | | foo(int) foo(unsigned int)\ | |
| | | foo(long) foo(unsigned long)\ | |
| | | foo(float) foo(double) | |
| | | | |
| | | #endif | |
| | | | |
| | | #define IMPLEMENT_FOR_ALL_TYPES(foo)\ | |
| | | IMPLEMENT_FOR_ALL_NUMBERS(foo)\ | |
| | | foo(const json_string &)\ | |
| | | foo(bool) | |
| | | | |
| | | /* | |
| | | This class is mostly just a wrapper class around internalJSONNode, this | |
| | | class keeps | |
| | | the reference count and handles copy on write and such. This class is | |
| | | also responsible | |
| | | for argument checking and throwing exceptions if needed. | |
| | | */ | |
| | | | |
| | | class JSONNode { | |
| | | public: | |
| | | explicit JSONNode(char mytype = JSON_NODE); | |
| | | #define DECLARE_CTOR(type) JSONNode(const json_string & name_t, type va | |
| | | lue_t) | |
| | | DECLARE_FOR_ALL_TYPES(DECLARE_CTOR) | |
| | | | |
| | | JSONNode(const JSONNode & orig); | |
| | | ~JSONNode(void); | |
| | | | |
| | | json_index_t size(void) const; | |
| | | bool empty(void) const; | |
| | | void clear(void); | |
| | | unsigned char type(void) const; | |
| | | | |
| | | json_string name(void) const; | |
| | | void set_name(const json_string & newname); | |
| | | #ifdef JSON_COMMENTS | |
| | | void set_comment(const json_string & comment); | |
| | | json_string get_comment(void) const; | |
| | | #endif | |
| | | #ifndef JSON_PREPARSE | |
| | | void preparse(void); | |
| | | #endif | |
| | | #ifdef JSON_VALIDATE | |
| | | #ifndef JSON_SAFE | |
| | | #error JSON_VALIDATE also requires JSON_SAFE | |
| | | #endif | |
| | | bool validate(void); | |
| | | #endif | |
| | | | |
| | | json_string as_string(void) const; | |
| | | long as_int(void) const; | |
| | | json_number as_float(void) const; | |
| | | bool as_bool(void) const; | |
| | | JSONNode as_node(void) const; | |
| | | JSONNode as_array(void) const; | |
| | | | |
| | | #ifdef JSON_BINARY | |
| | | std::string as_binary(void) const; | |
| | | void set_binary(const unsigned char * bin, json_index_t bytes); | |
| | | #endif | |
| | | | |
| | | JSONNode & at(json_index_t pos); | |
| | | const JSONNode & at(json_index_t pos) const; | |
| | | JSONNode & operator[](json_index_t pos); | |
| | | const JSONNode & operator[](json_index_t pos) const; | |
| | | | |
| | | JSONNode & at(const json_string & name_t); | |
| | | const JSONNode & at(const json_string & name_t) const; | |
| | | #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | |
| | | JSONNode & at_nocase(const json_string & name_t); | |
| | | const JSONNode & at_nocase(const json_string & name_t) const; | |
| | | #endif | |
| | | JSONNode & operator[](const json_string & name_t); | |
| | | const JSONNode & operator[](const json_string & name_t) const; | |
| | | | |
| | | #ifdef JSON_LIBRARY | |
| | | void push_back(JSONNode * node); | |
| #else | | #else | |
|
| double _number; | | void push_back(const JSONNode & node); | |
| size_t lastreal; //This is used to determine the last real entry i | | #endif | |
| n the Children, because it's possible to have comments at the end, we don't | | void reserve(json_index_t size); | |
| want commas before them | | JSONNode JSON_PTR_LIB pop_back(json_index_t pos); | |
| | | JSONNode JSON_PTR_LIB pop_back(const json_string & name_t); | |
| | | #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | |
| | | JSONNode JSON_PTR_LIB pop_back_nocase(const json_string & name_t) | |
| | | ; | |
| #endif | | #endif | |
|
| }; | | | |
| | | | |
|
| class JSONNode { | | DECLARE_FOR_ALL_TYPES(JSONNode & operator =) | |
| public: | | JSONNode & operator = (const JSONNode &); | |
| JSONNode(const json_string & name_t, const json_string & value_t) | | | |
| ; | | | |
| JSONNode(void){}; //Used ONLY for duplicating | | | |
| JSONNode(JSONNode * parent); | | | |
| ~JSONNode(void); | | | |
| void SetMyValue(const json_string & value_t); | | | |
| void CloneTo(JSONNode * node); | | | |
| json_string Write(unsigned int indent, bool & commaafter); //pas | | | |
| s 0xFFFFFFFF to do no formatting | | | |
| void Add(JSONNode * child); | | | |
| | | | |
|
| #ifdef JSON_LESS_MEMORY | | DECLARE_FOR_ALL_TYPES_CONST(bool operator ==) | |
| char type : 4; | | DECLARE_FOR_ALL_TYPES_CONST(bool operator !=) | |
| #else | | | |
| char type; //an enumerated type that tells the engine how to t | | | |
| reat it | | | |
| #endif | | | |
| | | | |
|
| #ifndef JSON_PREPARSE | | void nullify(void); | |
| void Fetch(void); | | void swap(JSONNode & other); | |
| bool Fetched; //if the value has been parsed yet or not | | void merge(JSONNode & other); | |
| #endif | | void merge(unsigned int num, ...); | |
| | | JSONNode duplicate(void) const; | |
| | | void cast(char newtype); | |
| | | | |
|
| #ifndef JSON_DLL //These are the only methods you should actuall | | //iterator | |
| y use | | #ifdef JSON_ITERATORS | |
| #ifndef JSON_PREPARSE | | #ifndef JSON_LIBRARY | |
| void Preparse(void); | | #define json_iterator_ptr(iter) iter.it | |
| #endif | | #define ptr_to_json_iterator(iter) json_iterator(iter) | |
| | | struct iterator { | |
| | | inline iterator& operator ++(void){ ++it; return *t | |
| | | his; } | |
| | | inline iterator& operator --(void){ --it; return *t | |
| | | his; } | |
| | | inline iterator& operator +=(long i){ it += i; retu | |
| | | rn *this; } | |
| | | inline iterator& operator -=(long i){ it -= i; retu | |
| | | rn *this; } | |
| | | inline iterator operator ++(int){ | |
| | | iterator result(*this); | |
| | | ++it; | |
| | | return result; | |
| | | } | |
| | | inline iterator operator --(int){ | |
| | | iterator result(*this); | |
| | | --it; | |
| | | return result; | |
| | | } | |
| | | inline iterator operator +(long i) const { | |
| | | iterator result(*this); | |
| | | result.it += i; | |
| | | return result; | |
| | | } | |
| | | inline iterator operator -(long i) const { | |
| | | iterator result(*this); | |
| | | result.it -= i; | |
| | | return result; | |
| | | } | |
| | | inline JSONNode& operator [](size_t pos) const { re | |
| | | turn *it[pos]; }; | |
| | | inline JSONNode& operator *(void) const { return *( | |
| | | *it); } | |
| | | inline bool operator == (const iterator & other) co | |
| | | nst { return it == other.it; } | |
| | | inline bool operator != (const iterator & other) co | |
| | | nst { return it != other.it; } | |
| | | inline bool operator > (const iterator & other) con | |
| | | st { return it > other.it; } | |
| | | inline bool operator >= (const iterator & other) co | |
| | | nst { return it >= other.it; } | |
| | | inline bool operator < (const iterator & other) con | |
| | | st { return it < other.it; } | |
| | | inline bool operator <= (const iterator & other) co | |
| | | nst { return it <= other.it; } | |
| | | inline iterator & operator = (const iterator & orig | |
| | | ){ it = orig.it; return *this; } | |
| | | iterator (const iterator & orig) : it(orig.it) {} | |
| | | private: | |
| | | JSONNode ** it; | |
| | | iterator(JSONNode ** starter) : it(starter) {} | |
| | | friend class JSONNode; | |
| | | }; | |
| | | typedef iterator json_iterator; | |
| | | | |
|
| JSONNode * GetNode(const json_string & name); | | struct const_iterator { | |
| JSONNode * GetNode_NoCase(const json_string & name); | | inline const_iterator& operator ++(void){ ++it; ret | |
| JSONNode * NodeAt(unsigned int position); | | urn *this; } | |
| unsigned int NodeSize(void); | | inline const_iterator& operator --(void){ --it; ret | |
| JSONNode * PopNode(const json_string & name); | | urn *this; } | |
| JSONNode * PopNode_NoCase(const json_string & name); | | inline const_iterator& operator +=(long i){ it += i | |
| JSONNode * PopNodeAt(unsigned int position); | | ; return *this; } | |
| | | inline const_iterator& operator -=(long i){ it -= i | |
| | | ; return *this; } | |
| | | inline const_iterator operator ++(int){ | |
| | | const_iterator result(*this); | |
| | | ++it; | |
| | | return result; | |
| | | } | |
| | | inline const_iterator operator --(int){ | |
| | | const_iterator result(*this); | |
| | | --it; | |
| | | return result; | |
| | | } | |
| | | inline const_iterator operator +(long i) const { | |
| | | const_iterator result(*this); | |
| | | result.it += i; | |
| | | return result; | |
| | | } | |
| | | inline const_iterator operator -(long i) const { | |
| | | const_iterator result(*this); | |
| | | result.it -= i; | |
| | | return result; | |
| | | } | |
| | | inline const JSONNode& operator [](size_t pos) cons | |
| | | t { return const_cast<const JSONNode&>(*it[pos]); }; | |
| | | inline const JSONNode& operator *(void) const { ret | |
| | | urn const_cast<const JSONNode&>(*(*it)); } | |
| | | inline bool operator == (const const_iterator & oth | |
| | | er) const { return it == other.it; } | |
| | | inline bool operator != (const const_iterator & oth | |
| | | er) const { return it != other.it; } | |
| | | inline bool operator > (const const_iterator & othe | |
| | | r) const { return it > other.it; } | |
| | | inline bool operator >= (const const_iterator & oth | |
| | | er) const { return it >= other.it; } | |
| | | inline bool operator < (const const_iterator & othe | |
| | | r) const { return it < other.it; } | |
| | | inline bool operator <= (const const_iterator & oth | |
| | | er) const { return it <= other.it; } | |
| | | inline const_iterator & operator =(const const_iter | |
| | | ator & orig){ it = orig.it; return *this; } | |
| | | const_iterator (const const_iterator & orig) : it(o | |
| | | rig.it) {} | |
| | | private: | |
| | | JSONNode ** it; | |
| | | const_iterator(JSONNode ** starter) : it(starter) { | |
| | | } | |
| | | friend class JSONNode; | |
| | | }; | |
| | | const_iterator begin(void) const; | |
| | | const_iterator end(void) const; | |
| | | | |
|
| char NodeType(void); | | struct reverse_iterator { | |
| const json_string & NodeName(void); | | inline reverse_iterator& operator ++(void){ --it; r | |
| const json_string & NodeAsString(void); | | eturn *this; } | |
| int NodeAsInt(void); | | inline reverse_iterator& operator --(void){ ++it; r | |
| bool NodeAsBool(void); | | eturn *this; } | |
| #ifdef JSON_LESS_MEMORY | | inline reverse_iterator& operator +=(long i){ it -= | |
| float NodeAsFloat(void); | | i; return *this; } | |
| #else | | inline reverse_iterator& operator -=(long i){ it += | |
| double NodeAsFloat(void); | | i; return *this; } | |
| #endif | | inline reverse_iterator operator ++(int){ | |
| | | reverse_iterator result(*this); | |
| | | --it; | |
| | | return result; | |
| | | } | |
| | | inline reverse_iterator operator --(int){ | |
| | | reverse_iterator result(*this); | |
| | | ++it; | |
| | | return result; | |
| | | } | |
| | | inline reverse_iterator operator +(long i) const { | |
| | | reverse_iterator result(*this); | |
| | | result.it -= i; | |
| | | return result; | |
| | | } | |
| | | inline reverse_iterator operator -(long i) const { | |
| | | reverse_iterator result(*this); | |
| | | result.it += i; | |
| | | return result; | |
| | | } | |
| | | inline JSONNode& operator [](size_t pos) const { re | |
| | | turn *it[pos]; }; | |
| | | inline JSONNode& operator *(void) const { return *( | |
| | | *it); } | |
| | | inline bool operator == (const reverse_iterator & o | |
| | | ther) const { return it == other.it; } | |
| | | inline bool operator != (const reverse_iterator & o | |
| | | ther) const { return it != other.it; } | |
| | | inline bool operator < (const reverse_iterator & ot | |
| | | her) const { return it > other.it; } | |
| | | inline bool operator <= (const reverse_iterator & o | |
| | | ther) const { return it >= other.it; } | |
| | | inline bool operator > (const reverse_iterator & ot | |
| | | her) const { return it < other.it; } | |
| | | inline bool operator >= (const reverse_iterator & o | |
| | | ther) const { return it <= other.it; } | |
| | | inline reverse_iterator & operator = (const reverse | |
| | | _iterator & orig){ it = orig.it; return *this; } | |
| | | reverse_iterator (const reverse_iterator & orig) : | |
| | | it(orig.it) {} | |
| | | private: | |
| | | JSONNode ** it; | |
| | | reverse_iterator(JSONNode ** starter) : it(starter) | |
| | | {} | |
| | | friend class JSONNode; | |
| | | }; | |
| | | reverse_iterator rbegin(void); | |
| | | reverse_iterator rend(void); | |
| | | | |
|
| JSONNode * AddNewChild(const json_string & name, const jso | | struct reverse_const_iterator { | |
| n_string & value); | | inline reverse_const_iterator& operator ++(void){ - | |
| JSONNode * AddNewStringChild(const json_string & name, con | | -it; return *this; } | |
| st json_string & value); | | inline reverse_const_iterator& operator --(void){ + | |
| JSONNode * Duplicate(void); | | +it; return *this; } | |
| | | inline reverse_const_iterator& operator +=(long i){ | |
| | | it -= i; return *this; } | |
| | | inline reverse_const_iterator& operator -=(long i){ | |
| | | it += i; return *this; } | |
| | | inline reverse_const_iterator operator ++(int){ | |
| | | reverse_const_iterator result(*this); | |
| | | --it; | |
| | | return result; | |
| | | } | |
| | | inline reverse_const_iterator operator --(int){ | |
| | | reverse_const_iterator result(*this); | |
| | | ++it; | |
| | | return result; | |
| | | } | |
| | | inline reverse_const_iterator operator +(long i) co | |
| | | nst { | |
| | | reverse_const_iterator result(*this); | |
| | | result.it -= i; | |
| | | return result; | |
| | | } | |
| | | inline reverse_const_iterator operator -(long i) co | |
| | | nst { | |
| | | reverse_const_iterator result(*this); | |
| | | result.it += i; | |
| | | return result; | |
| | | } | |
| | | inline const JSONNode& operator [](size_t pos) cons | |
| | | t { return const_cast<const JSONNode&>(*it[pos]); }; | |
| | | inline const JSONNode& operator *(void) const { ret | |
| | | urn const_cast<const JSONNode&>(*(*it)); } | |
| | | inline bool operator == (const reverse_const_iterat | |
| | | or & other) const { return it == other.it; } | |
| | | inline bool operator != (const reverse_const_iterat | |
| | | or & other) const { return it != other.it; } | |
| | | inline bool operator < (const reverse_const_iterato | |
| | | r & other) const { return it > other.it; } | |
| | | inline bool operator <= (const reverse_const_iterat | |
| | | or & other) const { return it >= other.it; } | |
| | | inline bool operator > (const reverse_const_iterato | |
| | | r & other) const { return it < other.it; } | |
| | | inline bool operator >= (const reverse_const_iterat | |
| | | or & other) const { return it <= other.it; } | |
| | | inline reverse_const_iterator & operator = (const r | |
| | | everse_const_iterator & orig){ it = orig.it; return *this; } | |
| | | reverse_const_iterator (const reverse_const_iterato | |
| | | r & orig) : it(orig.it) {} | |
| | | private: | |
| | | JSONNode ** it; | |
| | | reverse_const_iterator(JSONNode ** starter) : it(st | |
| | | arter) {} | |
| | | friend class JSONNode; | |
| | | }; | |
| | | reverse_const_iterator rbegin(void) const; | |
| | | reverse_const_iterator rend(void) const; | |
| | | | |
|
| void AddChild(const JSONNode * node); | | const_iterator find(const json_string & name_t) const; | |
| void SetValue(const json_string & value); | | #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | |
| void SetStringValue(const json_string & value); | | const_iterator find_nocase(const json_string & name | |
| | | _t) const; | |
| | | #endif | |
| | | | |
|
| void AddComment(const json_string & comment); | | reverse_iterator erase(reverse_iterator pos); | |
| json_string Write(unsigned int indent = 0xFFFFFFFF); | | reverse_iterator erase(reverse_iterator start, const rever | |
| json_string WriteFormatted(void); | | se_iterator & end); | |
| | | | |
|
| #ifdef DEBUG | | iterator insert(iterator pos, const JSONNode & x); | |
| json_string Dump(void); | | reverse_iterator insert(reverse_iterator pos, const JSONNo | |
| #endif | | de & x); | |
| | | iterator insert(iterator pos, const reverse_iterator & _st | |
| | | art, const reverse_iterator & _end); | |
| | | reverse_iterator insert(reverse_iterator pos, const iterat | |
| | | or & _start, const iterator & _end); | |
| | | reverse_iterator insert(reverse_iterator pos, const revers | |
| | | e_iterator & _start, const reverse_iterator & _end); | |
| | | | |
| | | json_iterator insert(json_iterator pos, const const_iterat | |
| | | or & _start, const const_iterator & _end); | |
| | | reverse_iterator insert(reverse_iterator pos, const const_ | |
| | | iterator & _start, const const_iterator & _end); | |
| | | json_iterator insert(json_iterator pos, const reverse_cons | |
| | | t_iterator & _start, const reverse_const_iterator & _end); | |
| | | reverse_iterator insert(reverse_iterator pos, const revers | |
| | | e_const_iterator & _start, const reverse_const_iterator & _end); | |
| | | #else | |
| | | typedef JSONNode** json_iterator; | |
| | | #define json_iterator_ptr(iter) iter | |
| | | #define ptr_to_json_iterator(iter) iter | |
| | | json_iterator insert(json_iterator pos, JSONNode * x); | |
| #endif | | #endif | |
| | | | |
|
| #ifdef JSON_SAFE | | json_iterator begin(void); | |
| void Nullify(void); | | json_iterator end(void); | |
| | | | |
| | | json_iterator find(const json_string & name_t); | |
| | | #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | |
| | | json_iterator find_nocase(const json_string & name_t); | |
| #endif | | #endif | |
|
| | | json_iterator erase(json_iterator pos); | |
| | | json_iterator erase(json_iterator start, const json_iterator & en | |
| | | d); | |
| | | json_iterator insert(json_iterator pos, const json_iterator & _st | |
| | | art, const json_iterator & _end); | |
| | | #endif | |
| | | | |
|
| #ifdef DEBUG | | #ifdef JSON_MUTEX_CALLBACKS | |
| unsigned int GetMemoryUsage(void); | | static void register_mutex_callbacks(json_mutex_callback_t lock, | |
| json_string MemDump(unsigned int indent = 0); | | json_mutex_callback_t unlock, void * manager_lock); | |
| | | #ifdef JSON_MUTEX_MANAGE | |
| | | static void register_mutex_destructor(json_mutex_callback_ | |
| | | t destroy); | |
| #endif | | #endif | |
|
| | | static void set_global_mutex(void * mutex); | |
| | | void set_mutex(void * mutex); | |
| | | void lock(int thread); | |
| | | void unlock(int thread); | |
| | | struct auto_lock { | |
| | | public: | |
| | | auto_lock(JSONNode & node, int thread) : mynode(&no | |
| | | de), mythread(thread){ | |
| | | mynode -> lock(mythread); | |
| | | } | |
| | | auto_lock(JSONNode * node, int thread) : mynode(nod | |
| | | e), mythread(thread){ | |
| | | mynode -> lock(mythread); | |
| | | } | |
| | | ~auto_lock(void){ | |
| | | mynode -> unlock(mythread); | |
| | | } | |
| | | private: | |
| | | auto_lock & operator = (const auto_lock &); | |
| | | auto_lock(const auto_lock &); | |
| | | JSONNode * mynode; | |
| | | int mythread; | |
| | | }; | |
| | | static void * getThisLock(JSONNode * pthis); | |
| | | #endif | |
| | | | |
|
| //This is the name of the node, the encoded flag tells the writer wh | | #ifdef JSON_UNIT_TEST | |
| ether or not to re-escape it when it gets written | | static int getNodeAllocationCount(void); | |
| json_string _name; bool name_encoded; | | static int getNodeDeallocationCount(void); | |
| | | static int getInternalAllocationCount(void); | |
| | | static int getInternalDeallocationCount(void); | |
| | | static void incAllocCount(void); | |
| | | static void decAllocCount(void); | |
| | | static void incinternalAllocCount(void); | |
| | | static void decinternalAllocCount(void); | |
| | | #endif | |
| | | | |
|
| //This is the json_string that is the value of the node, this mig | | #ifdef JSON_WRITER | |
| ht be a json_string, a number, or even a set of nodes or array that hasn't | | json_string write(void); | |
| been parsed yet | | json_string write_formatted(void); | |
| json_string _string; bool string_encoded; | | #endif | |
| | | | |
|
| //internal structure changes depending on type | | #ifdef JSON_DEBUG | |
| value_union_t _value; | | #ifndef JSON_LIBRARY | |
| | | JSONNode dump(void) const; | |
| | | #endif | |
| | | #endif | |
| | | static void deleteJSONNode(JSONNode * ptr); | |
| | | static JSONNode * newJSONNode_Shallow(const JSONNode & orig); | |
| | | JSON_PRIVATE | |
| | | static JSONNode * newJSONNode(const JSONNode & orig JSON_MUTEX_COPY | |
| | | _DECL2); | |
| | | static JSONNode * newJSONNode(internalJSONNode * internal_t); | |
| | | //used by JSONWorker | |
| | | JSONNode(const json_string & unparsed) : internal(internalJSONNode::new | |
| | | Internal(unparsed)){ //root, specialized because it can only be array or no | |
| | | de | |
| | | incAllocCount(); | |
| | | } | |
| | | JSONNode(internalJSONNode * internal_t) : internal(internal_t){ //do no | |
| | | t increment anything, this is only used in one case and it's already taken | |
| | | care of | |
| | | incAllocCount(); | |
| | | } | |
| | | JSONNode(bool, JSONNode & orig); | |
| | | | |
|
| jsonChildren Children; | | void decRef(void); //decrements internal's counter, deletes it if need | |
| private: | | ed | |
| void FetchString(void); | | #ifdef JSON_REF_COUNT | |
| void FetchNode(void); | | void makeUniqueInternal(void); //makes internal it's own | |
| void FetchArray(void); | | void merge(JSONNode * other); | |
| void FetchNumber(void); | | #endif | |
| | | | |
|
| json_string WriteChildren(unsigned int indent); | | #ifdef JSON_DEBUG | |
| json_string WriteName(bool formatted) const; | | #ifndef JSON_LIBRARY | |
| json_string WriteComment(unsigned int indent) const; | | JSONNode dump(size_t & totalmemory); | |
| | | #endif | |
| | | #endif | |
| | | | |
| | | #ifdef JSON_ITERATORS | |
| | | #ifndef JSON_LIBRARY | |
| | | json_iterator insertFRR(json_iterator pos, JSONNode ** con | |
| | | st _start, JSONNode ** const _end); | |
| | | reverse_iterator insertRRR(reverse_iterator pos, JSONNode | |
| | | ** const _start, JSONNode ** const _end); | |
| | | reverse_iterator insertRFF(reverse_iterator pos, JSONNode | |
| | | ** const _start, JSONNode ** const _end); | |
| | | #endif | |
| | | json_iterator insertFFF(json_iterator pos, JSONNode ** const _sta | |
| | | rt, JSONNode ** const _end); | |
| | | #endif | |
| | | | |
| | | mutable internalJSONNode * internal; | |
| | | friend class JSONWorker; | |
| | | friend class internalJSONNode; | |
| }; | | }; | |
| | | | |
|
| | | /* | |
| | | Implementations are here to keep the class declaration cleaner. They c | |
| | | an't be placed in a different | |
| | | file because they are inlined. | |
| | | */ | |
| | | | |
| | | inline JSONNode::JSONNode(char mytype) : internal(internalJSONNode::newInte | |
| | | rnal(mytype)){ | |
| | | JSON_ASSERT((mytype == JSON_NULL) || | |
| | | (mytype == JSON_STRING) || | |
| | | (mytype == JSON_NUMBER) || | |
| | | (mytype == JSON_BOOL) || | |
| | | (mytype == JSON_ARRAY) || | |
| | | (mytype == JSON_NODE), JSON_TEXT("Not a proper JSON | |
| | | type")); | |
| | | incAllocCount(); | |
| | | } | |
| | | | |
| | | inline JSONNode::JSONNode(const JSONNode & orig): internal(orig.internal -> | |
| | | incRef()){ | |
| | | incAllocCount(); | |
| | | } | |
| | | | |
| | | //this allows a temp node to simply transfer its contents, even with ref co | |
| | | unting off | |
| | | inline JSONNode::JSONNode(bool, JSONNode & orig): internal(orig.internal){ | |
| | | orig.internal = 0; | |
| | | incAllocCount(); | |
| | | } | |
| | | | |
| | | inline JSONNode::~JSONNode(void){ | |
| | | if (internal) decRef(); | |
| | | decAllocCount(); | |
| | | } | |
| | | | |
| | | inline json_index_t JSONNode::size(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> size(); | |
| | | } | |
| | | | |
| | | inline bool JSONNode::empty(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> empty(); | |
| | | } | |
| | | | |
| | | inline void JSONNode::clear(void){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | if (!empty()){ | |
| | | makeUniqueInternal(); | |
| | | internal -> Children.clear(); | |
| | | } | |
| | | } | |
| | | | |
| | | inline unsigned char JSONNode::type(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> type(); | |
| | | } | |
| | | | |
| | | inline json_string JSONNode::name(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> name(); | |
| | | } | |
| | | | |
| | | inline void JSONNode::set_name(const json_string & newname){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | makeUniqueInternal(); | |
| | | internal -> setname(newname); | |
| | | } | |
| | | | |
| | | #ifdef JSON_COMMENTS | |
| | | inline void JSONNode::set_comment(const json_string & newname){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | makeUniqueInternal(); | |
| | | internal -> setcomment(newname); | |
| | | } | |
| | | | |
| | | inline json_string JSONNode::get_comment(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> getcomment(); | |
| | | } | |
| | | #endif | |
| | | | |
| | | inline json_string JSONNode::as_string(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> as_string(); | |
| | | } | |
| | | | |
| | | inline long JSONNode::as_int(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> as_int(); | |
| | | } | |
| | | | |
| | | inline json_number JSONNode::as_float(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> as_float(); | |
| | | } | |
| | | | |
| | | inline bool JSONNode::as_bool(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> as_bool(); | |
| | | } | |
| | | | |
| | | #ifdef JSON_BINARY | |
| | | inline void JSONNode::set_binary(const unsigned char * bin, json_index_ | |
| | | t bytes){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | *this = JSONBase64::json_encode64(bin, bytes); | |
| | | } | |
| | | | |
| | | inline std::string JSONNode::as_binary(void) const { | |
| | | JSON_ASSERT_SAFE(type() == JSON_STRING, JSON_TEXT("using as_binar | |
| | | y for a non-string type"), return EMPTY_STRING2;); | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return JSONBase64::json_decode64(as_string()); | |
| | | } | |
| | | #endif | |
| | | | |
| | | inline JSONNode & JSONNode::operator[](const json_string & name_t){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | makeUniqueInternal(); | |
| | | return *(*(internal -> at(name_t))); | |
| | | } | |
| | | | |
| | | inline const JSONNode & JSONNode::operator[](const json_string & name_t) co | |
| | | nst { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return *(*(internal -> at(name_t))); | |
| | | } | |
| | | | |
| | | #ifdef JSON_LIBRARY | |
| | | inline void JSONNode::push_back(JSONNode * child){ | |
| | | #else | |
| | | inline void JSONNode::push_back(const JSONNode & child){ | |
| | | #endif | |
| | | JSON_CHECK_INTERNAL(); | |
| | | makeUniqueInternal(); | |
| | | internal -> push_back(child); | |
| | | } | |
| | | | |
| | | inline void JSONNode::reserve(json_index_t size){ | |
| | | makeUniqueInternal(); | |
| | | internal -> reserve(size); | |
| | | } | |
| | | | |
| | | inline JSONNode & JSONNode::operator = (const JSONNode & orig){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | #ifdef JSON_REF_COUNT | |
| | | if (internal == orig.internal) return *this; //don't want it acc | |
| | | identally deleting itself | |
| | | #endif | |
| | | decRef(); //dereference my current one | |
| | | internal = orig.internal -> incRef(); //increase reference of original | |
| | | return *this; | |
| | | } | |
| | | | |
| | | #ifndef JSON_LIBRARY | |
| | | inline JSONNode & JSONNode::operator = (const json_char * val){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | *this = json_string(val); | |
| | | return *this; | |
| | | } | |
| | | #endif | |
| | | | |
| | | #define NODE_SET_TYPED(type)\ | |
| | | inline JSONNode & JSONNode::operator = (type val){\ | |
| | | JSON_CHECK_INTERNAL();\ | |
| | | makeUniqueInternal();\ | |
| | | internal -> Set(val);\ | |
| | | return *this;\ | |
| | | } | |
| | | | |
| | | IMPLEMENT_FOR_ALL_TYPES(NODE_SET_TYPED) | |
| | | | |
| | | /* | |
| | | This section is the equality operators | |
| | | */ | |
| | | | |
| | | #define NODE_CHECK_EQUALITY(type)\ | |
| | | inline bool JSONNode::operator == (type val) const {\ | |
| | | JSON_CHECK_INTERNAL();\ | |
| | | return internal -> IsEqualToNum<type>(val);\ | |
| | | } | |
| | | | |
| | | IMPLEMENT_FOR_ALL_NUMBERS(NODE_CHECK_EQUALITY) | |
| | | | |
| | | inline bool JSONNode::operator == (const json_string & val) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> IsEqualTo(val); | |
| | | } | |
| | | | |
| | | #ifndef JSON_LIBRARY | |
| | | inline bool JSONNode::operator == (const json_char * val) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return *this == json_string(val); | |
| | | } | |
| | | #endif | |
| | | | |
| | | inline bool JSONNode::operator == (bool val) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> IsEqualTo(val); | |
| | | } | |
| | | inline bool JSONNode::operator == (const JSONNode & val) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | return internal -> IsEqualTo(val.internal); | |
| | | } | |
| | | | |
| | | /* | |
| | | This section is the inequality operators | |
| | | */ | |
| | | | |
| | | #define NODE_CHECK_INEQUALITY(type)\ | |
| | | inline bool JSONNode::operator != (type val) const {\ | |
| | | JSON_CHECK_INTERNAL();\ | |
| | | return !(*this == val);\ | |
| | | } | |
| | | | |
| | | IMPLEMENT_FOR_ALL_TYPES(NODE_CHECK_INEQUALITY) | |
| | | NODE_CHECK_INEQUALITY(const JSONNode &) | |
| | | #ifndef JSON_LIBRARY | |
| | | NODE_CHECK_INEQUALITY(const json_char * ) | |
| | | #endif | |
| | | | |
| | | inline void JSONNode::nullify(void){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | makeUniqueInternal(); | |
| | | internal -> Nullify(); | |
| | | } | |
| | | | |
| | | inline void JSONNode::swap(JSONNode & other){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | internalJSONNode * temp = other.internal; | |
| | | other.internal = internal; | |
| | | internal = temp; | |
| | | JSON_CHECK_INTERNAL(); | |
| | | } | |
| | | | |
| | | inline void JSONNode::decRef(void){ //decrements internal's counter, delete | |
| | | s it if needed | |
| | | JSON_CHECK_INTERNAL(); | |
| | | #ifdef JSON_REF_COUNT | |
| | | internal -> decRef(); | |
| | | if (internal -> hasNoReferences()){ | |
| | | internalJSONNode::deleteInternal(internal); | |
| | | } | |
| | | #else | |
| | | internalJSONNode::deleteInternal(internal); | |
| | | #endif | |
| | | } | |
| | | | |
| | | #ifdef JSON_REF_COUNT | |
| | | inline void JSONNode::makeUniqueInternal(){ //makes internal it's own | |
| | | JSON_CHECK_INTERNAL(); | |
| | | internal = internal -> makeUnique(); //might return itself or a | |
| | | new one that's exactly the same | |
| | | } | |
| | | #endif | |
| | | | |
| | | #ifdef JSON_ITERATORS | |
| | | inline JSONNode::json_iterator JSONNode::begin(void){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEX | |
| | | T("iterating a non-iteratable node")); | |
| | | makeUniqueInternal(); | |
| | | return json_iterator(internal -> begin()); | |
| | | } | |
| | | | |
| | | inline JSONNode::json_iterator JSONNode::end(void){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEX | |
| | | T("iterating a non-iteratable node")); | |
| | | makeUniqueInternal(); | |
| | | return json_iterator(internal -> end()); | |
| | | } | |
| | | | |
| | | #ifndef JSON_LIBRARY | |
| | | inline JSONNode::const_iterator JSONNode::begin(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J | |
| | | SON_TEXT("iterating a non-iteratable node")); | |
| | | return JSONNode::const_iterator(internal -> begin()); | |
| | | } | |
| | | | |
| | | inline JSONNode::const_iterator JSONNode::end(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J | |
| | | SON_TEXT("iterating a non-iteratable node")); | |
| | | return JSONNode::const_iterator(internal -> end()); | |
| | | } | |
| | | | |
| | | inline JSONNode::reverse_iterator JSONNode::rbegin(void){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J | |
| | | SON_TEXT("iterating a non-iteratable node")); | |
| | | makeUniqueInternal(); | |
| | | return JSONNode::reverse_iterator(internal -> end() - 1); | |
| | | } | |
| | | | |
| | | inline JSONNode::reverse_iterator JSONNode::rend(void){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J | |
| | | SON_TEXT("iterating a non-iteratable node")); | |
| | | makeUniqueInternal(); | |
| | | return JSONNode::reverse_iterator(internal -> begin() - 1) | |
| | | ; | |
| | | } | |
| | | | |
| | | inline JSONNode::reverse_const_iterator JSONNode::rbegin(void) co | |
| | | nst { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J | |
| | | SON_TEXT("iterating a non-iteratable node")); | |
| | | return JSONNode::reverse_const_iterator(internal -> end() | |
| | | - 1); | |
| | | } | |
| | | | |
| | | inline JSONNode::reverse_const_iterator JSONNode::rend(void) cons | |
| | | t { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J | |
| | | SON_TEXT("iterating a non-iteratable node")); | |
| | | return JSONNode::reverse_const_iterator(internal -> begin( | |
| | | ) - 1); | |
| | | } | |
| | | | |
| | | inline JSONNode::iterator JSONNode::insert(json_iterator pos, con | |
| | | st const_iterator & _start, const const_iterator & _end){ | |
| | | return insertFFF(pos, _start.it, _end.it); | |
| | | } | |
| | | | |
| | | inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat | |
| | | or pos, const const_iterator & _start, const const_iterator & _end){ | |
| | | return insertRFF(pos, _start.it, _end.it); | |
| | | } | |
| | | | |
| | | inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat | |
| | | or pos, const iterator & _start, const iterator & _end){ | |
| | | return insertRFF(pos, _start.it, _end.it); | |
| | | } | |
| | | | |
| | | inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat | |
| | | or pos, const reverse_const_iterator & _start, const reverse_const_iterator | |
| | | & _end){ | |
| | | return insertRRR(pos, _start.it, _end.it); | |
| | | } | |
| | | | |
| | | inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat | |
| | | or pos, const reverse_iterator & _start, const reverse_iterator & _end){ | |
| | | return insertRRR(pos, _start.it, _end.it); | |
| | | } | |
| | | | |
| | | inline JSONNode::iterator JSONNode::insert(json_iterator pos, con | |
| | | st reverse_const_iterator & _start, const reverse_const_iterator & _end){ | |
| | | return insertFRR(pos, _start.it, _end.it); | |
| | | } | |
| | | | |
| | | inline JSONNode::iterator JSONNode::insert(iterator pos, const re | |
| | | verse_iterator & _start, const reverse_iterator & _end){ | |
| | | return insertFRR(pos, _start.it, _end.it); | |
| | | } | |
| | | #endif | |
| | | | |
| | | inline JSONNode::json_iterator JSONNode::insert(json_iterator pos, cons | |
| | | t json_iterator & _start, const json_iterator & _end){ | |
| | | return insertFFF(pos, json_iterator_ptr(_start), json_iterator_pt | |
| | | r(_end)); | |
| | | } | |
| | | #endif | |
| | | | |
| | | #ifdef JSON_WRITER | |
| | | inline json_string JSONNode::write(void){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSO | |
| | | N_TEXT("Writing a non-writable node"), return JSON_TEXT("");); | |
| | | return internal -> Write(0xFFFFFFFF, true); | |
| | | } | |
| | | | |
| | | inline json_string JSONNode::write_formatted(void){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSO | |
| | | N_TEXT("Writing a non-writable node"), return JSON_TEXT("");); | |
| | | return internal -> Write(0, true); | |
| | | } | |
| | | | |
| | | #endif | |
| | | | |
| | | #ifndef JSON_PREPARSE | |
| | | inline void JSONNode::preparse(void){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | internal -> preparse(); | |
| | | } | |
| | | #endif | |
| | | | |
| | | #ifdef JSON_VALIDATE | |
| | | inline bool JSONNode::validate(void){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | if (type() == JSON_NULL) return false; | |
| | | JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSO | |
| | | N_TEXT("Validating non root node"), return false;); | |
| | | #ifndef JSON_PREPARSE | |
| | | internal -> Fetch(); //will nullify it if it's bad | |
| | | #endif | |
| | | if (type() == JSON_NULL) return false; | |
| | | return internal -> validate(); | |
| | | } | |
| | | #endif | |
| | | | |
| | | #ifdef JSON_DEBUG | |
| | | #ifndef JSON_LIBRARY | |
| | | inline JSONNode JSONNode::dump(void) const { | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSONNode dumpage(JSON_NODE); | |
| | | dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("this"), (lo | |
| | | ng)this))); | |
| | | size_t total = 0; | |
| | | JSONNode node = internal -> Dump(total); | |
| | | dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("total bytes | |
| | | used"), total))); | |
| | | dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("bytes used" | |
| | | ), sizeof(JSONNode)))); | |
| | | dumpage.push_back(JSON_NEW(node)); | |
| | | return dumpage; | |
| | | } | |
| | | | |
| | | inline JSONNode JSONNode::dump(size_t & totalmemory){ | |
| | | JSON_CHECK_INTERNAL(); | |
| | | JSONNode dumpage(JSON_NODE); | |
| | | dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("this"), (lo | |
| | | ng)this))); | |
| | | dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("bytes used" | |
| | | ), sizeof(JSONNode)))); | |
| | | dumpage.push_back(JSON_NEW(internal -> Dump(totalmemory))) | |
| | | ; | |
| | | return dumpage; | |
| | | } | |
| | | #endif | |
| | | #endif | |
| | | | |
| | | inline void JSONNode::deleteJSONNode(JSONNode * ptr){ | |
| | | #ifdef JSON_MEMORY_CALLBACKS | |
| | | ptr -> ~JSONNode(); | |
| | | libjson_free<JSONNode>(ptr); | |
| | | #else | |
| | | delete ptr; | |
| | | #endif | |
| | | } | |
| | | | |
| | | inline JSONNode * _newJSONNode(const JSONNode & orig){ | |
| | | #ifdef JSON_MEMORY_CALLBACKS | |
| | | return new(json_malloc<JSONNode>(1)) JSONNode(orig); | |
| | | #else | |
| | | return new JSONNode(orig); | |
| | | #endif | |
| | | } | |
| | | | |
| | | inline JSONNode * JSONNode::newJSONNode(const JSONNode & orig JSON_MUTEX | |
| | | _COPY_DECL){ | |
| | | #ifdef JSON_MUTEX_CALLBACKS | |
| | | if (parentMutex){ | |
| | | JSONNode * temp = _newJSONNode(orig); | |
| | | temp -> set_mutex(parentMutex); | |
| | | return temp; | |
| | | } | |
| | | #endif | |
| | | return _newJSONNode(orig); | |
| | | } | |
| | | | |
| | | inline JSONNode * JSONNode::newJSONNode(internalJSONNode * internal_t){ | |
| | | #ifdef JSON_MEMORY_CALLBACKS | |
| | | return new(json_malloc<JSONNode>(1)) JSONNode(internal_t); | |
| | | #else | |
| | | return new JSONNode(internal_t); | |
| | | #endif | |
| | | } | |
| | | | |
| | | inline JSONNode * JSONNode::newJSONNode_Shallow(const JSONNode & orig){ | |
| | | #ifdef JSON_MEMORY_CALLBACKS | |
| | | return new(json_malloc<JSONNode>(1)) JSONNode(true, const_cast<JS | |
| | | ONNode &>(orig)); | |
| | | #else | |
| | | return new JSONNode(true, const_cast<JSONNode &>(orig)); | |
| | | #endif | |
| | | } | |
| #endif | | #endif | |
| | | | |
End of changes. 27 change blocks. |
| 102 lines changed or deleted | | 1019 lines changed or added | |
|