summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/modules/json/JSONDefs.h166
-rw-r--r--src/modules/json/JSONIterators.cpp478
-rw-r--r--src/modules/json/JSONMemory.cpp212
-rw-r--r--src/modules/json/JSONMemory.h268
-rw-r--r--src/modules/json/JSONNode.cpp622
-rw-r--r--src/modules/json/JSONNode.h1846
6 files changed, 1796 insertions, 1796 deletions
diff --git a/src/modules/json/JSONDefs.h b/src/modules/json/JSONDefs.h
index e354a0b9fa..5f66efcd33 100644
--- a/src/modules/json/JSONDefs.h
+++ b/src/modules/json/JSONDefs.h
@@ -1,83 +1,83 @@
-#ifndef JSONDEFS_H
-#define JSONDEFS_H
-
-/*
- Defines all of the types of functions and various other definitions
- that are used in C applications, this is very useful if dynamically loading
- the library instead of linking.
-*/
-
-#include "JSONOptions.h"
-
-#define JSON_NULL '\0'
-#define JSON_STRING '\1'
-#define JSON_NUMBER '\2'
-#define JSON_BOOL '\3'
-#define JSON_ARRAY '\4'
-#define JSON_NODE '\5'
-
-#ifdef __cplusplus
- #include <string>
-#endif
-
-#ifdef JSON_UNICODE
- #ifdef JSON_ISO_STRICT
- #error, You can not use unicode under ISO Strict C++
- #endif
- #define json_char wchar_t
- #define json_uchar wchar_t
- #ifdef __cplusplus
- #include <cwchar> //need wide characters
- typedef std::wstring json_string;
- #else
- #include <wchar.h> //need wide characters
- #endif
- #define JSON_TEXT(s) L ## s
- #define json_strlen wcslen
- #define json_strcmp wcscmp
-#else
- #define json_char char
- #define json_uchar BYTE
- #ifdef __cplusplus
- typedef std::string json_string;
- #endif
- #define JSON_TEXT(s) s
- #define json_strlen strlen
- #define json_strcmp strcmp
-#endif
-
-#ifdef JSON_LESS_MEMORY
- #define BITS(x) :x //tells the compiler how many bits to use for a field
- typedef float json_number;
-#else
- #define BITS(x)
- typedef double json_number;
-#endif
-
-#if defined JSON_DEBUG || defined JSON_SAFE
- #ifdef JSON_LIBRARY
- typedef void (*json_error_callback_t)(const json_char *);
- #else
- typedef void (*json_error_callback_t)(const json_string &);
- #endif
-#endif
-
-#ifdef JSON_INDEX_TYPE
- typedef JSON_INDEX_TYPE json_index_t;
-#else
- typedef unsigned int json_index_t;
-#endif
-
-typedef void (*json_mutex_callback_t)(void *);
-typedef void (*json_free_t)(void *);
-#ifndef JSON_LIBRARY
- typedef void * (*json_malloc_t)(size_t);
- typedef void * (*json_realloc_t)(void *, size_t);
-#else
- #define JSONNODE void //so that JSONNODE* is void*
- typedef JSONNODE** JSONNODE_ITERATOR;
- typedef void * (*json_malloc_t)(unsigned long);
- typedef void * (*json_realloc_t)(void *, unsigned long);
-#endif
-
-#endif //JSONDEFS_H
+#ifndef JSONDEFS_H
+#define JSONDEFS_H
+
+/*
+ Defines all of the types of functions and various other definitions
+ that are used in C applications, this is very useful if dynamically loading
+ the library instead of linking.
+*/
+
+#include "JSONOptions.h"
+
+#define JSON_NULL '\0'
+#define JSON_STRING '\1'
+#define JSON_NUMBER '\2'
+#define JSON_BOOL '\3'
+#define JSON_ARRAY '\4'
+#define JSON_NODE '\5'
+
+#ifdef __cplusplus
+ #include <string>
+#endif
+
+#ifdef JSON_UNICODE
+ #ifdef JSON_ISO_STRICT
+ #error, You can not use unicode under ISO Strict C++
+ #endif
+ #define json_char wchar_t
+ #define json_uchar wchar_t
+ #ifdef __cplusplus
+ #include <cwchar> //need wide characters
+ typedef std::wstring json_string;
+ #else
+ #include <wchar.h> //need wide characters
+ #endif
+ #define JSON_TEXT(s) L ## s
+ #define json_strlen wcslen
+ #define json_strcmp wcscmp
+#else
+ #define json_char char
+ #define json_uchar BYTE
+ #ifdef __cplusplus
+ typedef std::string json_string;
+ #endif
+ #define JSON_TEXT(s) s
+ #define json_strlen strlen
+ #define json_strcmp strcmp
+#endif
+
+#ifdef JSON_LESS_MEMORY
+ #define BITS(x) :x //tells the compiler how many bits to use for a field
+ typedef float json_number;
+#else
+ #define BITS(x)
+ typedef double json_number;
+#endif
+
+#if defined JSON_DEBUG || defined JSON_SAFE
+ #ifdef JSON_LIBRARY
+ typedef void (*json_error_callback_t)(const json_char *);
+ #else
+ typedef void (*json_error_callback_t)(const json_string &);
+ #endif
+#endif
+
+#ifdef JSON_INDEX_TYPE
+ typedef JSON_INDEX_TYPE json_index_t;
+#else
+ typedef unsigned int json_index_t;
+#endif
+
+typedef void (*json_mutex_callback_t)(void *);
+typedef void (*json_free_t)(void *);
+#ifndef JSON_LIBRARY
+ typedef void * (*json_malloc_t)(size_t);
+ typedef void * (*json_realloc_t)(void *, size_t);
+#else
+ #define JSONNODE void //so that JSONNODE* is void*
+ typedef JSONNODE** JSONNODE_ITERATOR;
+ typedef void * (*json_malloc_t)(unsigned long);
+ typedef void * (*json_realloc_t)(void *, unsigned long);
+#endif
+
+#endif //JSONDEFS_H
diff --git a/src/modules/json/JSONIterators.cpp b/src/modules/json/JSONIterators.cpp
index 716be5f8e1..28eb6faf32 100644
--- a/src/modules/json/JSONIterators.cpp
+++ b/src/modules/json/JSONIterators.cpp
@@ -1,239 +1,239 @@
-/*
-
-Miranda IM: the free IM client for Microsoft* Windows*
-
-Copyright 2000-2009 Miranda ICQ/IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-
-#include "JSONNode.h"
-
-#ifdef JSON_ITERATORS
- #ifdef JSON_REF_COUNT
- #define JSON_ASSERT_UNIQUE(x) JSON_ASSERT(internal -> refcount == 1, json_string(JSON_TEXT(x)) + JSON_TEXT(" in non single reference"))
- #else
- #define JSON_ASSERT_UNIQUE(x) (void)0
- #endif
-
- #ifdef JSON_MUTEX_CALLBACKS
- #define JSON_MUTEX_COPY2 ,internal -> mylock
- #else
- #define JSON_MUTEX_COPY2
- #endif
-
-JSONNode::json_iterator JSONNode::find(const json_string & name_t){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node"));
- makeUniqueInternal();
- if (JSONNode ** res = internal -> at(name_t)) {
- return ptr_to_json_iterator(res);
- }
- return end();
-}
-
-#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
- JSONNode::json_iterator JSONNode::find_nocase(const json_string & name_t){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node"));
- makeUniqueInternal();
- if (JSONNode ** res = internal -> at_nocase(name_t)) {
- return ptr_to_json_iterator(res);
- }
- return end();
- }
-#endif
-
-JSONNode::json_iterator JSONNode::erase(json_iterator pos){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
- JSON_ASSERT_UNIQUE("erase 1");
- JSON_ASSERT_SAFE(pos < end(), JSON_TEXT("erase out of range"), return end(););
- JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("erase out of range"), return begin(););
- deleteJSONNode(*(json_iterator_ptr(pos)));
- internal -> Children.erase(json_iterator_ptr(pos));
- return (empty()) ? end() : pos;
-}
-
-JSONNode::json_iterator JSONNode::erase(json_iterator _start, const json_iterator & _end){
- if (_start == _end) return _start;
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
- JSON_ASSERT_UNIQUE("erase 3");
- JSON_ASSERT_SAFE(_start <= end(), JSON_TEXT("erase out of lo range"), return end(););
- JSON_ASSERT_SAFE(_end <= end(), JSON_TEXT("erase out of hi range"), return end(););
- JSON_ASSERT_SAFE(_start >= begin(), JSON_TEXT("erase out of lo range"), return begin(););
- JSON_ASSERT_SAFE(_end >= begin(), JSON_TEXT("erase out of hi range"), return begin(););
- for (JSONNode ** pos = json_iterator_ptr(_start); pos < json_iterator_ptr(_end); ++pos){
- deleteJSONNode(*pos);
- }
-
- internal -> Children.erase(json_iterator_ptr(_start), json_iterator_ptr(_end) - json_iterator_ptr(_start));
- return (empty()) ? end() : _start;
-}
-
-#ifdef JSON_LIBRARY
-JSONNode::json_iterator JSONNode::insert(json_iterator pos, JSONNode * x){
-#else
-JSONNode::json_iterator JSONNode::insert(json_iterator pos, const JSONNode & x){
-#endif
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
- JSON_ASSERT_UNIQUE("insert 1");
- if (json_iterator_ptr(pos) >= internal -> Children.end()) {
- internal -> push_back(x);
- return end() - 1;
- }
- JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of lo range"), return begin(););
- #ifdef JSON_LIBRARY
- internal -> Children.insert(json_iterator_ptr(pos), x);
- #else
- internal -> Children.insert(json_iterator_ptr(pos), newJSONNode(x));
- #endif
- return pos;
-}
-
-JSONNode::json_iterator JSONNode::insertFFF(json_iterator pos, JSONNode ** const _start, JSONNode ** const _end){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
- JSON_ASSERT_UNIQUE("insertFFF");
- JSON_ASSERT_SAFE(pos <= end(), JSON_TEXT("insert out of high range"), return end(););
- JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of low range"), return begin(););
- const size_t num = _end - _start;
- json_auto<JSONNode *> mem(num);
- JSONNode ** runner = mem.ptr;
- for (JSONNode ** po = _start; po < _end; ++po){
- *runner++=newJSONNode(*(*po) JSON_MUTEX_COPY2);
- }
- internal -> Children.insert(json_iterator_ptr(pos), mem.ptr, num);
- return pos;
-}
-
-#ifndef JSON_LIBRARY
- JSONNode::const_iterator JSONNode::find(const json_string & name_t) const {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node"));
- if (JSONNode ** res = internal -> at(name_t)) {
- return JSONNode::const_iterator(res);
- }
- return JSONNode::const_iterator(internal -> end());
- }
-
- #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
- JSONNode::const_iterator JSONNode::find_nocase(const json_string & name_t) const {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node"));
- if (JSONNode ** res = internal -> at_nocase(name_t)) {
- return JSONNode::const_iterator(res);
- }
- return JSONNode::const_iterator(internal -> end());
- }
- #endif
-
- JSONNode::reverse_iterator JSONNode::erase(reverse_iterator pos){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
- JSON_ASSERT_UNIQUE("erase 2");
- JSON_ASSERT_SAFE(pos < rend(), JSON_TEXT("erase out of range"), return rend(););
- JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("erase out of range"), return rbegin(););
- deleteJSONNode(*(pos.it));
- internal -> Children.erase(pos.it);
- return (empty()) ? rend() : pos + 1;
- }
-
- JSONNode::reverse_iterator JSONNode::erase(reverse_iterator _start, const reverse_iterator & _end){
- if (_start == _end) return _start;
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
- JSON_ASSERT_UNIQUE("erase 4");
- JSON_ASSERT_SAFE(_start <= rend(), JSON_TEXT("erase out of lo range"), return rend(););
- JSON_ASSERT_SAFE(_end <= rend(), JSON_TEXT("erase out of hi range"), return rend(););
- JSON_ASSERT_SAFE(_start >= rbegin(), JSON_TEXT("erase out of lo range"), return rbegin(););
- JSON_ASSERT_SAFE(_end >= rbegin(), JSON_TEXT("erase out of hi range"), return rbegin(););
- for (JSONNode ** pos = _start.it; pos > _end.it; --pos){
- deleteJSONNode(*pos);
- }
- const size_t num = _start.it - _end.it;
- internal -> Children.erase(_end.it + 1, num, _start.it);
- return (empty()) ? rend() : _start + num;
- }
-
- JSONNode::reverse_iterator JSONNode::insert(reverse_iterator pos, const JSONNode & x){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
- JSON_ASSERT_UNIQUE("insert 1");
- if (pos.it < internal -> Children.begin()) {
- internal -> push_front(x);
- return rend() - 1;
- }
- JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin(););
- internal -> Children.insert(++pos.it, newJSONNode(x), true);
- return pos;
- }
-
- JSONNode::reverse_iterator JSONNode::insertRFF(reverse_iterator pos, JSONNode ** const _start, JSONNode ** const _end){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
- JSON_ASSERT_UNIQUE("insert RFF");
- JSON_ASSERT_SAFE(pos <= rend(), JSON_TEXT("insert out of range"), return rend(););
- JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin(););
- const size_t num = _end - _start;
- json_auto<JSONNode *> mem(num);
- JSONNode ** runner = mem.ptr + num;
- for (JSONNode ** po = _start; po < _end; ++po){ //fill it backwards
- *(--runner) = newJSONNode(*(*po) JSON_MUTEX_COPY2);
- }
- internal -> Children.insert(++pos.it, mem.ptr, num);
- return pos - num + 1;
- }
-
- JSONNode::iterator JSONNode::insertFRR(json_iterator pos, JSONNode ** const _start, JSONNode ** const _end){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
- JSON_ASSERT_UNIQUE("insert FRR");
- JSON_ASSERT_SAFE(pos <= end(), JSON_TEXT("insert out of range"), return end(););
- JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of range"), return begin(););
- const size_t num = _start - _end;
- json_auto<JSONNode *> mem(num);
- JSONNode ** runner = mem.ptr;
- for (JSONNode ** po = _start; po > _end; --po){
- *runner++=newJSONNode(*(*po) JSON_MUTEX_COPY2);
- }
- internal -> Children.insert(pos.it, mem.ptr, num);
- return pos;
- }
-
- JSONNode::reverse_iterator JSONNode::insertRRR(reverse_iterator pos, JSONNode ** const _start, JSONNode ** const _end){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
- JSON_ASSERT_UNIQUE("insert RRR");
- JSON_ASSERT_SAFE(pos <= rend(), JSON_TEXT("insert out of range"), return rend(););
- JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin(););
- const size_t num = _start - _end;
- json_auto<JSONNode *> mem(num);
- JSONNode ** runner = mem.ptr;
- for (JSONNode ** po = _start; po > _end; --po){
- *runner++=newJSONNode(*(*po) JSON_MUTEX_COPY2);
- }
- internal -> Children.insert(++pos.it, mem.ptr, num);
- return pos - num + 1;
- }
-#endif
-
-#endif
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "..\..\core\commonheaders.h"
+
+#include "JSONNode.h"
+
+#ifdef JSON_ITERATORS
+ #ifdef JSON_REF_COUNT
+ #define JSON_ASSERT_UNIQUE(x) JSON_ASSERT(internal -> refcount == 1, json_string(JSON_TEXT(x)) + JSON_TEXT(" in non single reference"))
+ #else
+ #define JSON_ASSERT_UNIQUE(x) (void)0
+ #endif
+
+ #ifdef JSON_MUTEX_CALLBACKS
+ #define JSON_MUTEX_COPY2 ,internal -> mylock
+ #else
+ #define JSON_MUTEX_COPY2
+ #endif
+
+JSONNode::json_iterator JSONNode::find(const json_string & name_t){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node"));
+ makeUniqueInternal();
+ if (JSONNode ** res = internal -> at(name_t)) {
+ return ptr_to_json_iterator(res);
+ }
+ return end();
+}
+
+#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
+ JSONNode::json_iterator JSONNode::find_nocase(const json_string & name_t){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node"));
+ makeUniqueInternal();
+ if (JSONNode ** res = internal -> at_nocase(name_t)) {
+ return ptr_to_json_iterator(res);
+ }
+ return end();
+ }
+#endif
+
+JSONNode::json_iterator JSONNode::erase(json_iterator pos){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
+ JSON_ASSERT_UNIQUE("erase 1");
+ JSON_ASSERT_SAFE(pos < end(), JSON_TEXT("erase out of range"), return end(););
+ JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("erase out of range"), return begin(););
+ deleteJSONNode(*(json_iterator_ptr(pos)));
+ internal -> Children.erase(json_iterator_ptr(pos));
+ return (empty()) ? end() : pos;
+}
+
+JSONNode::json_iterator JSONNode::erase(json_iterator _start, const json_iterator & _end){
+ if (_start == _end) return _start;
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
+ JSON_ASSERT_UNIQUE("erase 3");
+ JSON_ASSERT_SAFE(_start <= end(), JSON_TEXT("erase out of lo range"), return end(););
+ JSON_ASSERT_SAFE(_end <= end(), JSON_TEXT("erase out of hi range"), return end(););
+ JSON_ASSERT_SAFE(_start >= begin(), JSON_TEXT("erase out of lo range"), return begin(););
+ JSON_ASSERT_SAFE(_end >= begin(), JSON_TEXT("erase out of hi range"), return begin(););
+ for (JSONNode ** pos = json_iterator_ptr(_start); pos < json_iterator_ptr(_end); ++pos){
+ deleteJSONNode(*pos);
+ }
+
+ internal -> Children.erase(json_iterator_ptr(_start), json_iterator_ptr(_end) - json_iterator_ptr(_start));
+ return (empty()) ? end() : _start;
+}
+
+#ifdef JSON_LIBRARY
+JSONNode::json_iterator JSONNode::insert(json_iterator pos, JSONNode * x){
+#else
+JSONNode::json_iterator JSONNode::insert(json_iterator pos, const JSONNode & x){
+#endif
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
+ JSON_ASSERT_UNIQUE("insert 1");
+ if (json_iterator_ptr(pos) >= internal -> Children.end()) {
+ internal -> push_back(x);
+ return end() - 1;
+ }
+ JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of lo range"), return begin(););
+ #ifdef JSON_LIBRARY
+ internal -> Children.insert(json_iterator_ptr(pos), x);
+ #else
+ internal -> Children.insert(json_iterator_ptr(pos), newJSONNode(x));
+ #endif
+ return pos;
+}
+
+JSONNode::json_iterator JSONNode::insertFFF(json_iterator pos, JSONNode ** const _start, JSONNode ** const _end){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
+ JSON_ASSERT_UNIQUE("insertFFF");
+ JSON_ASSERT_SAFE(pos <= end(), JSON_TEXT("insert out of high range"), return end(););
+ JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of low range"), return begin(););
+ const size_t num = _end - _start;
+ json_auto<JSONNode *> mem(num);
+ JSONNode ** runner = mem.ptr;
+ for (JSONNode ** po = _start; po < _end; ++po){
+ *runner++=newJSONNode(*(*po) JSON_MUTEX_COPY2);
+ }
+ internal -> Children.insert(json_iterator_ptr(pos), mem.ptr, num);
+ return pos;
+}
+
+#ifndef JSON_LIBRARY
+ JSONNode::const_iterator JSONNode::find(const json_string & name_t) const {
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node"));
+ if (JSONNode ** res = internal -> at(name_t)) {
+ return JSONNode::const_iterator(res);
+ }
+ return JSONNode::const_iterator(internal -> end());
+ }
+
+ #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
+ JSONNode::const_iterator JSONNode::find_nocase(const json_string & name_t) const {
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node"));
+ if (JSONNode ** res = internal -> at_nocase(name_t)) {
+ return JSONNode::const_iterator(res);
+ }
+ return JSONNode::const_iterator(internal -> end());
+ }
+ #endif
+
+ JSONNode::reverse_iterator JSONNode::erase(reverse_iterator pos){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
+ JSON_ASSERT_UNIQUE("erase 2");
+ JSON_ASSERT_SAFE(pos < rend(), JSON_TEXT("erase out of range"), return rend(););
+ JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("erase out of range"), return rbegin(););
+ deleteJSONNode(*(pos.it));
+ internal -> Children.erase(pos.it);
+ return (empty()) ? rend() : pos + 1;
+ }
+
+ JSONNode::reverse_iterator JSONNode::erase(reverse_iterator _start, const reverse_iterator & _end){
+ if (_start == _end) return _start;
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
+ JSON_ASSERT_UNIQUE("erase 4");
+ JSON_ASSERT_SAFE(_start <= rend(), JSON_TEXT("erase out of lo range"), return rend(););
+ JSON_ASSERT_SAFE(_end <= rend(), JSON_TEXT("erase out of hi range"), return rend(););
+ JSON_ASSERT_SAFE(_start >= rbegin(), JSON_TEXT("erase out of lo range"), return rbegin(););
+ JSON_ASSERT_SAFE(_end >= rbegin(), JSON_TEXT("erase out of hi range"), return rbegin(););
+ for (JSONNode ** pos = _start.it; pos > _end.it; --pos){
+ deleteJSONNode(*pos);
+ }
+ const size_t num = _start.it - _end.it;
+ internal -> Children.erase(_end.it + 1, num, _start.it);
+ return (empty()) ? rend() : _start + num;
+ }
+
+ JSONNode::reverse_iterator JSONNode::insert(reverse_iterator pos, const JSONNode & x){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
+ JSON_ASSERT_UNIQUE("insert 1");
+ if (pos.it < internal -> Children.begin()) {
+ internal -> push_front(x);
+ return rend() - 1;
+ }
+ JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin(););
+ internal -> Children.insert(++pos.it, newJSONNode(x), true);
+ return pos;
+ }
+
+ JSONNode::reverse_iterator JSONNode::insertRFF(reverse_iterator pos, JSONNode ** const _start, JSONNode ** const _end){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
+ JSON_ASSERT_UNIQUE("insert RFF");
+ JSON_ASSERT_SAFE(pos <= rend(), JSON_TEXT("insert out of range"), return rend(););
+ JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin(););
+ const size_t num = _end - _start;
+ json_auto<JSONNode *> mem(num);
+ JSONNode ** runner = mem.ptr + num;
+ for (JSONNode ** po = _start; po < _end; ++po){ //fill it backwards
+ *(--runner) = newJSONNode(*(*po) JSON_MUTEX_COPY2);
+ }
+ internal -> Children.insert(++pos.it, mem.ptr, num);
+ return pos - num + 1;
+ }
+
+ JSONNode::iterator JSONNode::insertFRR(json_iterator pos, JSONNode ** const _start, JSONNode ** const _end){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
+ JSON_ASSERT_UNIQUE("insert FRR");
+ JSON_ASSERT_SAFE(pos <= end(), JSON_TEXT("insert out of range"), return end(););
+ JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of range"), return begin(););
+ const size_t num = _start - _end;
+ json_auto<JSONNode *> mem(num);
+ JSONNode ** runner = mem.ptr;
+ for (JSONNode ** po = _start; po > _end; --po){
+ *runner++=newJSONNode(*(*po) JSON_MUTEX_COPY2);
+ }
+ internal -> Children.insert(pos.it, mem.ptr, num);
+ return pos;
+ }
+
+ JSONNode::reverse_iterator JSONNode::insertRRR(reverse_iterator pos, JSONNode ** const _start, JSONNode ** const _end){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node"));
+ JSON_ASSERT_UNIQUE("insert RRR");
+ JSON_ASSERT_SAFE(pos <= rend(), JSON_TEXT("insert out of range"), return rend(););
+ JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin(););
+ const size_t num = _start - _end;
+ json_auto<JSONNode *> mem(num);
+ JSONNode ** runner = mem.ptr;
+ for (JSONNode ** po = _start; po > _end; --po){
+ *runner++=newJSONNode(*(*po) JSON_MUTEX_COPY2);
+ }
+ internal -> Children.insert(++pos.it, mem.ptr, num);
+ return pos - num + 1;
+ }
+#endif
+
+#endif
diff --git a/src/modules/json/JSONMemory.cpp b/src/modules/json/JSONMemory.cpp
index 4c2c851022..61b2eef567 100644
--- a/src/modules/json/JSONMemory.cpp
+++ b/src/modules/json/JSONMemory.cpp
@@ -1,106 +1,106 @@
-/*
-
-Miranda IM: the free IM client for Microsoft* Windows*
-
-Copyright 2000-2009 Miranda ICQ/IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-
-#include "JSONMemory.h"
-#include "JSONNode.h"
-
-#ifdef JSON_MEMORY_MANAGE
- void auto_expand::purge(void){
- for(std::map<void *, void *>::iterator i = mymap.begin(), en = mymap.end(); i != en; ++i){
- #if defined(JSON_DEBUG) || defined(JSON_SAFE)
- void * temp = (void*)i -> first; //because its pass by reference
- libjson_free<void>(temp);
- #else
- libjson_free<void>((void*)i -> first);
- #endif
- }
- }
-
- void auto_expand_node::purge(void){
- for(std::map<void *, JSONNode *>::iterator i = mymap.begin(), en = mymap.end(); i != en; ++i){
- JSONNode::deleteJSONNode((JSONNode *)i -> second);
- }
- }
-#endif
-
-#ifdef JSON_MEMORY_CALLBACKS
-
-json_malloc_t mymalloc = 0;
-json_realloc_t myrealloc = 0;
-json_free_t myfree = 0;
-
-void * JSONMemory::json_malloc(size_t siz){
- if (mymalloc){
- #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
- void * result = mymalloc(siz);
- JSON_ASSERT(result, JSON_TEXT("out of memory"));
- return result;
- #else
- return mymalloc((unsigned long)siz);
- #endif
- }
- #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
- void * result = malloc(siz);
- JSON_ASSERT(result, JSON_TEXT("out of memory"));
- return result;
- #else
- return malloc(siz);
- #endif
-}
-
-void * JSONMemory::json_realloc(void * ptr, size_t siz){
- if (myrealloc){
- #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
- void * result = myrealloc(ptr, siz);
- JSON_ASSERT(result, JSON_TEXT("out of memory"));
- return result;
- #else
- return myrealloc(ptr, (unsigned long)siz);
- #endif
- }
- #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
- void * result = realloc(ptr, siz);
- JSON_ASSERT(result, JSON_TEXT("out of memory"));
- return result;
- #else
- return realloc(ptr, siz);
- #endif
-}
-
-void JSONMemory::json_free(void * ptr){
- if (myfree){
- myfree(ptr);
- } else {
- free(ptr);
- }
-}
-
-void JSONMemory::registerMemoryCallbacks(json_malloc_t mal, json_realloc_t real, json_free_t fre){
- mymalloc = mal;
- myrealloc = real;
- myfree = fre;
-}
-
-#endif
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "..\..\core\commonheaders.h"
+
+#include "JSONMemory.h"
+#include "JSONNode.h"
+
+#ifdef JSON_MEMORY_MANAGE
+ void auto_expand::purge(void){
+ for(std::map<void *, void *>::iterator i = mymap.begin(), en = mymap.end(); i != en; ++i){
+ #if defined(JSON_DEBUG) || defined(JSON_SAFE)
+ void * temp = (void*)i -> first; //because its pass by reference
+ libjson_free<void>(temp);
+ #else
+ libjson_free<void>((void*)i -> first);
+ #endif
+ }
+ }
+
+ void auto_expand_node::purge(void){
+ for(std::map<void *, JSONNode *>::iterator i = mymap.begin(), en = mymap.end(); i != en; ++i){
+ JSONNode::deleteJSONNode((JSONNode *)i -> second);
+ }
+ }
+#endif
+
+#ifdef JSON_MEMORY_CALLBACKS
+
+json_malloc_t mymalloc = 0;
+json_realloc_t myrealloc = 0;
+json_free_t myfree = 0;
+
+void * JSONMemory::json_malloc(size_t siz){
+ if (mymalloc){
+ #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
+ void * result = mymalloc(siz);
+ JSON_ASSERT(result, JSON_TEXT("out of memory"));
+ return result;
+ #else
+ return mymalloc((unsigned long)siz);
+ #endif
+ }
+ #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
+ void * result = malloc(siz);
+ JSON_ASSERT(result, JSON_TEXT("out of memory"));
+ return result;
+ #else
+ return malloc(siz);
+ #endif
+}
+
+void * JSONMemory::json_realloc(void * ptr, size_t siz){
+ if (myrealloc){
+ #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
+ void * result = myrealloc(ptr, siz);
+ JSON_ASSERT(result, JSON_TEXT("out of memory"));
+ return result;
+ #else
+ return myrealloc(ptr, (unsigned long)siz);
+ #endif
+ }
+ #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
+ void * result = realloc(ptr, siz);
+ JSON_ASSERT(result, JSON_TEXT("out of memory"));
+ return result;
+ #else
+ return realloc(ptr, siz);
+ #endif
+}
+
+void JSONMemory::json_free(void * ptr){
+ if (myfree){
+ myfree(ptr);
+ } else {
+ free(ptr);
+ }
+}
+
+void JSONMemory::registerMemoryCallbacks(json_malloc_t mal, json_realloc_t real, json_free_t fre){
+ mymalloc = mal;
+ myrealloc = real;
+ myfree = fre;
+}
+
+#endif
diff --git a/src/modules/json/JSONMemory.h b/src/modules/json/JSONMemory.h
index 899d73b6fc..32e8c3f4ef 100644
--- a/src/modules/json/JSONMemory.h
+++ b/src/modules/json/JSONMemory.h
@@ -1,134 +1,134 @@
-#ifndef JSON_MEMORY_H
-#define JSON_MEMORY_H
-
-#include <cstdlib> //for malloc, realloc, and free
-#include <cstring> //for memmove
-#include "JSONOptions.h"
-#include "JSONDebug.h"
-
-#if defined(JSON_DEBUG) || defined(JSON_SAFE)
- #define JSON_FREE_PASSTYPE &
-#else
- #define JSON_FREE_PASSTYPE
-#endif
-
-#ifdef JSON_MEMORY_CALLBACKS
- class JSONMemory {
- public:
- static void * json_malloc(size_t siz);
- static void * json_realloc(void * ptr, size_t siz);
- static void json_free(void * ptr);
- static void registerMemoryCallbacks(json_malloc_t mal, json_realloc_t real, json_free_t fre);
- };
-
- template <typename T> static inline T * json_malloc(size_t count){
- return (T *)JSONMemory::json_malloc(sizeof(T) * count);
- }
-
- template <typename T> static inline T * json_realloc(T * ptr, size_t count){
- return (T *)JSONMemory::json_realloc(ptr, sizeof(T) * count);
- }
-
- template <typename T> static inline void libjson_free(T * JSON_FREE_PASSTYPE ptr){
- JSONMemory::json_free(ptr);
- #if defined(JSON_DEBUG) || defined(JSON_SAFE) //in debug or safe mode, set the pointer to 0 so that it can't be used again
- ptr = 0;
- #endif
- }
-#else
- template <typename T>
- static inline T * json_malloc(size_t count){
- #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
- void * result = malloc(count * sizeof(T));
- JSON_ASSERT(result, JSON_TEXT("out of memory"));
- #ifdef JSON_NULL_MEMORY
- memset(result, '\0', count * sizeof(T));
- #endif
- return (T *)result;
- #else
- return (T *)malloc(count * sizeof(T));
- #endif
- }
-
- template <typename T>
- static inline void libjson_free(T * JSON_FREE_PASSTYPE ptr){
- free(ptr);
- #if defined(JSON_DEBUG) || defined(JSON_SAFE) //in debug or safe mode, set the pointer to 0 so that it can't be used again
- ptr = 0;
- #endif
- }
-
- template <typename T>
- static inline T * json_realloc(T * ptr, size_t count){
- #ifdef JSON_DEBUG //in debug mode, check the results of realloc to be sure it was successful
- void * result = realloc(ptr, count * sizeof(T));
- JSON_ASSERT(result, JSON_TEXT("out of memory"));
- #ifdef JSON_NULL_MEMORY
- memset(result, '\0', count * sizeof(T));
- #endif
- return (T *)result;
- #else
- return (T *)realloc(ptr, count * sizeof(T));
- #endif
- }
-#endif
-
-#ifdef JSON_MEMORY_MANAGE
- #include <map>
- class JSONNode;
- struct auto_expand {
- auto_expand(void) : mymap() {}
- ~auto_expand(void){ purge(); }
- void purge(void);
- inline void clear(void){ purge(); mymap.clear(); }
- inline void * insert(void * ptr){ mymap[ptr] = ptr; return ptr; }
- inline void remove(void * ptr){
- std::map<void *, void *>::iterator i = mymap.find(ptr);
- JSON_ASSERT(i != mymap.end(), JSON_TEXT("Removing a non-managed item"));
- mymap.erase(i);
- }
- std::map<void *, void *> mymap;
- };
-
- struct auto_expand_node {
- auto_expand_node(void) : mymap() {}
- ~auto_expand_node(void){ purge(); }
- void purge(void);
- inline void clear(void){ purge(); mymap.clear(); }
- inline JSONNode * insert(JSONNode * ptr){ mymap[ptr] = ptr; return ptr; }
- inline void remove(void * ptr){
- std::map<void *, JSONNode *>::iterator i = mymap.find(ptr);
- if(i != mymap.end()) mymap.erase(i);
- }
- std::map<void *, JSONNode *> mymap;
- };
-#endif
-
-//The C++ way, use an self-deleting pointer and let the optimizer decide when it gets destroyed
-template <typename T>
-class json_auto {
- public:
- json_auto(void) : ptr(0){}
- json_auto(size_t count) : ptr(json_malloc<T>(count)) {}
- ~json_auto(void){
- libjson_free<T>(ptr);
- }
- void set(T * p){
- ptr = p;
- }
- T * ptr;
- private:
- json_auto(const json_auto &);
- json_auto & operator = (const json_auto &);
-};
-
-//Clears a string, if required, frees the memory
-static inline void clearString(json_string & str){
- #ifdef JSON_LESS_MEMORY
- json_string().swap(str);
- #else
- str.clear();
- #endif
-}
-
-#endif
+#ifndef JSON_MEMORY_H
+#define JSON_MEMORY_H
+
+#include <cstdlib> //for malloc, realloc, and free
+#include <cstring> //for memmove
+#include "JSONOptions.h"
+#include "JSONDebug.h"
+
+#if defined(JSON_DEBUG) || defined(JSON_SAFE)
+ #define JSON_FREE_PASSTYPE &
+#else
+ #define JSON_FREE_PASSTYPE
+#endif
+
+#ifdef JSON_MEMORY_CALLBACKS
+ class JSONMemory {
+ public:
+ static void * json_malloc(size_t siz);
+ static void * json_realloc(void * ptr, size_t siz);
+ static void json_free(void * ptr);
+ static void registerMemoryCallbacks(json_malloc_t mal, json_realloc_t real, json_free_t fre);
+ };
+
+ template <typename T> static inline T * json_malloc(size_t count){
+ return (T *)JSONMemory::json_malloc(sizeof(T) * count);
+ }
+
+ template <typename T> static inline T * json_realloc(T * ptr, size_t count){
+ return (T *)JSONMemory::json_realloc(ptr, sizeof(T) * count);
+ }
+
+ template <typename T> static inline void libjson_free(T * JSON_FREE_PASSTYPE ptr){
+ JSONMemory::json_free(ptr);
+ #if defined(JSON_DEBUG) || defined(JSON_SAFE) //in debug or safe mode, set the pointer to 0 so that it can't be used again
+ ptr = 0;
+ #endif
+ }
+#else
+ template <typename T>
+ static inline T * json_malloc(size_t count){
+ #ifdef JSON_DEBUG //in debug mode, see if the malloc was successful
+ void * result = malloc(count * sizeof(T));
+ JSON_ASSERT(result, JSON_TEXT("out of memory"));
+ #ifdef JSON_NULL_MEMORY
+ memset(result, '\0', count * sizeof(T));
+ #endif
+ return (T *)result;
+ #else
+ return (T *)malloc(count * sizeof(T));
+ #endif
+ }
+
+ template <typename T>
+ static inline void libjson_free(T * JSON_FREE_PASSTYPE ptr){
+ free(ptr);
+ #if defined(JSON_DEBUG) || defined(JSON_SAFE) //in debug or safe mode, set the pointer to 0 so that it can't be used again
+ ptr = 0;
+ #endif
+ }
+
+ template <typename T>
+ static inline T * json_realloc(T * ptr, size_t count){
+ #ifdef JSON_DEBUG //in debug mode, check the results of realloc to be sure it was successful
+ void * result = realloc(ptr, count * sizeof(T));
+ JSON_ASSERT(result, JSON_TEXT("out of memory"));
+ #ifdef JSON_NULL_MEMORY
+ memset(result, '\0', count * sizeof(T));
+ #endif
+ return (T *)result;
+ #else
+ return (T *)realloc(ptr, count * sizeof(T));
+ #endif
+ }
+#endif
+
+#ifdef JSON_MEMORY_MANAGE
+ #include <map>
+ class JSONNode;
+ struct auto_expand {
+ auto_expand(void) : mymap() {}
+ ~auto_expand(void){ purge(); }
+ void purge(void);
+ inline void clear(void){ purge(); mymap.clear(); }
+ inline void * insert(void * ptr){ mymap[ptr] = ptr; return ptr; }
+ inline void remove(void * ptr){
+ std::map<void *, void *>::iterator i = mymap.find(ptr);
+ JSON_ASSERT(i != mymap.end(), JSON_TEXT("Removing a non-managed item"));
+ mymap.erase(i);
+ }
+ std::map<void *, void *> mymap;
+ };
+
+ struct auto_expand_node {
+ auto_expand_node(void) : mymap() {}
+ ~auto_expand_node(void){ purge(); }
+ void purge(void);
+ inline void clear(void){ purge(); mymap.clear(); }
+ inline JSONNode * insert(JSONNode * ptr){ mymap[ptr] = ptr; return ptr; }
+ inline void remove(void * ptr){
+ std::map<void *, JSONNode *>::iterator i = mymap.find(ptr);
+ if(i != mymap.end()) mymap.erase(i);
+ }
+ std::map<void *, JSONNode *> mymap;
+ };
+#endif
+
+//The C++ way, use an self-deleting pointer and let the optimizer decide when it gets destroyed
+template <typename T>
+class json_auto {
+ public:
+ json_auto(void) : ptr(0){}
+ json_auto(size_t count) : ptr(json_malloc<T>(count)) {}
+ ~json_auto(void){
+ libjson_free<T>(ptr);
+ }
+ void set(T * p){
+ ptr = p;
+ }
+ T * ptr;
+ private:
+ json_auto(const json_auto &);
+ json_auto & operator = (const json_auto &);
+};
+
+//Clears a string, if required, frees the memory
+static inline void clearString(json_string & str){
+ #ifdef JSON_LESS_MEMORY
+ json_string().swap(str);
+ #else
+ str.clear();
+ #endif
+}
+
+#endif
diff --git a/src/modules/json/JSONNode.cpp b/src/modules/json/JSONNode.cpp
index 8e4ca34678..b53bf2381f 100644
--- a/src/modules/json/JSONNode.cpp
+++ b/src/modules/json/JSONNode.cpp
@@ -1,311 +1,311 @@
-/*
-
-Miranda IM: the free IM client for Microsoft* Windows*
-
-Copyright 2000-2009 Miranda ICQ/IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-
-#include "JSONNode.h"
-
-#ifdef JSON_UNIT_TEST
- int allocCount = 0;
- int deallocCount = 0;
- int internalAllocCount = 0;
- int internalDeallocCount = 0;
- int JSONNode::getNodeAllocationCount(void){ return allocCount; }
- int JSONNode::getNodeDeallocationCount(void){ return deallocCount; }
- int JSONNode::getInternalAllocationCount(void){ return internalAllocCount; }
- int JSONNode::getInternalDeallocationCount(void){ return internalDeallocCount; }
- void JSONNode::incAllocCount(void){ ++allocCount; }
- void JSONNode::decAllocCount(void){ ++deallocCount; }
- void JSONNode::incinternalAllocCount(void){ ++internalAllocCount; }
- void JSONNode::decinternalAllocCount(void){ ++internalDeallocCount; }
-#endif
-
-#define IMPLEMENT_CTOR(type)\
- JSONNode::JSONNode(const json_string & name_t, type value_t) : internal(internalJSONNode::newInternal()) {\
- internal -> Set(value_t);\
- internal -> setname(name_t);\
- incAllocCount();\
- }
-IMPLEMENT_FOR_ALL_TYPES(IMPLEMENT_CTOR)
-
-#ifndef JSON_LIBRARY
- JSONNode::JSONNode(const json_string & name_t, const json_char * value_t) : internal(internalJSONNode::newInternal()) {
- internal -> Set(json_string(value_t));
- internal -> setname(name_t);
- incAllocCount();
- }
-#endif
-
-JSONNode JSONNode::as_node(void) const {
- 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){
- JSONNode res = JSONNode(JSON_NODE);
- res.set_mutex(internal -> mylock);
- return res;
- }
- #endif
- return JSONNode(JSON_NODE);
-}
-
-JSONNode JSONNode::as_array(void) const {
- 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) -> set_name(JSON_TEXT(""));
- }
- return res;
- }
- #ifdef JSON_MUTEX_CALLBACKS
- if (internal -> mylock){
- JSONNode res = JSONNode(JSON_ARRAY);
- res.set_mutex(internal -> mylock);
- return res;
- }
- #endif
- return JSONNode(JSON_ARRAY);
-}
-
-void JSONNode::cast(char newtype){
- 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"));
-}
-
-//different just to supress the warning
-#ifdef JSON_REF_COUNT
-void JSONNode::merge(JSONNode & other){
-#else
-void JSONNode::merge(JSONNode &) {
-#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_CHECK_INTERNAL();
- if (internal == other -> internal) return;
- *other = *this;
- }
-
- //different just to supress the warning
- void JSONNode::merge(unsigned int num, ...) {
-#else
- void JSONNode::merge(unsigned int, ...) {
-#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_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_CHECK_INTERNAL();
- if (pos >= internal -> size()) {
- JSON_FAIL(JSON_TEXT("at() out of bounds"));
- throw std::out_of_range(EMPTY_STRING2);
- }
- return (*this)[pos];
-}
-
-const JSONNode & JSONNode::at(json_index_t pos) const {
- JSON_CHECK_INTERNAL();
- if (pos >= internal -> size()) {
- JSON_FAIL(JSON_TEXT("at() const out of bounds"));
- throw std::out_of_range(EMPTY_STRING2);
- }
- return (*this)[pos];
-}
-
-JSONNode & JSONNode::operator[](json_index_t pos){
- 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_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_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("at a non-iteratable node"));
- 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);
- throw std::out_of_range(EMPTY_STRING2);
-}
-
-const JSONNode & JSONNode::at(const json_string & name_t) const {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("at a non-iteratable node"));
- 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);
- throw std::out_of_range(EMPTY_STRING2);
-}
-
-#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
- JSONNode & JSONNode::at_nocase(const json_string & name_t){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("at a non-iteratable node"));
- 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);
- throw std::out_of_range(EMPTY_STRING2);
- }
-
- const JSONNode & JSONNode::at_nocase(const json_string & name_t) const {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("at a non-iteratable node"));
- 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);
- throw std::out_of_range(EMPTY_STRING2);
- }
-#endif
-
-#ifndef JSON_LIBRARY
- struct auto_delete {
- public:
- auto_delete(JSONNode * node) : mynode(node){};
- ~auto_delete(void){ 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_CHECK_INTERNAL();
- if (pos >= internal -> size()) {
- JSON_FAIL(JSON_TEXT("pop_back out of bounds"));
- throw std::out_of_range(EMPTY_STRING2);
- }
- 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_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("popping a non-iteratable node"));
- #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);
- throw std::out_of_range(EMPTY_STRING2);
- #endif
-}
-
-#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
- JSONNode JSON_PTR_LIB JSONNode::pop_back_nocase(const json_string & name_t){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("popping a non-iteratable node"));
- #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);
- throw std::out_of_range(EMPTY_STRING2);
- #endif
- }
-#endif
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "..\..\core\commonheaders.h"
+
+#include "JSONNode.h"
+
+#ifdef JSON_UNIT_TEST
+ int allocCount = 0;
+ int deallocCount = 0;
+ int internalAllocCount = 0;
+ int internalDeallocCount = 0;
+ int JSONNode::getNodeAllocationCount(void){ return allocCount; }
+ int JSONNode::getNodeDeallocationCount(void){ return deallocCount; }
+ int JSONNode::getInternalAllocationCount(void){ return internalAllocCount; }
+ int JSONNode::getInternalDeallocationCount(void){ return internalDeallocCount; }
+ void JSONNode::incAllocCount(void){ ++allocCount; }
+ void JSONNode::decAllocCount(void){ ++deallocCount; }
+ void JSONNode::incinternalAllocCount(void){ ++internalAllocCount; }
+ void JSONNode::decinternalAllocCount(void){ ++internalDeallocCount; }
+#endif
+
+#define IMPLEMENT_CTOR(type)\
+ JSONNode::JSONNode(const json_string & name_t, type value_t) : internal(internalJSONNode::newInternal()) {\
+ internal -> Set(value_t);\
+ internal -> setname(name_t);\
+ incAllocCount();\
+ }
+IMPLEMENT_FOR_ALL_TYPES(IMPLEMENT_CTOR)
+
+#ifndef JSON_LIBRARY
+ JSONNode::JSONNode(const json_string & name_t, const json_char * value_t) : internal(internalJSONNode::newInternal()) {
+ internal -> Set(json_string(value_t));
+ internal -> setname(name_t);
+ incAllocCount();
+ }
+#endif
+
+JSONNode JSONNode::as_node(void) const {
+ 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){
+ JSONNode res = JSONNode(JSON_NODE);
+ res.set_mutex(internal -> mylock);
+ return res;
+ }
+ #endif
+ return JSONNode(JSON_NODE);
+}
+
+JSONNode JSONNode::as_array(void) const {
+ 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) -> set_name(JSON_TEXT(""));
+ }
+ return res;
+ }
+ #ifdef JSON_MUTEX_CALLBACKS
+ if (internal -> mylock){
+ JSONNode res = JSONNode(JSON_ARRAY);
+ res.set_mutex(internal -> mylock);
+ return res;
+ }
+ #endif
+ return JSONNode(JSON_ARRAY);
+}
+
+void JSONNode::cast(char newtype){
+ 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"));
+}
+
+//different just to supress the warning
+#ifdef JSON_REF_COUNT
+void JSONNode::merge(JSONNode & other){
+#else
+void JSONNode::merge(JSONNode &) {
+#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_CHECK_INTERNAL();
+ if (internal == other -> internal) return;
+ *other = *this;
+ }
+
+ //different just to supress the warning
+ void JSONNode::merge(unsigned int num, ...) {
+#else
+ void JSONNode::merge(unsigned int, ...) {
+#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_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_CHECK_INTERNAL();
+ if (pos >= internal -> size()) {
+ JSON_FAIL(JSON_TEXT("at() out of bounds"));
+ throw std::out_of_range(EMPTY_STRING2);
+ }
+ return (*this)[pos];
+}
+
+const JSONNode & JSONNode::at(json_index_t pos) const {
+ JSON_CHECK_INTERNAL();
+ if (pos >= internal -> size()) {
+ JSON_FAIL(JSON_TEXT("at() const out of bounds"));
+ throw std::out_of_range(EMPTY_STRING2);
+ }
+ return (*this)[pos];
+}
+
+JSONNode & JSONNode::operator[](json_index_t pos){
+ 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_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_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("at a non-iteratable node"));
+ 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);
+ throw std::out_of_range(EMPTY_STRING2);
+}
+
+const JSONNode & JSONNode::at(const json_string & name_t) const {
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("at a non-iteratable node"));
+ 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);
+ throw std::out_of_range(EMPTY_STRING2);
+}
+
+#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
+ JSONNode & JSONNode::at_nocase(const json_string & name_t){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("at a non-iteratable node"));
+ 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);
+ throw std::out_of_range(EMPTY_STRING2);
+ }
+
+ const JSONNode & JSONNode::at_nocase(const json_string & name_t) const {
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("at a non-iteratable node"));
+ 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);
+ throw std::out_of_range(EMPTY_STRING2);
+ }
+#endif
+
+#ifndef JSON_LIBRARY
+ struct auto_delete {
+ public:
+ auto_delete(JSONNode * node) : mynode(node){};
+ ~auto_delete(void){ 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_CHECK_INTERNAL();
+ if (pos >= internal -> size()) {
+ JSON_FAIL(JSON_TEXT("pop_back out of bounds"));
+ throw std::out_of_range(EMPTY_STRING2);
+ }
+ 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_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("popping a non-iteratable node"));
+ #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);
+ throw std::out_of_range(EMPTY_STRING2);
+ #endif
+}
+
+#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
+ JSONNode JSON_PTR_LIB JSONNode::pop_back_nocase(const json_string & name_t){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("popping a non-iteratable node"));
+ #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);
+ throw std::out_of_range(EMPTY_STRING2);
+ #endif
+ }
+#endif
diff --git a/src/modules/json/JSONNode.h b/src/modules/json/JSONNode.h
index 3552f9f73c..051475e704 100644
--- a/src/modules/json/JSONNode.h
+++ b/src/modules/json/JSONNode.h
@@ -1,923 +1,923 @@
-#ifndef JSONNODE_H
-#define JSONNODE_H
-
-#include "JSONDefs.h" //for string type
-#include "internalJSONNode.h" //internal structure for json value
-#include <stdexcept>
-#include <cstdarg> //for the ... parameter
-
-#ifdef JSON_BINARY
- #include "JSON_Base64.h"
-#endif
-
-#ifndef JSON_REF_COUNT
- #define makeUniqueInternal() (void)0
-#endif
-
-#define JSON_CHECK_INTERNAL() JSON_ASSERT(internal, JSON_TEXT("no internal"))
-
-#ifdef JSON_MUTEX_CALLBACKS
- #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 value_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
- void push_back(const JSONNode & node);
- #endif
- void reserve(json_index_t size);
- 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
-
- DECLARE_FOR_ALL_TYPES(JSONNode & operator = )
- JSONNode & operator = (const JSONNode &);
-
- DECLARE_FOR_ALL_TYPES_CONST(bool operator ==)
- DECLARE_FOR_ALL_TYPES_CONST(bool operator !=)
-
-
- void nullify(void);
- void swap(JSONNode & other);
- void merge(JSONNode & other);
- void merge(unsigned int num, ...);
- JSONNode duplicate(void) const;
- void cast(char newtype);
-
-
- //iterator
- #ifdef JSON_ITERATORS
- #ifndef JSON_LIBRARY
- #define json_iterator_ptr(iter) iter.it
- #define ptr_to_json_iterator(iter) json_iterator(iter)
- struct iterator {
- inline iterator& operator ++(void){ ++it; return *this; }
- inline iterator& operator --(void){ --it; return *this; }
- inline iterator& operator +=(long i){ it += i; return *this; }
- inline iterator& operator -=(long i){ it -= i; return *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 { return *it[pos]; };
- inline JSONNode& operator *(void) const { return *(*it); }
- inline bool operator == (const iterator & other) const { return it == other.it; }
- inline bool operator != (const iterator & other) const { return it != other.it; }
- inline bool operator > (const iterator & other) const { return it > other.it; }
- inline bool operator >= (const iterator & other) const { return it >= other.it; }
- inline bool operator < (const iterator & other) const { return it < other.it; }
- inline bool operator <= (const iterator & other) const { 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;
-
- struct const_iterator {
- inline const_iterator& operator ++(void){ ++it; return *this; }
- inline const_iterator& operator --(void){ --it; return *this; }
- inline const_iterator& operator +=(long i){ it += i; 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) const { return const_cast<const JSONNode&>(*it[pos]); };
- inline const JSONNode& operator *(void) const { return const_cast<const JSONNode&>(*(*it)); }
- inline bool operator == (const const_iterator & other) const { return it == other.it; }
- inline bool operator != (const const_iterator & other) const { return it != other.it; }
- inline bool operator > (const const_iterator & other) const { return it > other.it; }
- inline bool operator >= (const const_iterator & other) const { return it >= other.it; }
- inline bool operator < (const const_iterator & other) const { return it < other.it; }
- inline bool operator <= (const const_iterator & other) const { return it <= other.it; }
- inline const_iterator & operator = (const const_iterator & orig){ it = orig.it; return *this; }
- const_iterator (const const_iterator & orig) : it(orig.it) {}
- private:
- JSONNode ** it;
- const_iterator(JSONNode ** starter) : it(starter) {}
- friend class JSONNode;
- };
- const_iterator begin(void) const;
- const_iterator end(void) const;
-
- struct reverse_iterator {
- inline reverse_iterator& operator ++(void){ --it; return *this; }
- inline reverse_iterator& operator --(void){ ++it; return *this; }
- inline reverse_iterator& operator +=(long i){ it -= i; return *this; }
- inline reverse_iterator& operator -=(long i){ it += i; return *this; }
- 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 { return *it[pos]; };
- inline JSONNode& operator *(void) const { return *(*it); }
- inline bool operator == (const reverse_iterator & other) const { return it == other.it; }
- inline bool operator != (const reverse_iterator & other) const { return it != other.it; }
- inline bool operator < (const reverse_iterator & other) const { return it > other.it; }
- inline bool operator <= (const reverse_iterator & other) const { return it >= other.it; }
- inline bool operator > (const reverse_iterator & other) const { return it < other.it; }
- inline bool operator >= (const reverse_iterator & other) 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);
-
- struct reverse_const_iterator {
- inline reverse_const_iterator& operator ++(void){ --it; return *this; }
- inline reverse_const_iterator& operator --(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) const {
- reverse_const_iterator result(*this);
- result.it -= i;
- return result;
- }
- inline reverse_const_iterator operator -(long i) const {
- reverse_const_iterator result(*this);
- result.it += i;
- return result;
- }
- inline const JSONNode& operator [](size_t pos) const { return const_cast<const JSONNode&>(*it[pos]); };
- inline const JSONNode& operator *(void) const { return const_cast<const JSONNode&>(*(*it)); }
- inline bool operator == (const reverse_const_iterator & other) const { return it == other.it; }
- inline bool operator != (const reverse_const_iterator & other) const { return it != other.it; }
- inline bool operator < (const reverse_const_iterator & other) const { return it > other.it; }
- inline bool operator <= (const reverse_const_iterator & other) const { return it >= other.it; }
- inline bool operator > (const reverse_const_iterator & other) const { return it < other.it; }
- inline bool operator >= (const reverse_const_iterator & other) const { return it <= other.it; }
- inline reverse_const_iterator & operator = (const reverse_const_iterator & orig){ it = orig.it; return *this; }
- reverse_const_iterator (const reverse_const_iterator & orig) : it(orig.it) {}
- private:
- JSONNode ** it;
- reverse_const_iterator(JSONNode ** starter) : it(starter) {}
- friend class JSONNode;
- };
- reverse_const_iterator rbegin(void) const;
- reverse_const_iterator rend(void) const;
-
- const_iterator find(const json_string & name_t) const;
- #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
- const_iterator find_nocase(const json_string & name_t) const;
- #endif
-
- reverse_iterator erase(reverse_iterator pos);
- reverse_iterator erase(reverse_iterator start, const reverse_iterator & end);
-
- iterator insert(iterator pos, const JSONNode & x);
- reverse_iterator insert(reverse_iterator pos, const JSONNode & x);
- iterator insert(iterator pos, const reverse_iterator & _start, const reverse_iterator & _end);
- reverse_iterator insert(reverse_iterator pos, const iterator & _start, const iterator & _end);
- reverse_iterator insert(reverse_iterator pos, const reverse_iterator & _start, const reverse_iterator & _end);
-
- json_iterator insert(json_iterator pos, const const_iterator & _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_const_iterator & _start, const reverse_const_iterator & _end);
- reverse_iterator insert(reverse_iterator pos, const reverse_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
-
- json_iterator begin(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
- json_iterator erase(json_iterator pos);
- json_iterator erase(json_iterator start, const json_iterator & end);
- json_iterator insert(json_iterator pos, const json_iterator & _start, const json_iterator & _end);
- #endif
-
-
- #ifdef JSON_MUTEX_CALLBACKS
- static void register_mutex_callbacks(json_mutex_callback_t lock, json_mutex_callback_t unlock, void * manager_lock);
- #ifdef JSON_MUTEX_MANAGE
- static void register_mutex_destructor(json_mutex_callback_t destroy);
- #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(&node), mythread(thread){
- mynode -> lock(mythread);
- }
- auto_lock(JSONNode * node, int thread) : mynode(node), 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
-
- #ifdef JSON_UNIT_TEST
- static int getNodeAllocationCount(void);
- 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
-
- #ifdef JSON_WRITER
- json_string write(void);
- json_string write_formatted(void);
- #endif
-
- #ifdef JSON_DEBUG
- #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::newInternal(unparsed)) { //root, specialized because it can only be array or node
- incAllocCount();
- }
- JSONNode(internalJSONNode * internal_t) : internal(internal_t){ //do not increment anything, this is only used in one case and it's already taken care of
- incAllocCount();
- }
- JSONNode(bool, JSONNode & orig);
-
- void decRef(void); //decrements internal's counter, deletes it if needed
- #ifdef JSON_REF_COUNT
- void makeUniqueInternal(void); //makes internal it's own
- void merge(JSONNode * other);
- #endif
-
- #ifdef JSON_DEBUG
- #ifndef JSON_LIBRARY
- JSONNode dump(size_t & totalmemory);
- #endif
- #endif
-
- #ifdef JSON_ITERATORS
- #ifndef JSON_LIBRARY
- json_iterator insertFRR(json_iterator pos, JSONNode ** const _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 _start, JSONNode ** const _end);
- #endif
-
- mutable internalJSONNode * internal;
- friend class JSONWorker;
- friend class internalJSONNode;
-};
-
-
-
-/*
- Implementations are here to keep the class declaration cleaner. They can't be placed in a different
- file because they are inlined.
-*/
-
-inline JSONNode::JSONNode(char mytype) : internal(internalJSONNode::newInternal(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 counting 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_binary 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) const {
- 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 accidentally 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, deletes 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_TEXT("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_TEXT("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, JSON_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, JSON_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, JSON_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, JSON_TEXT("iterating a non-iteratable node"));
- makeUniqueInternal();
- return JSONNode::reverse_iterator(internal -> begin() - 1);
- }
-
- inline JSONNode::reverse_const_iterator JSONNode::rbegin(void) const {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("iterating a non-iteratable node"));
- return JSONNode::reverse_const_iterator(internal -> end() - 1);
- }
-
- inline JSONNode::reverse_const_iterator JSONNode::rend(void) const {
- JSON_CHECK_INTERNAL();
- JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("iterating a non-iteratable node"));
- return JSONNode::reverse_const_iterator(internal -> begin() - 1);
- }
-
- inline JSONNode::iterator JSONNode::insert(json_iterator pos, const const_iterator & _start, const const_iterator & _end){
- return insertFFF(pos, _start.it, _end.it);
- }
-
- inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterator pos, const const_iterator & _start, const const_iterator & _end){
- return insertRFF(pos, _start.it, _end.it);
- }
-
- inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterator pos, const iterator & _start, const iterator & _end){
- return insertRFF(pos, _start.it, _end.it);
- }
-
- inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterator 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_iterator pos, const reverse_iterator & _start, const reverse_iterator & _end){
- return insertRRR(pos, _start.it, _end.it);
- }
-
- inline JSONNode::iterator JSONNode::insert(json_iterator pos, const reverse_const_iterator & _start, const reverse_const_iterator & _end){
- return insertFRR(pos, _start.it, _end.it);
- }
-
- inline JSONNode::iterator JSONNode::insert(iterator pos, const reverse_iterator & _start, const reverse_iterator & _end){
- return insertFRR(pos, _start.it, _end.it);
- }
- #endif
-
- inline JSONNode::json_iterator JSONNode::insert(json_iterator pos, const json_iterator & _start, const json_iterator & _end){
- return insertFFF(pos, json_iterator_ptr(_start), json_iterator_ptr(_end));
- }
-#endif
-
-#ifdef JSON_WRITER
- inline json_string JSONNode::write(void){
- JSON_CHECK_INTERNAL();
- JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSON_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, JSON_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, JSON_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"), (long)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"), (long)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<JSONNode &>(orig));
- #else
- return new JSONNode(true, const_cast<JSONNode &>(orig));
- #endif
-}
-#endif
+#ifndef JSONNODE_H
+#define JSONNODE_H
+
+#include "JSONDefs.h" //for string type
+#include "internalJSONNode.h" //internal structure for json value
+#include <stdexcept>
+#include <cstdarg> //for the ... parameter
+
+#ifdef JSON_BINARY
+ #include "JSON_Base64.h"
+#endif
+
+#ifndef JSON_REF_COUNT
+ #define makeUniqueInternal() (void)0
+#endif
+
+#define JSON_CHECK_INTERNAL() JSON_ASSERT(internal, JSON_TEXT("no internal"))
+
+#ifdef JSON_MUTEX_CALLBACKS
+ #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 value_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
+ void push_back(const JSONNode & node);
+ #endif
+ void reserve(json_index_t size);
+ 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
+
+ DECLARE_FOR_ALL_TYPES(JSONNode & operator = )
+ JSONNode & operator = (const JSONNode &);
+
+ DECLARE_FOR_ALL_TYPES_CONST(bool operator ==)
+ DECLARE_FOR_ALL_TYPES_CONST(bool operator !=)
+
+
+ void nullify(void);
+ void swap(JSONNode & other);
+ void merge(JSONNode & other);
+ void merge(unsigned int num, ...);
+ JSONNode duplicate(void) const;
+ void cast(char newtype);
+
+
+ //iterator
+ #ifdef JSON_ITERATORS
+ #ifndef JSON_LIBRARY
+ #define json_iterator_ptr(iter) iter.it
+ #define ptr_to_json_iterator(iter) json_iterator(iter)
+ struct iterator {
+ inline iterator& operator ++(void){ ++it; return *this; }
+ inline iterator& operator --(void){ --it; return *this; }
+ inline iterator& operator +=(long i){ it += i; return *this; }
+ inline iterator& operator -=(long i){ it -= i; return *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 { return *it[pos]; };
+ inline JSONNode& operator *(void) const { return *(*it); }
+ inline bool operator == (const iterator & other) const { return it == other.it; }
+ inline bool operator != (const iterator & other) const { return it != other.it; }
+ inline bool operator > (const iterator & other) const { return it > other.it; }
+ inline bool operator >= (const iterator & other) const { return it >= other.it; }
+ inline bool operator < (const iterator & other) const { return it < other.it; }
+ inline bool operator <= (const iterator & other) const { 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;
+
+ struct const_iterator {
+ inline const_iterator& operator ++(void){ ++it; return *this; }
+ inline const_iterator& operator --(void){ --it; return *this; }
+ inline const_iterator& operator +=(long i){ it += i; 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) const { return const_cast<const JSONNode&>(*it[pos]); };
+ inline const JSONNode& operator *(void) const { return const_cast<const JSONNode&>(*(*it)); }
+ inline bool operator == (const const_iterator & other) const { return it == other.it; }
+ inline bool operator != (const const_iterator & other) const { return it != other.it; }
+ inline bool operator > (const const_iterator & other) const { return it > other.it; }
+ inline bool operator >= (const const_iterator & other) const { return it >= other.it; }
+ inline bool operator < (const const_iterator & other) const { return it < other.it; }
+ inline bool operator <= (const const_iterator & other) const { return it <= other.it; }
+ inline const_iterator & operator = (const const_iterator & orig){ it = orig.it; return *this; }
+ const_iterator (const const_iterator & orig) : it(orig.it) {}
+ private:
+ JSONNode ** it;
+ const_iterator(JSONNode ** starter) : it(starter) {}
+ friend class JSONNode;
+ };
+ const_iterator begin(void) const;
+ const_iterator end(void) const;
+
+ struct reverse_iterator {
+ inline reverse_iterator& operator ++(void){ --it; return *this; }
+ inline reverse_iterator& operator --(void){ ++it; return *this; }
+ inline reverse_iterator& operator +=(long i){ it -= i; return *this; }
+ inline reverse_iterator& operator -=(long i){ it += i; return *this; }
+ 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 { return *it[pos]; };
+ inline JSONNode& operator *(void) const { return *(*it); }
+ inline bool operator == (const reverse_iterator & other) const { return it == other.it; }
+ inline bool operator != (const reverse_iterator & other) const { return it != other.it; }
+ inline bool operator < (const reverse_iterator & other) const { return it > other.it; }
+ inline bool operator <= (const reverse_iterator & other) const { return it >= other.it; }
+ inline bool operator > (const reverse_iterator & other) const { return it < other.it; }
+ inline bool operator >= (const reverse_iterator & other) 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);
+
+ struct reverse_const_iterator {
+ inline reverse_const_iterator& operator ++(void){ --it; return *this; }
+ inline reverse_const_iterator& operator --(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) const {
+ reverse_const_iterator result(*this);
+ result.it -= i;
+ return result;
+ }
+ inline reverse_const_iterator operator -(long i) const {
+ reverse_const_iterator result(*this);
+ result.it += i;
+ return result;
+ }
+ inline const JSONNode& operator [](size_t pos) const { return const_cast<const JSONNode&>(*it[pos]); };
+ inline const JSONNode& operator *(void) const { return const_cast<const JSONNode&>(*(*it)); }
+ inline bool operator == (const reverse_const_iterator & other) const { return it == other.it; }
+ inline bool operator != (const reverse_const_iterator & other) const { return it != other.it; }
+ inline bool operator < (const reverse_const_iterator & other) const { return it > other.it; }
+ inline bool operator <= (const reverse_const_iterator & other) const { return it >= other.it; }
+ inline bool operator > (const reverse_const_iterator & other) const { return it < other.it; }
+ inline bool operator >= (const reverse_const_iterator & other) const { return it <= other.it; }
+ inline reverse_const_iterator & operator = (const reverse_const_iterator & orig){ it = orig.it; return *this; }
+ reverse_const_iterator (const reverse_const_iterator & orig) : it(orig.it) {}
+ private:
+ JSONNode ** it;
+ reverse_const_iterator(JSONNode ** starter) : it(starter) {}
+ friend class JSONNode;
+ };
+ reverse_const_iterator rbegin(void) const;
+ reverse_const_iterator rend(void) const;
+
+ const_iterator find(const json_string & name_t) const;
+ #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
+ const_iterator find_nocase(const json_string & name_t) const;
+ #endif
+
+ reverse_iterator erase(reverse_iterator pos);
+ reverse_iterator erase(reverse_iterator start, const reverse_iterator & end);
+
+ iterator insert(iterator pos, const JSONNode & x);
+ reverse_iterator insert(reverse_iterator pos, const JSONNode & x);
+ iterator insert(iterator pos, const reverse_iterator & _start, const reverse_iterator & _end);
+ reverse_iterator insert(reverse_iterator pos, const iterator & _start, const iterator & _end);
+ reverse_iterator insert(reverse_iterator pos, const reverse_iterator & _start, const reverse_iterator & _end);
+
+ json_iterator insert(json_iterator pos, const const_iterator & _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_const_iterator & _start, const reverse_const_iterator & _end);
+ reverse_iterator insert(reverse_iterator pos, const reverse_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
+
+ json_iterator begin(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
+ json_iterator erase(json_iterator pos);
+ json_iterator erase(json_iterator start, const json_iterator & end);
+ json_iterator insert(json_iterator pos, const json_iterator & _start, const json_iterator & _end);
+ #endif
+
+
+ #ifdef JSON_MUTEX_CALLBACKS
+ static void register_mutex_callbacks(json_mutex_callback_t lock, json_mutex_callback_t unlock, void * manager_lock);
+ #ifdef JSON_MUTEX_MANAGE
+ static void register_mutex_destructor(json_mutex_callback_t destroy);
+ #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(&node), mythread(thread){
+ mynode -> lock(mythread);
+ }
+ auto_lock(JSONNode * node, int thread) : mynode(node), 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
+
+ #ifdef JSON_UNIT_TEST
+ static int getNodeAllocationCount(void);
+ 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
+
+ #ifdef JSON_WRITER
+ json_string write(void);
+ json_string write_formatted(void);
+ #endif
+
+ #ifdef JSON_DEBUG
+ #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::newInternal(unparsed)) { //root, specialized because it can only be array or node
+ incAllocCount();
+ }
+ JSONNode(internalJSONNode * internal_t) : internal(internal_t){ //do not increment anything, this is only used in one case and it's already taken care of
+ incAllocCount();
+ }
+ JSONNode(bool, JSONNode & orig);
+
+ void decRef(void); //decrements internal's counter, deletes it if needed
+ #ifdef JSON_REF_COUNT
+ void makeUniqueInternal(void); //makes internal it's own
+ void merge(JSONNode * other);
+ #endif
+
+ #ifdef JSON_DEBUG
+ #ifndef JSON_LIBRARY
+ JSONNode dump(size_t & totalmemory);
+ #endif
+ #endif
+
+ #ifdef JSON_ITERATORS
+ #ifndef JSON_LIBRARY
+ json_iterator insertFRR(json_iterator pos, JSONNode ** const _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 _start, JSONNode ** const _end);
+ #endif
+
+ mutable internalJSONNode * internal;
+ friend class JSONWorker;
+ friend class internalJSONNode;
+};
+
+
+
+/*
+ Implementations are here to keep the class declaration cleaner. They can't be placed in a different
+ file because they are inlined.
+*/
+
+inline JSONNode::JSONNode(char mytype) : internal(internalJSONNode::newInternal(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 counting 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_binary 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) const {
+ 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 accidentally 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, deletes 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_TEXT("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_TEXT("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, JSON_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, JSON_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, JSON_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, JSON_TEXT("iterating a non-iteratable node"));
+ makeUniqueInternal();
+ return JSONNode::reverse_iterator(internal -> begin() - 1);
+ }
+
+ inline JSONNode::reverse_const_iterator JSONNode::rbegin(void) const {
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("iterating a non-iteratable node"));
+ return JSONNode::reverse_const_iterator(internal -> end() - 1);
+ }
+
+ inline JSONNode::reverse_const_iterator JSONNode::rend(void) const {
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("iterating a non-iteratable node"));
+ return JSONNode::reverse_const_iterator(internal -> begin() - 1);
+ }
+
+ inline JSONNode::iterator JSONNode::insert(json_iterator pos, const const_iterator & _start, const const_iterator & _end){
+ return insertFFF(pos, _start.it, _end.it);
+ }
+
+ inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterator pos, const const_iterator & _start, const const_iterator & _end){
+ return insertRFF(pos, _start.it, _end.it);
+ }
+
+ inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterator pos, const iterator & _start, const iterator & _end){
+ return insertRFF(pos, _start.it, _end.it);
+ }
+
+ inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterator 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_iterator pos, const reverse_iterator & _start, const reverse_iterator & _end){
+ return insertRRR(pos, _start.it, _end.it);
+ }
+
+ inline JSONNode::iterator JSONNode::insert(json_iterator pos, const reverse_const_iterator & _start, const reverse_const_iterator & _end){
+ return insertFRR(pos, _start.it, _end.it);
+ }
+
+ inline JSONNode::iterator JSONNode::insert(iterator pos, const reverse_iterator & _start, const reverse_iterator & _end){
+ return insertFRR(pos, _start.it, _end.it);
+ }
+ #endif
+
+ inline JSONNode::json_iterator JSONNode::insert(json_iterator pos, const json_iterator & _start, const json_iterator & _end){
+ return insertFFF(pos, json_iterator_ptr(_start), json_iterator_ptr(_end));
+ }
+#endif
+
+#ifdef JSON_WRITER
+ inline json_string JSONNode::write(void){
+ JSON_CHECK_INTERNAL();
+ JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSON_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, JSON_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, JSON_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"), (long)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"), (long)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<JSONNode &>(orig));
+ #else
+ return new JSONNode(true, const_cast<JSONNode &>(orig));
+ #endif
+}
+#endif