| JSONMemory.h | | JSONMemory.h | |
| | | | |
| skipping to change at line 15 | | skipping to change at line 15 | |
| #include <cstring> //for memmove | | #include <cstring> //for memmove | |
| #include "../JSONOptions.h" | | #include "../JSONOptions.h" | |
| #include "JSONDebug.h" | | #include "JSONDebug.h" | |
| | | | |
| #if defined(JSON_DEBUG) || defined(JSON_SAFE) | | #if defined(JSON_DEBUG) || defined(JSON_SAFE) | |
| #define JSON_FREE_PASSTYPE & | | #define JSON_FREE_PASSTYPE & | |
| #else | | #else | |
| #define JSON_FREE_PASSTYPE | | #define JSON_FREE_PASSTYPE | |
| #endif | | #endif | |
| | | | |
|
| #ifdef JSON_MEMORY_CALLBACKS | | #if defined(JSON_MEMORY_CALLBACKS) || defined(JSON_MEMORY_POOL) | |
| class JSONMemory { | | class JSONMemory { | |
| public: | | public: | |
| #ifdef __GNUC__ | | #ifdef __GNUC__ | |
| static void * json_malloc(size_t siz) json_malloc_attr; | | static void * json_malloc(size_t siz) json_malloc_attr; | |
|
| static void * json_realloc(void * ptr, size_t siz) json_ma
lloc_attr; | | static void * json_realloc(void * ptr, size_t siz) json_malloc
_attr; | |
| #else | | #else | |
| static void * json_malloc(size_t siz) json_nothrow; | | static void * json_malloc(size_t siz) json_nothrow; | |
|
| static void * json_realloc(void * ptr, size_t siz) json_no
throw; | | static void * json_realloc(void * ptr, size_t siz) json_no
throw; | |
| #endif | | #endif | |
| static void json_free(void * ptr) json_nothrow; | | static void json_free(void * ptr) json_nothrow; | |
| static void registerMemoryCallbacks(json_malloc_t mal, json_reall
oc_t real, json_free_t fre) json_nothrow json_cold; | | static void registerMemoryCallbacks(json_malloc_t mal, json_reall
oc_t real, json_free_t fre) json_nothrow json_cold; | |
| }; | | }; | |
| | | | |
| template <typename T> static inline T * json_malloc(size_t count) json_
malloc_attr; | | template <typename T> static inline T * json_malloc(size_t count) json_
malloc_attr; | |
| template <typename T> static inline T * json_malloc(size_t count) json_
nothrow { | | template <typename T> static inline T * json_malloc(size_t count) json_
nothrow { | |
| return (T *)JSONMemory::json_malloc(sizeof(T) * count); | | return (T *)JSONMemory::json_malloc(sizeof(T) * count); | |
| } | | } | |
| | | | |
| template <typename T> static inline T * json_realloc(T * ptr, size_t co
unt) json_malloc_attr; | | template <typename T> static inline T * json_realloc(T * ptr, size_t co
unt) json_malloc_attr; | |
| template <typename T> static inline T * json_realloc(T * ptr, size_t co
unt) json_nothrow { | | template <typename T> static inline T * json_realloc(T * ptr, size_t co
unt) json_nothrow { | |
|
| return (T *)JSONMemory::json_realloc(ptr, sizeof(T) * count); | | return (T *)JSONMemory::json_realloc(ptr, sizeof(T) * count); | |
| } | | } | |
| | | | |
| template <typename T> static inline void libjson_free(T * JSON_FREE_PAS
STYPE ptr) json_nothrow { | | template <typename T> static inline void libjson_free(T * JSON_FREE_PAS
STYPE ptr) json_nothrow { | |
| JSONMemory::json_free(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 | | #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; | | ptr = 0; | |
| #endif | | #endif | |
| } | | } | |
| #else | | #else | |
| | | | |
| template <typename T> static inline T * json_malloc(size_t count) json_
malloc_attr; | | template <typename T> static inline T * json_malloc(size_t count) json_
malloc_attr; | |
| template <typename T> static inline T * json_malloc(size_t count) json_
nothrow { | | template <typename T> static inline T * json_malloc(size_t count) json_
nothrow { | |
| #ifdef JSON_DEBUG //in debug mode, see if the malloc was success
ful | | #ifdef JSON_DEBUG //in debug mode, see if the malloc was success
ful | |
|
| void * result = malloc(count * sizeof(T)); | | void * result = std::malloc(count * sizeof(T)); | |
| JSON_ASSERT(result != 0, JSON_TEXT("out of memory")); | | JSON_ASSERT(result != 0, JSON_TEXT("Out of memory")); | |
| #ifdef JSON_NULL_MEMORY | | #ifdef JSON_NULL_MEMORY | |
|
| memset(result, '\0', count * sizeof(T)); | | std::memset(result, '\0', count * sizeof(T)); | |
| #endif | | #endif | |
| return (T *)result; | | return (T *)result; | |
| #else | | #else | |
|
| return (T *)malloc(count * sizeof(T)); | | return (T *)std::malloc(count * sizeof(T)); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| template <typename T> static inline void libjson_free(T * JSON_FREE_PAS
STYPE ptr) json_nothrow { | | template <typename T> static inline void libjson_free(T * JSON_FREE_PAS
STYPE ptr) json_nothrow { | |
|
| free(ptr); | | std::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 | | #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; | | ptr = 0; | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| template <typename T> static inline T * json_realloc(T * ptr, size_t co
unt) json_malloc_attr; | | template <typename T> static inline T * json_realloc(T * ptr, size_t co
unt) json_malloc_attr; | |
| template <typename T> static inline T * json_realloc(T * ptr, size_t co
unt) json_nothrow { | | template <typename T> static inline T * json_realloc(T * ptr, size_t co
unt) json_nothrow { | |
| #ifdef JSON_DEBUG //in debug mode, check the results of realloc
to be sure it was successful | | #ifdef JSON_DEBUG //in debug mode, check the results of realloc
to be sure it was successful | |
|
| void * result = realloc(ptr, count * sizeof(T)); | | void * result = std::realloc(ptr, count * sizeof(T)); | |
| JSON_ASSERT(result != 0, JSON_TEXT("out of memory")); | | JSON_ASSERT(result != 0, JSON_TEXT("Out of memory")); | |
| #ifdef JSON_NULL_MEMORY | | | |
| memset(result, '\0', count * sizeof(T)); | | | |
| #endif | | | |
| return (T *)result; | | return (T *)result; | |
| #else | | #else | |
|
| return (T *)realloc(ptr, count * sizeof(T)); | | return (T *)std::realloc(ptr, count * sizeof(T)); | |
| #endif | | #endif | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_MEMORY_MANAGE | | #ifdef JSON_MEMORY_MANAGE | |
| #include <map> | | #include <map> | |
| class JSONNode; | | class JSONNode; | |
| struct auto_expand { | | struct auto_expand { | |
| auto_expand(void) json_nothrow : mymap(){} | | auto_expand(void) json_nothrow : mymap(){} | |
| ~auto_expand(void) json_nothrow { purge(); } | | ~auto_expand(void) json_nothrow { purge(); } | |
| void purge(void) json_nothrow; | | void purge(void) json_nothrow; | |
| inline void clear(void) json_nothrow { purge(); mymap.clear(); } | | inline void clear(void) json_nothrow { purge(); mymap.clear(); } | |
| inline void * insert(void * ptr) json_nothrow { mymap[ptr] = ptr;
return ptr; } | | inline void * insert(void * ptr) json_nothrow { mymap[ptr] = ptr;
return ptr; } | |
| inline void remove(void * ptr) json_nothrow { | | inline void remove(void * ptr) json_nothrow { | |
|
| std::map<void *, void *>::iterator i = mymap.find(ptr); | | JSON_MAP(void *, void *)::iterator i = mymap.find(ptr); | |
| JSON_ASSERT(i != mymap.end(), JSON_TEXT("Removing a non-ma
naged item")); | | JSON_ASSERT(i != mymap.end(), JSON_TEXT("Removing a non-ma
naged item")); | |
| mymap.erase(i); | | mymap.erase(i); | |
| } | | } | |
|
| std::map<void *, void *> mymap; | | JSON_MAP(void *, void *) mymap; | |
| }; | | }; | |
| | | | |
| struct auto_expand_node { | | struct auto_expand_node { | |
| auto_expand_node(void) json_nothrow : mymap(){} | | auto_expand_node(void) json_nothrow : mymap(){} | |
| ~auto_expand_node(void) json_nothrow { purge(); } | | ~auto_expand_node(void) json_nothrow { purge(); } | |
| void purge(void) json_nothrow ; | | void purge(void) json_nothrow ; | |
| inline void clear(void) json_nothrow { purge(); mymap.clear(); } | | inline void clear(void) json_nothrow { purge(); mymap.clear(); } | |
| inline JSONNode * insert(JSONNode * ptr) json_nothrow { mymap[ptr
] = ptr; return ptr; } | | inline JSONNode * insert(JSONNode * ptr) json_nothrow { mymap[ptr
] = ptr; return ptr; } | |
| inline void remove(void * ptr) json_nothrow { | | inline void remove(void * ptr) json_nothrow { | |
|
| std::map<void *, JSONNode *>::iterator i = mymap.find(ptr)
; | | JSON_MAP(void *, JSONNode *)::iterator i = mymap.find(ptr)
; | |
| if(json_likely(i != mymap.end())) mymap.erase(i); | | if(json_likely(i != mymap.end())) mymap.erase(i); | |
| } | | } | |
|
| std::map<void *, JSONNode *> mymap; | | JSON_MAP(void *, JSONNode *) mymap; | |
| }; | | }; | |
| | | | |
| #ifdef JSON_STREAM | | #ifdef JSON_STREAM | |
| class JSONStream; | | class JSONStream; | |
| struct auto_expand_stream { | | struct auto_expand_stream { | |
| auto_expand_stream(void) json_nothrow : mymap(){} | | auto_expand_stream(void) json_nothrow : mymap(){} | |
| ~auto_expand_stream(void) json_nothrow { purge(); } | | ~auto_expand_stream(void) json_nothrow { purge(); } | |
| void purge(void) json_nothrow ; | | void purge(void) json_nothrow ; | |
| inline void clear(void) json_nothrow { purge(); mymap.clea
r(); } | | inline void clear(void) json_nothrow { purge(); mymap.clea
r(); } | |
| inline JSONStream * insert(JSONStream * ptr) json_nothrow
{ mymap[ptr] = ptr; return ptr; } | | inline JSONStream * insert(JSONStream * ptr) json_nothrow
{ mymap[ptr] = ptr; return ptr; } | |
| inline void remove(void * ptr) json_nothrow { | | inline void remove(void * ptr) json_nothrow { | |
|
| std::map<void *, JSONStream *>::iterator i = mymap.
find(ptr); | | JSON_MAP(void *, JSONStream *)::iterator i = mymap.
find(ptr); | |
| if(json_likely(i != mymap.end())) mymap.erase(i); | | if(json_likely(i != mymap.end())) mymap.erase(i); | |
| } | | } | |
|
| std::map<void *, JSONStream *> mymap; | | JSON_MAP(void *, JSONStream *) mymap; | |
| }; | | }; | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| //The C++ way, use an self-deleting pointer and let the optimizer decide wh
en it gets destroyed | | //The C++ way, use an self-deleting pointer and let the optimizer decide wh
en it gets destroyed | |
| template <typename T> | | template <typename T> | |
| class json_auto { | | class json_auto { | |
| public: | | public: | |
| json_auto(void) json_nothrow : ptr(0){} | | json_auto(void) json_nothrow : ptr(0){} | |
| json_auto(size_t count) json_nothrow : ptr(json_malloc<T>(count))
{} | | json_auto(size_t count) json_nothrow : ptr(json_malloc<T>(count))
{} | |
|
| | | json_auto(T * arg) json_nothrow : ptr(arg){} | |
| ~json_auto(void) json_nothrow { | | ~json_auto(void) json_nothrow { | |
| libjson_free<T>(ptr); | | libjson_free<T>(ptr); | |
| } | | } | |
| inline void set(T * p) json_nothrow{ | | inline void set(T * p) json_nothrow{ | |
| ptr = p; | | ptr = p; | |
| } | | } | |
| T * ptr; | | T * ptr; | |
| private: | | private: | |
| json_auto(const json_auto &); | | json_auto(const json_auto &); | |
| json_auto & operator =(const json_auto &); | | json_auto & operator =(const json_auto &); | |
| | | | |
End of changes. 17 change blocks. |
| 21 lines changed or deleted | | 19 lines changed or added | |
|
| JSONNode.h | | JSONNode.h | |
| | | | |
| skipping to change at line 38 | | skipping to change at line 38 | |
| #define JSON_MUTEX_COPY_DECL ,void * parentMutex | | #define JSON_MUTEX_COPY_DECL ,void * parentMutex | |
| #define JSON_MUTEX_COPY_DECL2 ,void * parentMutex = 0 | | #define JSON_MUTEX_COPY_DECL2 ,void * parentMutex = 0 | |
| #else | | #else | |
| #define JSON_MUTEX_COPY_DECL | | #define JSON_MUTEX_COPY_DECL | |
| #define JSON_MUTEX_COPY_DECL2 | | #define JSON_MUTEX_COPY_DECL2 | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_LIBRARY | | #ifdef JSON_LIBRARY | |
| #define JSON_PTR_LIB * | | #define JSON_PTR_LIB * | |
| #define JSON_NEW(x) JSONNode::newJSONNode_Shallow(x) | | #define JSON_NEW(x) JSONNode::newJSONNode_Shallow(x) | |
|
| | | | |
| #define DECLARE_FOR_ALL_TYPES(foo)\ | | #define DECLARE_FOR_ALL_TYPES(foo)\ | |
|
| foo(long)json_nothrow;\ | | foo(json_int_t)json_nothrow;\ | |
| foo(json_number) json_nothrow;\ | | foo(json_number) json_nothrow;\ | |
| foo(bool) json_nothrow;\ | | foo(bool) json_nothrow;\ | |
| foo(const json_string &) json_nothrow; | | foo(const json_string &) json_nothrow; | |
| | | | |
|
| #define DECLARE_FOR_ALL_TYPES_CONST(foo)\ | | #define DECLARE_FOR_ALL_CAST_TYPES_CONST(foo)\ | |
| foo(long) const json_nothrow;\ | | foo(json_int_t) const json_nothrow;\ | |
| foo(json_number) const json_nothrow;\ | | foo(json_number) const json_nothrow;\ | |
| foo(bool) const json_nothrow;\ | | foo(bool) const json_nothrow;\ | |
| foo(const json_string &) const json_nothrow;\ | | foo(const json_string &) const json_nothrow;\ | |
|
| | | | |
| | | #define DECLARE_FOR_ALL_TYPES_CONST(foo)\ | |
| | | DECLARE_FOR_ALL_CAST_TYPES_CONST(foo)\ | |
| foo(const JSONNode &) const json_nothrow; | | foo(const JSONNode &) const json_nothrow; | |
| | | | |
| #define IMPLEMENT_FOR_ALL_NUMBERS(foo)\ | | #define IMPLEMENT_FOR_ALL_NUMBERS(foo)\ | |
|
| foo(long)\ | | foo(json_int_t)\ | |
| foo(json_number) | | foo(json_number) | |
| | | | |
| #else | | #else | |
| #define JSON_PTR_LIB | | #define JSON_PTR_LIB | |
| #define JSON_NEW(x) x | | #define JSON_NEW(x) x | |
|
| | | | |
| | | #ifdef JSON_ISO_STRICT | |
| | | #define DECLARE_FOR_LONG_LONG(foo) | |
| | | #define DECLARE_FOR_LONG_LONG_CONST(foo) | |
| | | #define IMPLEMENT_FOR_LONG_LONG(foo) | |
| | | #define DECLARE_FOR_LONG_DOUBLE(foo) | |
| | | #define DECLARE_FOR_LONG_DOUBLE_CONST(foo) | |
| | | #define IMPLEMENT_FOR_LONG_DOUBLE(foo) | |
| | | #else | |
| | | #define DECLARE_FOR_LONG_LONG(foo) foo(long long) json_nothrow; f | |
| | | oo(unsigned long long) json_nothrow; | |
| | | #define DECLARE_FOR_LONG_LONG_CONST(foo) foo(long long) const jso | |
| | | n_nothrow; foo(unsigned long long) const json_nothrow; | |
| | | #define IMPLEMENT_FOR_LONG_LONG(foo) foo(long long) foo(unsigned | |
| | | long long) | |
| | | #define DECLARE_FOR_LONG_DOUBLE(foo) foo(long double) json_nothro | |
| | | w; | |
| | | #define DECLARE_FOR_LONG_DOUBLE_CONST(foo) foo(long double) const | |
| | | json_nothrow; | |
| | | #define IMPLEMENT_FOR_LONG_DOUBLE(foo) foo(long double) | |
| | | #endif | |
| | | | |
| #define DECLARE_FOR_ALL_TYPES(foo)\ | | #define DECLARE_FOR_ALL_TYPES(foo)\ | |
| foo(char) json_nothrow; foo(unsigned char) json_nothrow;\ | | foo(char) json_nothrow; foo(unsigned char) json_nothrow;\ | |
| foo(short) json_nothrow; foo(unsigned short) json_nothrow;\ | | foo(short) json_nothrow; foo(unsigned short) json_nothrow;\ | |
| foo(int) json_nothrow; foo(unsigned int) json_nothrow;\ | | foo(int) json_nothrow; foo(unsigned int) json_nothrow;\ | |
| foo(long) json_nothrow; foo(unsigned long) json_nothrow;\ | | foo(long) json_nothrow; foo(unsigned long) json_nothrow;\ | |
| foo(float) json_nothrow; foo(double) json_nothrow;\ | | foo(float) json_nothrow; foo(double) json_nothrow;\ | |
| foo(bool) json_nothrow;\ | | foo(bool) json_nothrow;\ | |
| foo(const json_string &) json_nothrow;\ | | foo(const json_string &) json_nothrow;\ | |
|
| foo(const json_char *) json_nothrow; | | foo(const json_char *) json_nothrow;\ | |
| | | DECLARE_FOR_LONG_LONG(foo)\ | |
| | | DECLARE_FOR_LONG_DOUBLE(foo) | |
| | | | |
|
| #define DECLARE_FOR_ALL_TYPES_CONST(foo)\ | | #define DECLARE_FOR_ALL_CAST_TYPES_CONST(foo)\ | |
| foo(char) const json_nothrow; foo(unsigned char) const jso
n_nothrow;\ | | foo(char) const json_nothrow; foo(unsigned char) const jso
n_nothrow;\ | |
| foo(short) const json_nothrow; foo(unsigned short) const js
on_nothrow;\ | | foo(short) const json_nothrow; foo(unsigned short) const js
on_nothrow;\ | |
| foo(int) const json_nothrow; foo(unsigned int) const json_nothrow
;\ | | foo(int) const json_nothrow; foo(unsigned int) const json_nothrow
;\ | |
| foo(long) const json_nothrow; foo(unsigned long) const jso
n_nothrow;\ | | foo(long) const json_nothrow; foo(unsigned long) const jso
n_nothrow;\ | |
| foo(float) const json_nothrow; foo(double) const json_nothr
ow;\ | | foo(float) const json_nothrow; foo(double) const json_nothr
ow;\ | |
| foo(bool) const json_nothrow;\ | | foo(bool) const json_nothrow;\ | |
| foo(const json_string &) const json_nothrow;\ | | foo(const json_string &) const json_nothrow;\ | |
|
| | | DECLARE_FOR_LONG_LONG_CONST(foo)\ | |
| | | DECLARE_FOR_LONG_DOUBLE_CONST(foo) | |
| | | | |
| | | #define DECLARE_FOR_ALL_TYPES_CONST(foo)\ | |
| | | DECLARE_FOR_ALL_CAST_TYPES_CONST(foo)\ | |
| foo(const JSONNode &) const json_nothrow;\ | | foo(const JSONNode &) const json_nothrow;\ | |
| foo(const json_char *) const json_nothrow; | | foo(const json_char *) const json_nothrow; | |
| | | | |
| #define IMPLEMENT_FOR_ALL_NUMBERS(foo)\ | | #define IMPLEMENT_FOR_ALL_NUMBERS(foo)\ | |
| foo(char) foo(unsigned char)\ | | foo(char) foo(unsigned char)\ | |
| foo(short) foo(unsigned short)\ | | foo(short) foo(unsigned short)\ | |
| foo(int) foo(unsigned int)\ | | foo(int) foo(unsigned int)\ | |
| foo(long) foo(unsigned long)\ | | foo(long) foo(unsigned long)\ | |
|
| foo(float) foo(double) | | foo(float) foo(double)\ | |
| | | IMPLEMENT_FOR_LONG_LONG(foo)\ | |
| | | IMPLEMENT_FOR_LONG_DOUBLE(foo) | |
| | | | |
| #endif | | #endif | |
| | | | |
| #define IMPLEMENT_FOR_ALL_TYPES(foo)\ | | #define IMPLEMENT_FOR_ALL_TYPES(foo)\ | |
| IMPLEMENT_FOR_ALL_NUMBERS(foo)\ | | IMPLEMENT_FOR_ALL_NUMBERS(foo)\ | |
| foo(const json_string &)\ | | foo(const json_string &)\ | |
| foo(bool) | | foo(bool) | |
| | | | |
| /* | | /* | |
| This class is mostly just a wrapper class around internalJSONNode, this
class keeps | | 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 | | the reference count and handles copy on write and such. This class is
also responsible | |
| for argument checking and throwing exceptions if needed. | | for argument checking and throwing exceptions if needed. | |
| */ | | */ | |
| | | | |
| class JSONNode { | | class JSONNode { | |
| public: | | public: | |
| explicit JSONNode(char mytype = JSON_NODE) json_nothrow json_hot; | | explicit JSONNode(char mytype = JSON_NODE) json_nothrow json_hot; | |
|
| #define DECLARE_CTOR(type) JSONNode(const json_string & name_t, type va
lue_t) | | #define DECLARE_CTOR(type) explicit JSONNode(const json_string & name_t
, type value_t) | |
| DECLARE_FOR_ALL_TYPES(DECLARE_CTOR) | | DECLARE_FOR_ALL_TYPES(DECLARE_CTOR) | |
| | | | |
| JSONNode(const JSONNode & orig) json_nothrow json_hot; | | JSONNode(const JSONNode & orig) json_nothrow json_hot; | |
| ~JSONNode(void) json_nothrow json_hot; | | ~JSONNode(void) json_nothrow json_hot; | |
| | | | |
|
| | | #if (defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)) | |
| | | static JSONNode stringType(const json_string & str); | |
| | | void set_name_(const json_string & newname) json_nothrow json_write | |
| | | _priority; | |
| | | #endif | |
| | | | |
| json_index_t size(void) const json_nothrow json_read_priority; | | json_index_t size(void) const json_nothrow json_read_priority; | |
| bool empty(void) const json_nothrow json_read_priority; | | bool empty(void) const json_nothrow json_read_priority; | |
| void clear(void) json_nothrow json_cold; | | void clear(void) json_nothrow json_cold; | |
| unsigned char type(void) const json_nothrow json_read_priority; | | unsigned char type(void) const json_nothrow json_read_priority; | |
| | | | |
| json_string name(void) const json_nothrow json_read_priority; | | json_string name(void) const json_nothrow json_read_priority; | |
| void set_name(const json_string & newname) json_nothrow json_write_prio
rity; | | void set_name(const json_string & newname) json_nothrow json_write_prio
rity; | |
| #ifdef JSON_COMMENTS | | #ifdef JSON_COMMENTS | |
| void set_comment(const json_string & comment) json_nothrow; | | void set_comment(const json_string & comment) json_nothrow; | |
| json_string get_comment(void) const json_nothrow; | | json_string get_comment(void) const json_nothrow; | |
| #endif | | #endif | |
| #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY) | | #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY) | |
| void preparse(void) json_nothrow json_read_priority; | | void preparse(void) json_nothrow json_read_priority; | |
| #endif | | #endif | |
| | | | |
| json_string as_string(void) const json_nothrow json_read_priority; | | json_string as_string(void) const json_nothrow json_read_priority; | |
|
| long as_int(void) const json_nothrow json_read_priority; | | json_int_t as_int(void) const json_nothrow json_read_priority; | |
| json_number as_float(void) const json_nothrow json_read_priority; | | json_number as_float(void) const json_nothrow json_read_priority; | |
| bool as_bool(void) const json_nothrow json_read_priority; | | bool as_bool(void) const json_nothrow json_read_priority; | |
|
| JSONNode as_node(void) const json_nothrow json_read_priority; | | | |
| JSONNode as_array(void) const json_nothrow json_read_priority; | | #ifdef JSON_CASTABLE | |
| | | JSONNode as_node(void) const json_nothrow json_read_priority; | |
| | | JSONNode as_array(void) const json_nothrow json_read_priority; | |
| | | void cast(char newtype) json_nothrow; | |
| | | #endif | |
| | | | |
| #ifdef JSON_BINARY | | #ifdef JSON_BINARY | |
| std::string as_binary(void) const json_nothrow json_cold; | | std::string as_binary(void) const json_nothrow json_cold; | |
| void set_binary(const unsigned char * bin, size_t bytes) json_not
hrow json_cold; | | void set_binary(const unsigned char * bin, size_t bytes) json_not
hrow json_cold; | |
| #endif | | #endif | |
| | | | |
| JSONNode & at(json_index_t pos) json_throws(std::out_of_range); | | JSONNode & at(json_index_t pos) json_throws(std::out_of_range); | |
| const JSONNode & at(json_index_t pos) const json_throws(std::out_of_ran
ge); | | const JSONNode & at(json_index_t pos) const json_throws(std::out_of_ran
ge); | |
|
| | | | |
| JSONNode & operator[](json_index_t pos) json_nothrow; | | JSONNode & operator[](json_index_t pos) json_nothrow; | |
| const JSONNode & operator[](json_index_t pos) const json_nothrow; | | const JSONNode & operator[](json_index_t pos) const json_nothrow; | |
| | | | |
| JSONNode & at(const json_string & name_t) json_throws(std::out_of_range
); | | JSONNode & at(const json_string & name_t) json_throws(std::out_of_range
); | |
| const JSONNode & at(const json_string & name_t) const json_throws(std::
out_of_range); | | const JSONNode & at(const json_string & name_t) const json_throws(std::
out_of_range); | |
| #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | | #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | |
| JSONNode & at_nocase(const json_string & name_t) json_throws(std:
:out_of_range); | | JSONNode & at_nocase(const json_string & name_t) json_throws(std:
:out_of_range); | |
| const JSONNode & at_nocase(const json_string & name_t) const json
_throws(std::out_of_range); | | const JSONNode & at_nocase(const json_string & name_t) const json
_throws(std::out_of_range); | |
| #endif | | #endif | |
| JSONNode & operator[](const json_string & name_t) json_nothrow; | | JSONNode & operator[](const json_string & name_t) json_nothrow; | |
| | | | |
| skipping to change at line 172 | | skipping to change at line 212 | |
| JSONNode & operator = (const JSONNode &) json_nothrow; | | JSONNode & operator = (const JSONNode &) json_nothrow; | |
| | | | |
| DECLARE_FOR_ALL_TYPES_CONST(bool operator ==) | | DECLARE_FOR_ALL_TYPES_CONST(bool operator ==) | |
| DECLARE_FOR_ALL_TYPES_CONST(bool operator !=) | | DECLARE_FOR_ALL_TYPES_CONST(bool operator !=) | |
| | | | |
| void nullify(void) json_nothrow; | | void nullify(void) json_nothrow; | |
| void swap(JSONNode & other) json_nothrow; | | void swap(JSONNode & other) json_nothrow; | |
| void merge(JSONNode & other) json_nothrow json_cold; | | void merge(JSONNode & other) json_nothrow json_cold; | |
| void merge(unsigned int num, ...) json_nothrow json_cold; | | void merge(unsigned int num, ...) json_nothrow json_cold; | |
| JSONNode duplicate(void) const json_nothrow; | | JSONNode duplicate(void) const json_nothrow; | |
|
| void cast(char newtype) json_nothrow; | | | |
| | | | |
| //iterator | | //iterator | |
| #ifdef JSON_ITERATORS | | #ifdef JSON_ITERATORS | |
| #ifndef JSON_LIBRARY | | #ifndef JSON_LIBRARY | |
| #define json_iterator_ptr(iter) iter.it | | #define json_iterator_ptr(iter) iter.it | |
| #define ptr_to_json_iterator(iter) json_iterator(iter) | | #define ptr_to_json_iterator(iter) json_iterator(iter) | |
|
| struct iterator { | | | |
| inline iterator& operator ++(void) json_nothrow { + | | | |
| +it; return *this; } | | | |
| inline iterator& operator --(void) json_nothrow { - | | | |
| -it; return *this; } | | | |
| inline iterator& operator +=(long i) json_nothrow { | | | |
| it += i; return *this; } | | | |
| inline iterator& operator -=(long i) json_nothrow { | | | |
| it -= i; return *this; } | | | |
| inline iterator operator ++(int) json_nothrow { | | | |
| iterator result(*this); | | | |
| ++it; | | | |
| return result; | | | |
| } | | | |
| inline iterator operator --(int) json_nothrow { | | | |
| iterator result(*this); | | | |
| --it; | | | |
| return result; | | | |
| } | | | |
| inline iterator operator +(long i) const json_nothr | | | |
| ow { | | | |
| iterator result(*this); | | | |
| result.it += i; | | | |
| return result; | | | |
| } | | | |
| inline iterator operator -(long i) const json_nothr | | | |
| ow { | | | |
| iterator result(*this); | | | |
| result.it -= i; | | | |
| return result; | | | |
| } | | | |
| inline JSONNode& operator [](size_t pos) const json | | | |
| _nothrow { return *it[pos]; }; | | | |
| inline JSONNode& operator *(void) const json_nothro | | | |
| w { return *(*it); } | | | |
| inline bool operator == (const iterator & other) co | | | |
| nst json_nothrow { return it == other.it; } | | | |
| inline bool operator != (const iterator & other) co | | | |
| nst json_nothrow { return it != other.it; } | | | |
| inline bool operator > (const iterator & other) con | | | |
| st json_nothrow { return it > other.it; } | | | |
| inline bool operator >= (const iterator & other) co | | | |
| nst json_nothrow { return it >= other.it; } | | | |
| inline bool operator < (const iterator & other) con | | | |
| st json_nothrow { return it < other.it; } | | | |
| inline bool operator <= (const iterator & other) co | | | |
| nst json_nothrow { return it <= other.it; } | | | |
| inline iterator & operator = (const iterator & orig | | | |
| ) json_nothrow { it = orig.it; return *this; } | | | |
| iterator (const iterator & orig) json_nothrow : it( | | | |
| orig.it) {} | | | |
| private: | | | |
| JSONNode ** it; | | | |
| iterator(JSONNode ** starter) json_nothrow : it(sta | | | |
| rter) {} | | | |
| friend class JSONNode; | | | |
| }; | | | |
| typedef iterator json_iterator; | | | |
| | | | |
|
| | | struct iterator; | |
| struct const_iterator { | | struct const_iterator { | |
| inline const_iterator& operator ++(void) json_nothr
ow { ++it; return *this; } | | inline const_iterator& operator ++(void) json_nothr
ow { ++it; return *this; } | |
| inline const_iterator& operator --(void) json_nothr
ow { --it; return *this; } | | inline const_iterator& operator --(void) json_nothr
ow { --it; return *this; } | |
| inline const_iterator& operator +=(long i) json_not
hrow { it += i; return *this; } | | inline const_iterator& operator +=(long i) json_not
hrow { it += i; return *this; } | |
| inline const_iterator& operator -=(long i) json_not
hrow { it -= i; return *this; } | | inline const_iterator& operator -=(long i) json_not
hrow { it -= i; return *this; } | |
| inline const_iterator operator ++(int) json_nothrow
{ | | inline const_iterator operator ++(int) json_nothrow
{ | |
| const_iterator result(*this); | | const_iterator result(*this); | |
| ++it; | | ++it; | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| skipping to change at line 248 | | skipping to change at line 247 | |
| result.it += i; | | result.it += i; | |
| return result; | | return result; | |
| } | | } | |
| inline const_iterator operator -(long i) const json
_nothrow { | | inline const_iterator operator -(long i) const json
_nothrow { | |
| const_iterator result(*this); | | const_iterator result(*this); | |
| result.it -= i; | | result.it -= i; | |
| return result; | | return result; | |
| } | | } | |
| inline const JSONNode& operator [](size_t pos) cons
t json_nothrow { return const_cast<const JSONNode&>(*it[pos]); }; | | inline const JSONNode& operator [](size_t pos) cons
t json_nothrow { return const_cast<const JSONNode&>(*it[pos]); }; | |
| inline const JSONNode& operator *(void) const json_
nothrow { return const_cast<const JSONNode&>(*(*it)); } | | inline const JSONNode& operator *(void) const json_
nothrow { return const_cast<const JSONNode&>(*(*it)); } | |
|
| | | inline const JSONNode* operator ->(void) const json
_nothrow { return const_cast<const JSONNode*>(*it); } | |
| inline bool operator == (const const_iterator & oth
er) const json_nothrow { return it == other.it; } | | inline bool operator == (const const_iterator & oth
er) const json_nothrow { return it == other.it; } | |
| inline bool operator != (const const_iterator & oth
er) const json_nothrow { return it != other.it; } | | inline bool operator != (const const_iterator & oth
er) const json_nothrow { return it != other.it; } | |
| inline bool operator > (const const_iterator & othe
r) const json_nothrow { return it > other.it; } | | inline bool operator > (const const_iterator & othe
r) const json_nothrow { return it > other.it; } | |
| inline bool operator >= (const const_iterator & oth
er) const json_nothrow { return it >= other.it; } | | inline bool operator >= (const const_iterator & oth
er) const json_nothrow { return it >= other.it; } | |
| inline bool operator < (const const_iterator & othe
r) const json_nothrow { return it < other.it; } | | inline bool operator < (const const_iterator & othe
r) const json_nothrow { return it < other.it; } | |
| inline bool operator <= (const const_iterator & oth
er) const json_nothrow { return it <= other.it; } | | inline bool operator <= (const const_iterator & oth
er) const json_nothrow { return it <= other.it; } | |
|
| | | | |
| | | inline bool operator == (const iterator & other) co | |
| | | nst json_nothrow { return it == other.it; } | |
| | | inline bool operator != (const iterator & other) co | |
| | | nst json_nothrow { return it != other.it; } | |
| | | inline bool operator > (const iterator & other) con | |
| | | st json_nothrow { return it > other.it; } | |
| | | inline bool operator >= (const iterator & other) co | |
| | | nst json_nothrow { return it >= other.it; } | |
| | | inline bool operator < (const iterator & other) con | |
| | | st json_nothrow { return it < other.it; } | |
| | | inline bool operator <= (const iterator & other) co | |
| | | nst json_nothrow { return it <= other.it; } | |
| | | | |
| inline const_iterator & operator =(const const_iter
ator & orig) json_nothrow { it = orig.it; return *this; } | | inline const_iterator & operator =(const const_iter
ator & orig) json_nothrow { it = orig.it; return *this; } | |
| const_iterator (const const_iterator & orig) json_n
othrow : it(orig.it) {} | | const_iterator (const const_iterator & orig) json_n
othrow : it(orig.it) {} | |
| private: | | private: | |
| JSONNode ** it; | | JSONNode ** it; | |
| const_iterator(JSONNode ** starter) : it(starter) {
} | | const_iterator(JSONNode ** starter) : it(starter) {
} | |
| friend class JSONNode; | | friend class JSONNode; | |
|
| | | friend struct iterator; | |
| }; | | }; | |
| const_iterator begin(void) const json_nothrow; | | const_iterator begin(void) const json_nothrow; | |
| const_iterator end(void) const json_nothrow; | | const_iterator end(void) const json_nothrow; | |
| | | | |
|
| struct reverse_iterator { | | struct iterator { | |
| inline reverse_iterator& operator ++(void) json_not | | inline iterator& operator ++(void) json_nothrow { + | |
| hrow { --it; return *this; } | | +it; return *this; } | |
| inline reverse_iterator& operator --(void) json_not | | inline iterator& operator --(void) json_nothrow { - | |
| hrow { ++it; return *this; } | | -it; return *this; } | |
| inline reverse_iterator& operator +=(long i) json_n | | inline iterator& operator +=(long i) json_nothrow { | |
| othrow { it -= i; return *this; } | | it += i; return *this; } | |
| inline reverse_iterator& operator -=(long i) json_n | | inline iterator& operator -=(long i) json_nothrow { | |
| othrow { it += i; return *this; } | | it -= i; return *this; } | |
| inline reverse_iterator operator ++(int) json_nothr | | inline iterator operator ++(int) json_nothrow { | |
| ow { | | iterator result(*this); | |
| reverse_iterator result(*this); | | | |
| --it; | | | |
| return result; | | | |
| } | | | |
| inline reverse_iterator operator --(int) json_nothr | | | |
| ow { | | | |
| reverse_iterator result(*this); | | | |
| ++it; | | ++it; | |
| return result; | | return result; | |
| } | | } | |
|
| inline reverse_iterator operator +(long i) const js | | inline iterator operator --(int) json_nothrow { | |
| on_nothrow { | | iterator result(*this); | |
| reverse_iterator result(*this); | | --it; | |
| result.it -= i; | | | |
| return result; | | return result; | |
| } | | } | |
|
| inline reverse_iterator operator -(long i) const js | | inline iterator operator +(long i) const json_nothr | |
| on_nothrow { | | ow { | |
| reverse_iterator result(*this); | | iterator result(*this); | |
| result.it += i; | | result.it += i; | |
| return result; | | return result; | |
| } | | } | |
|
| | | inline iterator operator -(long i) const json_nothr | |
| | | ow { | |
| | | iterator result(*this); | |
| | | result.it -= i; | |
| | | return result; | |
| | | } | |
| inline JSONNode& operator [](size_t pos) const json
_nothrow { return *it[pos]; }; | | inline JSONNode& operator [](size_t pos) const json
_nothrow { return *it[pos]; }; | |
| inline JSONNode& operator *(void) const json_nothro
w { return *(*it); } | | inline JSONNode& operator *(void) const json_nothro
w { return *(*it); } | |
|
| inline bool operator == (const reverse_iterator & o | | inline JSONNode* operator ->(void) const json_nothr | |
| ther) const json_nothrow { return it == other.it; } | | ow { return *it; } | |
| inline bool operator != (const reverse_iterator & o | | inline bool operator == (const iterator & other) co | |
| ther) const json_nothrow { return it != other.it; } | | nst json_nothrow { return it == other.it; } | |
| inline bool operator < (const reverse_iterator & ot | | inline bool operator != (const iterator & other) co | |
| her) const json_nothrow { return it > other.it; } | | nst json_nothrow { return it != other.it; } | |
| inline bool operator <= (const reverse_iterator & o | | inline bool operator > (const iterator & other) con | |
| ther) const json_nothrow { return it >= other.it; } | | st json_nothrow { return it > other.it; } | |
| inline bool operator > (const reverse_iterator & ot | | inline bool operator >= (const iterator & other) co | |
| her) const json_nothrow { return it < other.it; } | | nst json_nothrow { return it >= other.it; } | |
| inline bool operator >= (const reverse_iterator & o | | inline bool operator < (const iterator & other) con | |
| ther) const json_nothrow { return it <= other.it; } | | st json_nothrow { return it < other.it; } | |
| inline reverse_iterator & operator = (const reverse | | inline bool operator <= (const iterator & other) co | |
| _iterator & orig) json_nothrow { it = orig.it; return *this; } | | nst json_nothrow { return it <= other.it; } | |
| reverse_iterator (const reverse_iterator & orig) js | | inline iterator & operator = (const iterator & orig | |
| on_nothrow : it(orig.it) {} | | ) json_nothrow { it = orig.it; return *this; } | |
| | | | |
| | | inline bool operator == (const const_iterator & oth | |
| | | er) const json_nothrow { return it == other.it; } | |
| | | inline bool operator != (const const_iterator & oth | |
| | | er) const json_nothrow { return it != other.it; } | |
| | | inline bool operator > (const const_iterator & othe | |
| | | r) const json_nothrow { return it > other.it; } | |
| | | inline bool operator >= (const const_iterator & oth | |
| | | er) const json_nothrow { return it >= other.it; } | |
| | | inline bool operator < (const const_iterator & othe | |
| | | r) const json_nothrow { return it < other.it; } | |
| | | inline bool operator <= (const const_iterator & oth | |
| | | er) const json_nothrow { return it <= other.it; } | |
| | | inline iterator & operator = (const const_iterator | |
| | | & orig) json_nothrow { it = orig.it; return *this; } | |
| | | | |
| | | iterator (const iterator & orig) json_nothrow : it( | |
| | | orig.it) {} | |
| | | inline operator const_iterator() const json_nothrow | |
| | | { return const_iterator(it); } | |
| private: | | private: | |
| JSONNode ** it; | | JSONNode ** it; | |
|
| reverse_iterator(JSONNode ** starter) json_nothrow
: it(starter) {} | | iterator(JSONNode ** starter) json_nothrow : it(sta
rter) {} | |
| friend class JSONNode; | | friend class JSONNode; | |
|
| | | friend struct const_iterator; | |
| }; | | }; | |
|
| reverse_iterator rbegin(void) json_nothrow; | | typedef iterator json_iterator; | |
| reverse_iterator rend(void) json_nothrow; | | | |
| | | | |
|
| | | struct reverse_iterator; | |
| struct reverse_const_iterator { | | struct reverse_const_iterator { | |
| inline reverse_const_iterator& operator ++(void) js
on_nothrow{ --it; return *this; } | | inline reverse_const_iterator& operator ++(void) js
on_nothrow{ --it; return *this; } | |
| inline reverse_const_iterator& operator --(void) js
on_nothrow{ ++it; return *this; } | | inline reverse_const_iterator& operator --(void) js
on_nothrow{ ++it; return *this; } | |
| inline reverse_const_iterator& operator +=(long i)
json_nothrow{ it -= i; return *this; } | | inline reverse_const_iterator& operator +=(long i)
json_nothrow{ it -= i; return *this; } | |
| inline reverse_const_iterator& operator -=(long i)
json_nothrow{ it += i; return *this; } | | inline reverse_const_iterator& operator -=(long i)
json_nothrow{ it += i; return *this; } | |
| inline reverse_const_iterator operator ++(int) json
_nothrow{ | | inline reverse_const_iterator operator ++(int) json
_nothrow{ | |
| reverse_const_iterator result(*this); | | reverse_const_iterator result(*this); | |
| --it; | | --it; | |
| return result; | | return result; | |
| } | | } | |
| | | | |
| skipping to change at line 334 | | skipping to change at line 355 | |
| result.it -= i; | | result.it -= i; | |
| return result; | | return result; | |
| } | | } | |
| inline reverse_const_iterator operator -(long i) co
nst json_nothrow { | | inline reverse_const_iterator operator -(long i) co
nst json_nothrow { | |
| reverse_const_iterator result(*this); | | reverse_const_iterator result(*this); | |
| result.it += i; | | result.it += i; | |
| return result; | | return result; | |
| } | | } | |
| inline const JSONNode& operator [](size_t pos) cons
t json_nothrow { return const_cast<const JSONNode&>(*it[pos]); }; | | inline const JSONNode& operator [](size_t pos) cons
t json_nothrow { return const_cast<const JSONNode&>(*it[pos]); }; | |
| inline const JSONNode& operator *(void) const json_
nothrow { return const_cast<const JSONNode&>(*(*it)); } | | inline const JSONNode& operator *(void) const json_
nothrow { return const_cast<const JSONNode&>(*(*it)); } | |
|
| | | inline const JSONNode* operator ->(void) const json
_nothrow { return const_cast<const JSONNode*>(*it); } | |
| inline bool operator == (const reverse_const_iterat
or & other) const json_nothrow { return it == other.it; } | | inline bool operator == (const reverse_const_iterat
or & other) const json_nothrow { return it == other.it; } | |
| inline bool operator != (const reverse_const_iterat
or & other) const json_nothrow { return it != other.it; } | | inline bool operator != (const reverse_const_iterat
or & other) const json_nothrow { return it != other.it; } | |
| inline bool operator < (const reverse_const_iterato
r & other) const json_nothrow { return it > other.it; } | | inline bool operator < (const reverse_const_iterato
r & other) const json_nothrow { return it > other.it; } | |
| inline bool operator <= (const reverse_const_iterat
or & other) const json_nothrow { return it >= other.it; } | | inline bool operator <= (const reverse_const_iterat
or & other) const json_nothrow { return it >= other.it; } | |
| inline bool operator > (const reverse_const_iterato
r & other) const json_nothrow { return it < other.it; } | | inline bool operator > (const reverse_const_iterato
r & other) const json_nothrow { return it < other.it; } | |
| inline bool operator >= (const reverse_const_iterat
or & other) const json_nothrow { return it <= other.it; } | | inline bool operator >= (const reverse_const_iterat
or & other) const json_nothrow { return it <= other.it; } | |
|
| | | | |
| | | inline bool operator == (const reverse_iterator & o | |
| | | ther) const json_nothrow { return it == other.it; } | |
| | | inline bool operator != (const reverse_iterator & o | |
| | | ther) const json_nothrow { return it != other.it; } | |
| | | inline bool operator < (const reverse_iterator & ot | |
| | | her) const json_nothrow { return it > other.it; } | |
| | | inline bool operator <= (const reverse_iterator & o | |
| | | ther) const json_nothrow { return it >= other.it; } | |
| | | inline bool operator > (const reverse_iterator & ot | |
| | | her) const json_nothrow { return it < other.it; } | |
| | | inline bool operator >= (const reverse_iterator & o | |
| | | ther) const json_nothrow { return it <= other.it; } | |
| | | | |
| inline reverse_const_iterator & operator = (const r
everse_const_iterator & orig) json_nothrow { it = orig.it; return *this; } | | inline reverse_const_iterator & operator = (const r
everse_const_iterator & orig) json_nothrow { it = orig.it; return *this; } | |
| reverse_const_iterator (const reverse_const_iterato
r & orig) json_nothrow : it(orig.it) {} | | reverse_const_iterator (const reverse_const_iterato
r & orig) json_nothrow : it(orig.it) {} | |
| private: | | private: | |
| JSONNode ** it; | | JSONNode ** it; | |
| reverse_const_iterator(JSONNode ** starter) json_no
throw : it(starter) {} | | reverse_const_iterator(JSONNode ** starter) json_no
throw : it(starter) {} | |
| friend class JSONNode; | | friend class JSONNode; | |
|
| | | friend struct reverse_iterator; | |
| }; | | }; | |
| reverse_const_iterator rbegin(void) const json_nothrow; | | reverse_const_iterator rbegin(void) const json_nothrow; | |
| reverse_const_iterator rend(void) const json_nothrow; | | reverse_const_iterator rend(void) const json_nothrow; | |
| | | | |
|
| | | struct reverse_iterator { | |
| | | inline reverse_iterator& operator ++(void) json_not | |
| | | hrow { --it; return *this; } | |
| | | inline reverse_iterator& operator --(void) json_not | |
| | | hrow { ++it; return *this; } | |
| | | inline reverse_iterator& operator +=(long i) json_n | |
| | | othrow { it -= i; return *this; } | |
| | | inline reverse_iterator& operator -=(long i) json_n | |
| | | othrow { it += i; return *this; } | |
| | | inline reverse_iterator operator ++(int) json_nothr | |
| | | ow { | |
| | | reverse_iterator result(*this); | |
| | | --it; | |
| | | return result; | |
| | | } | |
| | | inline reverse_iterator operator --(int) json_nothr | |
| | | ow { | |
| | | reverse_iterator result(*this); | |
| | | ++it; | |
| | | return result; | |
| | | } | |
| | | inline reverse_iterator operator +(long i) const js | |
| | | on_nothrow { | |
| | | reverse_iterator result(*this); | |
| | | result.it -= i; | |
| | | return result; | |
| | | } | |
| | | inline reverse_iterator operator -(long i) const js | |
| | | on_nothrow { | |
| | | reverse_iterator result(*this); | |
| | | result.it += i; | |
| | | return result; | |
| | | } | |
| | | inline JSONNode& operator [](size_t pos) const json | |
| | | _nothrow { return *it[pos]; }; | |
| | | inline JSONNode& operator *(void) const json_nothro | |
| | | w { return *(*it); } | |
| | | inline JSONNode* operator ->(void) const json_nothr | |
| | | ow { return *it; } | |
| | | inline bool operator == (const reverse_iterator & o | |
| | | ther) const json_nothrow { return it == other.it; } | |
| | | inline bool operator != (const reverse_iterator & o | |
| | | ther) const json_nothrow { return it != other.it; } | |
| | | inline bool operator < (const reverse_iterator & ot | |
| | | her) const json_nothrow { return it > other.it; } | |
| | | inline bool operator <= (const reverse_iterator & o | |
| | | ther) const json_nothrow { return it >= other.it; } | |
| | | inline bool operator > (const reverse_iterator & ot | |
| | | her) const json_nothrow { return it < other.it; } | |
| | | inline bool operator >= (const reverse_iterator & o | |
| | | ther) const json_nothrow { return it <= other.it; } | |
| | | | |
| | | inline bool operator == (const reverse_const_iterat | |
| | | or & other) const json_nothrow { return it == other.it; } | |
| | | inline bool operator != (const reverse_const_iterat | |
| | | or & other) const json_nothrow { return it != other.it; } | |
| | | inline bool operator < (const reverse_const_iterato | |
| | | r & other) const json_nothrow { return it > other.it; } | |
| | | inline bool operator <= (const reverse_const_iterat | |
| | | or & other) const json_nothrow { return it >= other.it; } | |
| | | inline bool operator > (const reverse_const_iterato | |
| | | r & other) const json_nothrow { return it < other.it; } | |
| | | inline bool operator >= (const reverse_const_iterat | |
| | | or & other) const json_nothrow { return it <= other.it; } | |
| | | | |
| | | inline reverse_iterator & operator = (const reverse | |
| | | _iterator & orig) json_nothrow { it = orig.it; return *this; } | |
| | | reverse_iterator (const reverse_iterator & orig) js | |
| | | on_nothrow : it(orig.it) {} | |
| | | inline operator reverse_const_iterator() const json | |
| | | _nothrow { return reverse_const_iterator(it); } | |
| | | private: | |
| | | JSONNode ** it; | |
| | | reverse_iterator(JSONNode ** starter) json_nothrow | |
| | | : it(starter) {} | |
| | | friend class JSONNode; | |
| | | friend struct reverse_const_iterator; | |
| | | }; | |
| | | reverse_iterator rbegin(void) json_nothrow; | |
| | | reverse_iterator rend(void) json_nothrow; | |
| | | | |
| const_iterator find(const json_string & name_t) const json
_nothrow; | | const_iterator find(const json_string & name_t) const json
_nothrow; | |
| #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | | #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | |
| const_iterator find_nocase(const json_string & name
_t) const json_nothrow; | | const_iterator find_nocase(const json_string & name
_t) const json_nothrow; | |
| #endif | | #endif | |
| | | | |
| reverse_iterator erase(reverse_iterator pos) json_nothrow; | | reverse_iterator erase(reverse_iterator pos) json_nothrow; | |
| reverse_iterator erase(reverse_iterator start, const rever
se_iterator & end) json_nothrow; | | reverse_iterator erase(reverse_iterator start, const rever
se_iterator & end) json_nothrow; | |
| | | | |
| iterator insert(iterator pos, const JSONNode & x) json_not
hrow; | | iterator insert(iterator pos, const JSONNode & x) json_not
hrow; | |
| reverse_iterator insert(reverse_iterator pos, const JSONNo
de & x) json_nothrow; | | reverse_iterator insert(reverse_iterator pos, const JSONNo
de & x) json_nothrow; | |
| | | | |
| skipping to change at line 432 | | skipping to change at line 517 | |
| static int getChildrenDeallocationCount(void); | | static int getChildrenDeallocationCount(void); | |
| static void incAllocCount(void); | | static void incAllocCount(void); | |
| static void decAllocCount(void); | | static void decAllocCount(void); | |
| static void incinternalAllocCount(void); | | static void incinternalAllocCount(void); | |
| static void decinternalAllocCount(void); | | static void decinternalAllocCount(void); | |
| static void incChildrenAllocCount(void); | | static void incChildrenAllocCount(void); | |
| static void decChildrenAllocCount(void); | | static void decChildrenAllocCount(void); | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_WRITE_PRIORITY | | #ifdef JSON_WRITE_PRIORITY | |
|
| json_string write(void) json_nothrow json_write_priority; | | #ifdef JSON_LESS_MEMORY | |
| json_string write_formatted(void) json_nothrow json_write_priorit | | #define DEFAULT_APPROX_SIZE 8 | |
| y; | | #define DEFAULT_APPROX_SIZE_FORMATTED 16 | |
| | | #else | |
| | | #define DEFAULT_APPROX_SIZE 1024 | |
| | | #define DEFAULT_APPROX_SIZE_FORMATTED 2048 | |
| | | #endif | |
| | | json_string write(size_t approxsize = DEFAULT_APPROX_SIZE) const | |
| | | json_nothrow json_write_priority; | |
| | | json_string write_formatted(size_t approxsize = DEFAULT_APPROX_SI | |
| | | ZE_FORMATTED) const json_nothrow json_write_priority; | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_DEBUG | | #ifdef JSON_DEBUG | |
| #ifndef JSON_LIBRARY | | #ifndef JSON_LIBRARY | |
| JSONNode dump(void) const json_nothrow; | | JSONNode dump(void) const json_nothrow; | |
| #endif | | #endif | |
| #endif | | #endif | |
| static void deleteJSONNode(JSONNode * ptr) json_nothrow json_hot; | | static void deleteJSONNode(JSONNode * ptr) json_nothrow json_hot; | |
| static JSONNode * newJSONNode_Shallow(const JSONNode & orig) json_hot; | | static JSONNode * newJSONNode_Shallow(const JSONNode & orig) json_hot; | |
|
| | | | |
| | | #define DECLARE_CAST_OP(type) operator type() | |
| | | //DECLARE_FOR_ALL_CAST_TYPES_CONST(DECLARE_CAST_OP) | |
| JSON_PRIVATE | | JSON_PRIVATE | |
| static JSONNode * newJSONNode(const JSONNode & orig JSON_MUTEX_COPY
_DECL2) json_hot; | | static JSONNode * newJSONNode(const JSONNode & orig JSON_MUTEX_COPY
_DECL2) json_hot; | |
| static JSONNode * newJSONNode(internalJSONNode * internal_t) json_hot; | | static JSONNode * newJSONNode(internalJSONNode * internal_t) json_hot; | |
| #ifdef JSON_READ_PRIORITY | | #ifdef JSON_READ_PRIORITY | |
| //used by JSONWorker | | //used by JSONWorker | |
| JSONNode(const json_string & unparsed) json_nothrow : internal(in
ternalJSONNode::newInternal(unparsed)){ //root, specialized because it can
only be array or node | | JSONNode(const json_string & unparsed) json_nothrow : internal(in
ternalJSONNode::newInternal(unparsed)){ //root, specialized because it can
only be array or node | |
| incAllocCount(); | | incAllocCount(); | |
| } | | } | |
| #endif | | #endif | |
| JSONNode(internalJSONNode * internal_t) json_nothrow : internal(interna
l_t){ //do not increment anything, this is only used in one case and it's a
lready taken care of | | JSONNode(internalJSONNode * internal_t) json_nothrow : internal(interna
l_t){ //do not increment anything, this is only used in one case and it's a
lready taken care of | |
| | | | |
| skipping to change at line 494 | | skipping to change at line 589 | |
| mutable internalJSONNode * internal; | | mutable internalJSONNode * internal; | |
| friend class JSONWorker; | | friend class JSONWorker; | |
| friend class internalJSONNode; | | friend class internalJSONNode; | |
| }; | | }; | |
| | | | |
| /* | | /* | |
| Implementations are here to keep the class declaration cleaner. They c
an't be placed in a different | | Implementations are here to keep the class declaration cleaner. They c
an't be placed in a different | |
| file because they are inlined. | | file because they are inlined. | |
| */ | | */ | |
| | | | |
|
| | | #define CAST_OP(type)\ | |
| | | inline JSONNode::operator type() const json_nothrow {\ | |
| | | return static_cast<type>(*internal);\ | |
| | | } | |
| | | //IMPLEMENT_FOR_ALL_TYPES(CAST_OP) | |
| | | | |
| inline JSONNode::JSONNode(char mytype) json_nothrow : internal(internalJSON
Node::newInternal(mytype)){ | | inline JSONNode::JSONNode(char mytype) json_nothrow : internal(internalJSON
Node::newInternal(mytype)){ | |
| JSON_ASSERT((mytype == JSON_NULL) || | | JSON_ASSERT((mytype == JSON_NULL) || | |
| (mytype == JSON_STRING) || | | (mytype == JSON_STRING) || | |
| (mytype == JSON_NUMBER) || | | (mytype == JSON_NUMBER) || | |
| (mytype == JSON_BOOL) || | | (mytype == JSON_BOOL) || | |
| (mytype == JSON_ARRAY) || | | (mytype == JSON_ARRAY) || | |
| (mytype == JSON_NODE), JSON_TEXT("Not a proper JSON
type")); | | (mytype == JSON_NODE), JSON_TEXT("Not a proper JSON
type")); | |
| incAllocCount(); | | incAllocCount(); | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 566 | | skipping to change at line 667 | |
| makeUniqueInternal(); | | makeUniqueInternal(); | |
| internal -> setcomment(newname); | | internal -> setcomment(newname); | |
| } | | } | |
| | | | |
| inline json_string JSONNode::get_comment(void) const json_nothrow { | | inline json_string JSONNode::get_comment(void) const json_nothrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
| return internal -> getcomment(); | | return internal -> getcomment(); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
|
| inline json_string JSONNode::as_string(void) const json_nothrow { | | //#ifdef JSON_DEPRECATED_FUNCTIONS | |
| JSON_CHECK_INTERNAL(); | | inline json_string JSONNode::as_string(void) const json_nothrow { | |
| return internal -> as_string(); | | JSON_CHECK_INTERNAL(); | |
| } | | return static_cast<json_string>(*internal); | |
| | | } | |
| | | | |
|
| inline long JSONNode::as_int(void) const json_nothrow { | | inline json_int_t JSONNode::as_int(void) const json_nothrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
| return internal -> as_int(); | | return static_cast<json_int_t>(*internal); | |
| } | | } | |
| | | | |
|
| inline json_number JSONNode::as_float(void) const json_nothrow { | | inline json_number JSONNode::as_float(void) const json_nothrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
| return internal -> as_float(); | | return static_cast<json_number>(*internal); | |
| } | | } | |
| | | | |
|
| inline bool JSONNode::as_bool(void) const json_nothrow { | | inline bool JSONNode::as_bool(void) const json_nothrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
| return internal -> as_bool(); | | return static_cast<bool>(*internal); | |
| } | | } | |
| | | //#endif | |
| | | | |
| #ifdef JSON_BINARY | | #ifdef JSON_BINARY | |
| inline void JSONNode::set_binary(const unsigned char * bin, size_t byte
s) json_nothrow{ | | inline void JSONNode::set_binary(const unsigned char * bin, size_t byte
s) json_nothrow{ | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
| *this = JSONBase64::json_encode64(bin, bytes); | | *this = JSONBase64::json_encode64(bin, bytes); | |
| } | | } | |
| | | | |
| inline std::string JSONNode::as_binary(void) const json_nothrow { | | inline std::string JSONNode::as_binary(void) const json_nothrow { | |
|
| JSON_ASSERT_SAFE(type() == JSON_STRING, JSON_TEXT("using as_binar
y for a non-string type"), return EMPTY_STD_STRING;); | | JSON_ASSERT_SAFE(type() == JSON_STRING, JSON_TEXT("using as_binar
y for a non-string type"), return json_global(EMPTY_STD_STRING);); | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
| return JSONBase64::json_decode64(as_string()); | | return JSONBase64::json_decode64(as_string()); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
|
| inline JSONNode & JSONNode::operator[](const json_string & name_t) json_not
hrow{ | | inline JSONNode & JSONNode::operator[](const json_string & name_t) json_not
hrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
| makeUniqueInternal(); | | makeUniqueInternal(); | |
| return *(*(internal -> at(name_t))); | | return *(*(internal -> at(name_t))); | |
| } | | } | |
| | | | |
| inline const JSONNode & JSONNode::operator[](const json_string & name_t) co
nst json_nothrow { | | inline const JSONNode & JSONNode::operator[](const json_string & name_t) co
nst json_nothrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
| return *(*(internal -> at(name_t))); | | return *(*(internal -> at(name_t))); | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 738 | | skipping to change at line 840 | |
| #ifdef JSON_REF_COUNT | | #ifdef JSON_REF_COUNT | |
| inline void JSONNode::makeUniqueInternal() json_nothrow { //makes inter
nal it's own | | inline void JSONNode::makeUniqueInternal() json_nothrow { //makes inter
nal it's own | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
| internal = internal -> makeUnique(); //might return itself or a
new one that's exactly the same | | internal = internal -> makeUnique(); //might return itself or a
new one that's exactly the same | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_ITERATORS | | #ifdef JSON_ITERATORS | |
| inline JSONNode::json_iterator JSONNode::begin(void) json_nothrow { | | inline JSONNode::json_iterator JSONNode::begin(void) json_nothrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
|
| JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEX
T("iterating a non-iteratable node")); | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_glo
bal(ERROR_NON_ITERATABLE) + JSON_TEXT("begin")); | |
| makeUniqueInternal(); | | makeUniqueInternal(); | |
| return json_iterator(internal -> begin()); | | return json_iterator(internal -> begin()); | |
| } | | } | |
| | | | |
| inline JSONNode::json_iterator JSONNode::end(void) json_nothrow { | | inline JSONNode::json_iterator JSONNode::end(void) json_nothrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
|
| JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEX
T("iterating a non-iteratable node")); | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, json_glo
bal(ERROR_NON_ITERATABLE) + JSON_TEXT("end")); | |
| makeUniqueInternal(); | | makeUniqueInternal(); | |
| return json_iterator(internal -> end()); | | return json_iterator(internal -> end()); | |
| } | | } | |
| | | | |
| #ifndef JSON_LIBRARY | | #ifndef JSON_LIBRARY | |
| inline JSONNode::const_iterator JSONNode::begin(void) const json_
nothrow { | | inline JSONNode::const_iterator JSONNode::begin(void) const json_
nothrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
|
| JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J
SON_TEXT("iterating a non-iteratable node")); | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, j
son_global(ERROR_NON_ITERATABLE) + JSON_TEXT("begin")); | |
| return JSONNode::const_iterator(internal -> begin()); | | return JSONNode::const_iterator(internal -> begin()); | |
| } | | } | |
| | | | |
| inline JSONNode::const_iterator JSONNode::end(void) const json_no
throw { | | inline JSONNode::const_iterator JSONNode::end(void) const json_no
throw { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
|
| JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J
SON_TEXT("iterating a non-iteratable node")); | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, j
son_global(ERROR_NON_ITERATABLE) + JSON_TEXT("end")); | |
| return JSONNode::const_iterator(internal -> end()); | | return JSONNode::const_iterator(internal -> end()); | |
| } | | } | |
| | | | |
| inline JSONNode::reverse_iterator JSONNode::rbegin(void) json_not
hrow { | | inline JSONNode::reverse_iterator JSONNode::rbegin(void) json_not
hrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
|
| JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J
SON_TEXT("iterating a non-iteratable node")); | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, j
son_global(ERROR_NON_ITERATABLE) + JSON_TEXT("rbegin")); | |
| makeUniqueInternal(); | | makeUniqueInternal(); | |
| return JSONNode::reverse_iterator(internal -> end() - 1); | | return JSONNode::reverse_iterator(internal -> end() - 1); | |
| } | | } | |
| | | | |
| inline JSONNode::reverse_iterator JSONNode::rend(void) json_nothr
ow { | | inline JSONNode::reverse_iterator JSONNode::rend(void) json_nothr
ow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
|
| JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J
SON_TEXT("iterating a non-iteratable node")); | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, j
son_global(ERROR_NON_ITERATABLE) + JSON_TEXT("rend")); | |
| makeUniqueInternal(); | | makeUniqueInternal(); | |
| return JSONNode::reverse_iterator(internal -> begin() - 1)
; | | return JSONNode::reverse_iterator(internal -> begin() - 1)
; | |
| } | | } | |
| | | | |
| inline JSONNode::reverse_const_iterator JSONNode::rbegin(void) co
nst json_nothrow { | | inline JSONNode::reverse_const_iterator JSONNode::rbegin(void) co
nst json_nothrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
|
| JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J
SON_TEXT("iterating a non-iteratable node")); | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, j
son_global(ERROR_NON_ITERATABLE) + JSON_TEXT("rbegin")); | |
| return JSONNode::reverse_const_iterator(internal -> end()
- 1); | | return JSONNode::reverse_const_iterator(internal -> end()
- 1); | |
| } | | } | |
| | | | |
| inline JSONNode::reverse_const_iterator JSONNode::rend(void) cons
t json_nothrow { | | inline JSONNode::reverse_const_iterator JSONNode::rend(void) cons
t json_nothrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
|
| JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, J
SON_TEXT("iterating a non-iteratable node")); | | JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, j
son_global(ERROR_NON_ITERATABLE) + JSON_TEXT("rend")); | |
| return JSONNode::reverse_const_iterator(internal -> begin(
) - 1); | | return JSONNode::reverse_const_iterator(internal -> begin(
) - 1); | |
| } | | } | |
| | | | |
| inline JSONNode::iterator JSONNode::insert(json_iterator pos, con
st const_iterator & _start, const const_iterator & _end) json_nothrow { | | inline JSONNode::iterator JSONNode::insert(json_iterator pos, con
st const_iterator & _start, const const_iterator & _end) json_nothrow { | |
| return insertFFF(pos, _start.it, _end.it); | | return insertFFF(pos, _start.it, _end.it); | |
| } | | } | |
| | | | |
| inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat
or pos, const const_iterator & _start, const const_iterator & _end) json_no
throw { | | inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat
or pos, const const_iterator & _start, const const_iterator & _end) json_no
throw { | |
| return insertRFF(pos, _start.it, _end.it); | | return insertRFF(pos, _start.it, _end.it); | |
| } | | } | |
| | | | |
| skipping to change at line 824 | | skipping to change at line 926 | |
| return insertFRR(pos, _start.it, _end.it); | | return insertFRR(pos, _start.it, _end.it); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| inline JSONNode::json_iterator JSONNode::insert(json_iterator pos, cons
t json_iterator & _start, const json_iterator & _end) json_nothrow { | | inline JSONNode::json_iterator JSONNode::insert(json_iterator pos, cons
t json_iterator & _start, const json_iterator & _end) json_nothrow { | |
| return insertFFF(pos, json_iterator_ptr(_start), json_iterator_pt
r(_end)); | | return insertFFF(pos, json_iterator_ptr(_start), json_iterator_pt
r(_end)); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_WRITE_PRIORITY | | #ifdef JSON_WRITE_PRIORITY | |
|
| inline json_string JSONNode::write(void) json_nothrow { | | inline json_string JSONNode::write(size_t approxsize) const json_nothro | |
| JSON_CHECK_INTERNAL(); | | w { | |
| JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSO | | JSON_CHECK_INTERNAL(); | |
| N_TEXT("Writing a non-writable node"), return EMPTY_JSON_STRING;); | | JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JS | |
| return internal -> Write(0xFFFFFFFF, true); | | ON_TEXT("Writing a non-writable node"), return json_global(EMPTY_JSON_STRIN | |
| | | G);); | |
| | | json_string result; | |
| | | result.reserve(approxsize); | |
| | | internal -> Write(0xFFFFFFFF, true, result); | |
| | | return result; | |
| } | | } | |
| | | | |
|
| inline json_string JSONNode::write_formatted(void) json_nothrow { | | inline json_string JSONNode::write_formatted(size_t approxsize) const j | |
| JSON_CHECK_INTERNAL(); | | son_nothrow { | |
| JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSO | | JSON_CHECK_INTERNAL(); | |
| N_TEXT("Writing a non-writable node"), return EMPTY_JSON_STRING;); | | JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JS | |
| return internal -> Write(0, true); | | ON_TEXT("Writing a non-writable node"), return json_global(EMPTY_JSON_STRIN | |
| | | G);); | |
| | | json_string result; | |
| | | result.reserve(approxsize); | |
| | | internal -> Write(0, true, result); | |
| | | return result; | |
| } | | } | |
| | | | |
| #endif | | #endif | |
| | | | |
| #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY) | | #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY) | |
| inline void JSONNode::preparse(void) json_nothrow { | | inline void JSONNode::preparse(void) json_nothrow { | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
| internal -> preparse(); | | internal -> preparse(); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| skipping to change at line 870 | | skipping to change at line 978 | |
| JSON_CHECK_INTERNAL(); | | JSON_CHECK_INTERNAL(); | |
| JSONNode dumpage(JSON_NODE); | | JSONNode dumpage(JSON_NODE); | |
| dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("this"), (lo
ng)this))); | | dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("this"), (lo
ng)this))); | |
| dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("bytes used"
), sizeof(JSONNode)))); | | dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("bytes used"
), sizeof(JSONNode)))); | |
| dumpage.push_back(JSON_NEW(internal -> Dump(totalmemory)))
; | | dumpage.push_back(JSON_NEW(internal -> Dump(totalmemory)))
; | |
| return dumpage; | | return dumpage; | |
| } | | } | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
|
| inline void JSONNode::deleteJSONNode(JSONNode * ptr) json_nothrow { | | | |
| #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 != 0){ | | | |
| JSONNode * temp = _newJSONNode(orig); | | | |
| temp -> set_mutex(parentMutex); | | | |
| return temp; | | | |
| } | | | |
| #endif | | | |
| return _newJSONNode(orig); | | | |
| } | | | |
| | | | |
| inline JSONNode * JSONNode::newJSONNode(internalJSONNode * internal_t) { | | | |
| #ifdef JSON_MEMORY_CALLBACKS | | | |
| return new(json_malloc<JSONNode>(1)) JSONNode(internal_t); | | | |
| #else | | | |
| return new JSONNode(internal_t); | | | |
| #endif | | | |
| } | | | |
| | | | |
| inline JSONNode * JSONNode::newJSONNode_Shallow(const JSONNode & orig) { | | | |
| #ifdef JSON_MEMORY_CALLBACKS | | | |
| return new(json_malloc<JSONNode>(1)) JSONNode(true, const_cast<JS | | | |
| ONNode &>(orig)); | | | |
| #else | | | |
| return new JSONNode(true, const_cast<JSONNode &>(orig)); | | | |
| #endif | | | |
| } | | | |
| | | | |
| #ifdef JSON_LESS_MEMORY | | #ifdef JSON_LESS_MEMORY | |
| #ifdef __GNUC__ | | #ifdef __GNUC__ | |
| #pragma pack(pop) | | #pragma pack(pop) | |
| #elif _MSC_VER | | #elif _MSC_VER | |
| #pragma pack(pop, JSONNode_pack) | | #pragma pack(pop, JSONNode_pack) | |
| #endif | | #endif | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
End of changes. 54 change blocks. |
| 199 lines changed or deleted | | 302 lines changed or added | |
|
| JSONOptions.h | | JSONOptions.h | |
| | | | |
| skipping to change at line 86 | | skipping to change at line 86 | |
| * JSON_REF_COUNT causes libjson to reference count JSONNodes, which makes
copying | | * JSON_REF_COUNT causes libjson to reference count JSONNodes, which makes
copying | |
| * and passing them around much faster. It is recommended that this stay
on for | | * and passing them around much faster. It is recommended that this stay
on for | |
| * most uses | | * most uses | |
| */ | | */ | |
| #define JSON_REF_COUNT | | #define JSON_REF_COUNT | |
| | | | |
| /* | | /* | |
| * JSON_BINARY is used to support binary, which is base64 encoded and deco
ded by libjson, | | * JSON_BINARY is used to support binary, which is base64 encoded and deco
ded by libjson, | |
| * if this option is not turned on, no base64 support is included | | * if this option is not turned on, no base64 support is included | |
| */ | | */ | |
|
| //#define JSON_BINARY | | #define JSON_BINARY | |
| | | | |
| /* | | /* | |
| * JSON_EXPOSE_BASE64 is used to turn on the functionality of libjson's ba
se64 encoding | | * JSON_EXPOSE_BASE64 is used to turn on the functionality of libjson's ba
se64 encoding | |
| * and decoding. This may be useful if you want to obfuscate your json, o
r send binary data over | | * and decoding. This may be useful if you want to obfuscate your json, o
r send binary data over | |
| * a network | | * a network | |
| */ | | */ | |
|
| //#define JSON_EXPOSE_BASE64 | | #define JSON_EXPOSE_BASE64 | |
| | | | |
| /* | | /* | |
| * JSON_ITERATORS turns on all of libjson's iterating functionality. This
would usually | | * JSON_ITERATORS turns on all of libjson's iterating functionality. This
would usually | |
| * only be turned off while compiling for use with C | | * only be turned off while compiling for use with C | |
| */ | | */ | |
|
| //#define JSON_ITERATORS | | #define JSON_ITERATORS | |
| | | | |
| /* | | /* | |
| * JSON_STREAM turns on libjson's streaming functionality. This allows yo
u to give parts of | | * JSON_STREAM turns on libjson's streaming functionality. This allows yo
u to give parts of | |
| * your json into a stream, which will automatically hit a callback when f
ull nodes are | | * your json into a stream, which will automatically hit a callback when f
ull nodes are | |
| * completed | | * completed | |
| */ | | */ | |
|
| //#define JSON_STREAM | | #define JSON_STREAM | |
| | | | |
| /* | | /* | |
| * JSON_MEMORY_CALLBACKS exposes functions to register callbacks for alloc
ating, resizing, | | * JSON_MEMORY_CALLBACKS exposes functions to register callbacks for alloc
ating, resizing, | |
|
| * and freeing memory. Because libjson is designed for costomizability, i
t is feasible | | * and freeing memory. Because libjson is designed for customizability, i
t is feasible | |
| * that some users would like to further add speed by having the library u
tilize a memory | | * that some users would like to further add speed by having the library u
tilize a memory | |
| * pool. With this option turned on, the default behavior is still done i
nternally unless | | * pool. With this option turned on, the default behavior is still done i
nternally unless | |
|
| * a callback is registered. So you can have this option on and mot use i
t. | | * a callback is registered. So you can have this option on and not use i
t. | |
| */ | | */ | |
| //#define JSON_MEMORY_CALLBACKS | | //#define JSON_MEMORY_CALLBACKS | |
| | | | |
| /* | | /* | |
| * JSON_MEMORY_MANAGE is used to create functionality to automatically tra
ck and clean | | * JSON_MEMORY_MANAGE is used to create functionality to automatically tra
ck and clean | |
| * up memory that has been allocated by the user. This includes strings,
binary data, and | | * up memory that has been allocated by the user. This includes strings,
binary data, and | |
| * nodes. It also exposes bulk delete functions. | | * nodes. It also exposes bulk delete functions. | |
| */ | | */ | |
| //#define JSON_MEMORY_MANAGE | | //#define JSON_MEMORY_MANAGE | |
| | | | |
| /* | | /* | |
|
| | | * JSON_MEMORY_POOL Turns on libjson's iteraction with mempool++. It i | |
| | | s more efficient that simply | |
| | | * connecting mempool++ to the callbacks because it integrates things i | |
| | | nternally and uses a number | |
| | | * of memory pools. This value tells libjson how large of a memory poo | |
| | | l to start out with. 500KB | |
| | | * should suffice for most cases. libjson will distribute that within | |
| | | the pool for the best | |
| | | * performance depending on other settings. | |
| | | */ | |
| | | //#define JSON_MEMORY_POOL 524288 | |
| | | | |
| | | /* | |
| * JSON_MUTEX_CALLBACKS exposes functions to register callbacks to lock an
d unlock | | * JSON_MUTEX_CALLBACKS exposes functions to register callbacks to lock an
d unlock | |
| * mutexs and functions to lock and unlock JSONNodes and all of it's child
ren. This | | * mutexs and functions to lock and unlock JSONNodes and all of it's child
ren. This | |
| * does not prevent other threads from accessing the node, but will preven
t them from | | * does not prevent other threads from accessing the node, but will preven
t them from | |
| * locking it. It is much easier for the end programmer to allow libjson t
o manage | | * locking it. It is much easier for the end programmer to allow libjson t
o manage | |
| * your mutexs because of reference counting and manipulating trees, libjs
on automatically | | * your mutexs because of reference counting and manipulating trees, libjs
on automatically | |
| * tracks mutex controls for you, so you only ever lock what you need to | | * tracks mutex controls for you, so you only ever lock what you need to | |
| */ | | */ | |
| //#define JSON_MUTEX_CALLBACKS | | //#define JSON_MUTEX_CALLBACKS | |
| | | | |
| /* | | /* | |
| | | | |
| skipping to change at line 190 | | skipping to change at line 199 | |
| * JSON_ESCAPE_WRITES tells the libjson engine to escape special character
s when it writes | | * JSON_ESCAPE_WRITES tells the libjson engine to escape special character
s when it writes | |
| * out. If this option is turned off, the json it outputs may not adhere
to JSON standards | | * out. If this option is turned off, the json it outputs may not adhere
to JSON standards | |
| */ | | */ | |
| #define JSON_ESCAPE_WRITES | | #define JSON_ESCAPE_WRITES | |
| | | | |
| /* | | /* | |
| * JSON_COMMENTS tells libjson to store and write comments. libjson alway
s supports | | * JSON_COMMENTS tells libjson to store and write comments. libjson alway
s supports | |
| * parsing json that has comments in it as it simply ignores them, but wit
h this option | | * parsing json that has comments in it as it simply ignores them, but wit
h this option | |
| * it keeps the comments and allows you to insert further comments | | * it keeps the comments and allows you to insert further comments | |
| */ | | */ | |
|
| //#define JSON_COMMENTS | | #define JSON_COMMENTS | |
| | | | |
| /* | | /* | |
| * JSON_WRITE_BASH_COMMENTS will cause libjson to write all comments in ba
sh (#) style | | * JSON_WRITE_BASH_COMMENTS will cause libjson to write all comments in ba
sh (#) style | |
| * if this option is not turned on, then it will use C-style comments. Ba
sh comments are | | * if this option is not turned on, then it will use C-style comments. Ba
sh comments are | |
| * all single line | | * all single line | |
| */ | | */ | |
| //#define JSON_WRITE_BASH_COMMENTS | | //#define JSON_WRITE_BASH_COMMENTS | |
| | | | |
| /* | | /* | |
| * JSON_WRITE_SINGLE_LINE_COMMENTS will cause libjson to write all comment
s in using // | | * JSON_WRITE_SINGLE_LINE_COMMENTS will cause libjson to write all comment
s in using // | |
| * notation, or (#) if that option is on. Some parsers do not support mul
tiline C comments | | * notation, or (#) if that option is on. Some parsers do not support mul
tiline C comments | |
| * although, this option is not needed for bash comments, as they are all
single line anyway | | * although, this option is not needed for bash comments, as they are all
single line anyway | |
| */ | | */ | |
| //#define JSON_WRITE_SINGLE_LINE_COMMENTS | | //#define JSON_WRITE_SINGLE_LINE_COMMENTS | |
| | | | |
| /* | | /* | |
|
| * JSON_VALIDATE turns on validation features of libjson. This option req | | * JSON_ARRAY_SIZE_ON_ON_LINE allows you to put small arrays of primitives | |
| uires JSON_SAFE | | all on one line | |
| | | * in a write_formatted. This is common for tuples, like coordinates. If | |
| | | must be defined | |
| | | * as an integer | |
| */ | | */ | |
|
| //#define JSON_VALIDATE | | //#define JSON_ARRAY_SIZE_ON_ONE_LINE 2 | |
| | | | |
| | | /* | |
| | | * JSON_VALIDATE turns on validation features of libjson. | |
| | | */ | |
| | | #define JSON_VALIDATE | |
| | | | |
| /* | | /* | |
| * JSON_CASE_INSENSITIVE_FUNCTIONS turns on funtions for finding child nod
es in a case- | | * JSON_CASE_INSENSITIVE_FUNCTIONS turns on funtions for finding child nod
es in a case- | |
| * insenititve way | | * insenititve way | |
| */ | | */ | |
|
| //#define JSON_CASE_INSENSITIVE_FUNCTIONS | | #define JSON_CASE_INSENSITIVE_FUNCTIONS | |
| | | | |
| /* | | /* | |
| * JSON_INDEX_TYPE allows you th change the size type for the children fun
ctions. If this | | * JSON_INDEX_TYPE allows you th change the size type for the children fun
ctions. If this | |
| * option is not used then unsigned int is used. This option is useful fo
r cutting down | | * option is not used then unsigned int is used. This option is useful fo
r cutting down | |
| * on memory, or using huge numbers of child nodes (over 4 billion) | | * on memory, or using huge numbers of child nodes (over 4 billion) | |
| */ | | */ | |
| //#define JSON_INDEX_TYPE unsigned int | | //#define JSON_INDEX_TYPE unsigned int | |
| | | | |
| /* | | /* | |
| * JSON_BOOL_TYPE lets you change the bool type for the C interface. Beca
use before C99 there | | * JSON_BOOL_TYPE lets you change the bool type for the C interface. Beca
use before C99 there | |
| * was no bool, and even then it's just a typedef, you may want to use som
ething else. If this | | * was no bool, and even then it's just a typedef, you may want to use som
ething else. If this | |
| * is not defined, it will revert to int | | * is not defined, it will revert to int | |
| */ | | */ | |
| //#define JSON_BOOL_TYPE char | | //#define JSON_BOOL_TYPE char | |
| | | | |
| /* | | /* | |
|
| | | * JSON_INT_TYPE lets you change the int type for as_int. If you ommit th | |
| | | is option, the default | |
| | | * long will be used | |
| | | */ | |
| | | //#define JSON_INT_TYPE long | |
| | | | |
| | | /* | |
| * JSON_STRING_HEADER allows you to change the type of string that libjson
uses both for the | | * JSON_STRING_HEADER allows you to change the type of string that libjson
uses both for the | |
| * interface and internally. It must implement most of the STL string int
erface, but not all | | * interface and internally. It must implement most of the STL string int
erface, but not all | |
| * of it. Things like wxString or QString should wourk without much troub
le | | * of it. Things like wxString or QString should wourk without much troub
le | |
| */ | | */ | |
| //#define JSON_STRING_HEADER "../TestSuite/StringTest.h" | | //#define JSON_STRING_HEADER "../TestSuite/StringTest.h" | |
| | | | |
| /* | | /* | |
| * JSON_UNIT_TEST is used to maintain and debug the libjson. It makes all
private | | * JSON_UNIT_TEST is used to maintain and debug the libjson. It makes all
private | |
| * members and functions public so that tests can do checks of the inner w
orkings | | * members and functions public so that tests can do checks of the inner w
orkings | |
| * of libjson. This should not be turned on by end users. | | * of libjson. This should not be turned on by end users. | |
| */ | | */ | |
| //#define JSON_UNIT_TEST | | //#define JSON_UNIT_TEST | |
| | | | |
| /* | | /* | |
|
| * JSON_NO_EXCEPTIONS turns off any exception trhowing by the library. It
may still use exceptions | | * JSON_NO_EXCEPTIONS turns off any exception throwing by the library. It
may still use exceptions | |
| * internally, but the interface will never throw anything. | | * internally, but the interface will never throw anything. | |
| */ | | */ | |
| //#define JSON_NO_EXCEPTIONS | | //#define JSON_NO_EXCEPTIONS | |
| | | | |
| /* | | /* | |
| * JSON_DEPRECATED_FUNCTIONS turns on functions that have been deprecated,
this is for backwards | | * JSON_DEPRECATED_FUNCTIONS turns on functions that have been deprecated,
this is for backwards | |
| * compatibility between major releases. It is highly recommended that yo
u move your functions | | * compatibility between major releases. It is highly recommended that yo
u move your functions | |
| * over to the new equivalents | | * over to the new equivalents | |
| */ | | */ | |
| #define JSON_DEPRECATED_FUNCTIONS | | #define JSON_DEPRECATED_FUNCTIONS | |
| | | | |
|
| | | /* | |
| | | * JSON_CASTABLE allows you to call as_bool on a number and have it do the | |
| | | 0 or not 0 check, | |
| | | * it also allows you to ask for a string from a number, or boolean, and h | |
| | | ave it return the right thing. | |
| | | * Without this option, those types of requests are undefined. It also ex | |
| | | poses the as_array, as_node, and cast | |
| | | * functions | |
| | | */ | |
| | | #define JSON_CASTABLE | |
| | | | |
| | | /* | |
| | | * JSON_SECURITY_MAX_NEST_LEVEL is a security measure added to make preven | |
| | | t against DoS attacks | |
| | | * This only affects validation, as if you are worried about security atta | |
| | | cks, then you are | |
| | | * most certainly validating json before sending it to be parsed. This op | |
| | | tion allows you to limitl how many | |
| | | * levels deep a JSON Node can go. 128 is a good depth to start with | |
| | | */ | |
| | | #define JSON_SECURITY_MAX_NEST_LEVEL 128 | |
| | | | |
| | | /* | |
| | | * JSON_SECURITY_MAX_STRING_LENGTH is another security measure, preventing | |
| | | DoS attacks with very long | |
| | | * strings of JSON. 32MB is the default value for this, this allows large | |
| | | images to be embedded | |
| | | */ | |
| | | #define JSON_SECURITY_MAX_STRING_LENGTH 33554432 | |
| | | | |
| | | /* | |
| | | * JSON_SECURITY_MAX_STREAM_OBJECTS is a security measure for streams. | |
| | | It prevents DoS attacks with | |
| | | * large number of objects hitting the stream all at once. 128 is a lo | |
| | | t of objects, but not out of | |
| | | * the question for high speed systems. | |
| | | */ | |
| | | #define JSON_SECURITY_MAX_STREAM_OBJECTS 128 | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 14 change blocks. |
| 12 lines changed or deleted | | 79 lines changed or added | |
|
| NumberToString.h | | NumberToString.h | |
| #ifndef NUMBERTOSTRING_H | | #ifndef NUMBERTOSTRING_H | |
| #define NUMBERTOSTRING_H | | #define NUMBERTOSTRING_H | |
| | | | |
|
| | | #include <limits> | |
| #include "JSONDebug.h" | | #include "JSONDebug.h" | |
| #ifdef JSON_LESS_MEMORY | | #ifdef JSON_LESS_MEMORY | |
| #include "JSONMemory.h" | | #include "JSONMemory.h" | |
| #endif | | #endif | |
|
| | | #include "JSONSharedString.h" | |
| #include <cstdio> | | #include <cstdio> | |
| #ifdef JSON_STRICT | | #ifdef JSON_STRICT | |
| #include <cmath> | | #include <cmath> | |
| #endif | | #endif | |
| template <unsigned int GETLENSIZE> | | template <unsigned int GETLENSIZE> | |
| struct getLenSize{ | | struct getLenSize{ | |
| char tmp[GETLENSIZE == 16]; // compile time assertion | | char tmp[GETLENSIZE == 16]; // compile time assertion | |
| enum {GETLEN = 41}; | | enum {GETLEN = 41}; | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 61 | | skipping to change at line 63 | |
| #ifdef JSON_LESS_MEMORY | | #ifdef JSON_LESS_MEMORY | |
| json_auto<json_char> s(getLenSize<sizeof(T)>::GETLEN); | | json_auto<json_char> s(getLenSize<sizeof(T)>::GETLEN); | |
| #else | | #else | |
| json_char num_str_result[getLenSize<sizeof(T)>::GETLEN]; | | json_char num_str_result[getLenSize<sizeof(T)>::GETLEN]; | |
| #endif | | #endif | |
| num_str_result[getLenSize<sizeof(T)>::GETLEN - 1] = JSON_TEXT('\0
'); //null terminator | | num_str_result[getLenSize<sizeof(T)>::GETLEN - 1] = JSON_TEXT('\0
'); //null terminator | |
| json_char * runner = &num_str_result[getLenSize<sizeof(T)>::GETLE
N - 2]; | | json_char * runner = &num_str_result[getLenSize<sizeof(T)>::GETLE
N - 2]; | |
| bool negative; | | bool negative; | |
| | | | |
| START_MEM_SCOPE | | START_MEM_SCOPE | |
|
| long value = (long)val; | | long value = (long)val; | |
| //first thing, check if it's negative, if so, make it posi | | //first thing, check if it's negative, if so, make it positive | |
| tive | | if (value < 0){ | |
| if (value < 0){ | | //HitScopeCoverage(_itoa_coverage); | |
| value = -value; | | value = -value; | |
| negative = true; | | negative = true; | |
| } else { | | } else { | |
| negative = false; | | //HitScopeCoverage(_itoa_coverage); | |
| } | | negative = false; | |
| | | } | |
| | | | |
|
| //create the string | | //create the string | |
| do { | | do { | |
| *runner-- = (json_char)(value % 10) + JSON_TEXT('0' | | //HitScopeCoverage(_itoa_coverage); | |
| ); | | *runner-- = (json_char)(value % 10) + JSON_TEXT('0'); | |
| } while(value /= 10); | | } while(value /= 10); | |
| END_MEM_SCOPE | | END_MEM_SCOPE | |
| | | | |
| //if it's negative, add the negation | | //if it's negative, add the negation | |
| if (negative){ | | if (negative){ | |
|
| | | //HitScopeCoverage(_itoa_coverage); | |
| *runner = JSON_TEXT('-'); | | *runner = JSON_TEXT('-'); | |
| return json_string(runner); | | return json_string(runner); | |
|
| | | } else { | |
| | | //HitScopeCoverage(_itoa_coverage); | |
| } | | } | |
|
| | | //HitScopeCoverage(_itoa_coverage); | |
| return json_string(runner + 1); | | return json_string(runner + 1); | |
| } | | } | |
| | | | |
| #ifndef JSON_LIBRARY | | #ifndef JSON_LIBRARY | |
| template<typename T> | | template<typename T> | |
| static json_string _uitoa(T val) json_nothrow { | | static json_string _uitoa(T val) json_nothrow { | |
| #ifdef JSON_LESS_MEMORY | | #ifdef JSON_LESS_MEMORY | |
| json_auto<json_char> s(getLenSize<sizeof(T)>::GETLE
N); | | json_auto<json_char> s(getLenSize<sizeof(T)>::GETLE
N); | |
| #else | | #else | |
| json_char num_str_result[getLenSize<sizeof(T)>::GET
LEN]; | | json_char num_str_result[getLenSize<sizeof(T)>::GET
LEN]; | |
| | | | |
| skipping to change at line 107 | | skipping to change at line 116 | |
| unsigned long value = (unsigned long)val; | | unsigned long value = (unsigned long)val; | |
| do { | | do { | |
| *runner-- = (json_char)(value % 10) + JSON_T
EXT('0'); | | *runner-- = (json_char)(value % 10) + JSON_T
EXT('0'); | |
| } while(value /= 10); | | } while(value /= 10); | |
| END_MEM_SCOPE | | END_MEM_SCOPE | |
| | | | |
| return json_string(runner + 1); | | return json_string(runner + 1); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
|
| | | #ifdef JSON_ISO_STRICT | |
| | | #define EXTRA_LONG | |
| | | #define FLOAT_STRING "%f" | |
| | | #define LFLOAT_STRING L"%f" | |
| | | #else | |
| | | #define EXTRA_LONG long | |
| | | #define FLOAT_STRING "%Lf" | |
| | | #define LFLOAT_STRING L"%Lf" | |
| | | #endif | |
| | | | |
| static json_string _ftoa(json_number value) json_nothrow { | | static json_string _ftoa(json_number value) json_nothrow { | |
| #ifndef JSON_LIBRARY | | #ifndef JSON_LIBRARY | |
|
| if (json_unlikely(value > 0.0 && _floatsAreEqual(value, (j | | //ScopeCoverage(_ftoa_coverage, 6); | |
| son_number)((unsigned long)value)))){ | | if (json_unlikely(value >= 0.0 && _floatsAreEqual(value, ( | |
| return _uitoa<unsigned long>((unsigned long)value); | | json_number)((unsigned EXTRA_LONG long)value)))){ | |
| | | //HitScopeCoverage(_ftoa_coverage); | |
| | | return _uitoa<unsigned EXTRA_LONG long>((unsigned E | |
| | | XTRA_LONG long)value); | |
| } else | | } else | |
|
| | | #else | |
| | | //ScopeCoverage(_ftoa_coverage, 5); | |
| #endif | | #endif | |
|
| if (json_unlikely(_floatsAreEqual(value, (json_number)((long)valu | | if (json_unlikely(_floatsAreEqual(value, (json_number)((lo | |
| e)))){ | | ng EXTRA_LONG)value)))){ | |
| return _itoa<long>((long)value); | | //HitScopeCoverage(_ftoa_coverage); | |
| } | | return _itoa<long EXTRA_LONG>((long EXTRA_LONG)valu | |
| | | e); | |
| | | } | |
| | | | |
| #ifdef JSON_LESS_MEMORY | | #ifdef JSON_LESS_MEMORY | |
| json_auto<json_char> s(64); | | json_auto<json_char> s(64); | |
| #else | | #else | |
| json_char num_str_result[64]; | | json_char num_str_result[64]; | |
| #endif | | #endif | |
| #ifdef JSON_UNICODE | | #ifdef JSON_UNICODE | |
|
| swprintf(num_str_result, 63, L"%f", value); | | std::swprintf(num_str_result, 63, LFLOAT_STRING, (EXTRA_LO
NG double)value); | |
| #else | | #else | |
| //Thanks to Salvor Hardin for this Visual C++ fix | | //Thanks to Salvor Hardin for this Visual C++ fix | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
|
| _snprintf_s(num_str_result, 63, 63, "%f", value); /
/yes, 63 appears twice using _snprintf_s() | | _snprintf_s(num_str_result, 63, 63, FLOAT_STRING, (
EXTRA_LONG double)value); //yes, 63 appears twice using _snprintf_s() | |
| #else | | #else | |
|
| snprintf(num_str_result, 63, "%f", value); | | std::snprintf(num_str_result, 63, FLOAT_STRING, (EX
TRA_LONG double)value); | |
| #endif | | #endif | |
| #endif | | #endif | |
| //strip the trailing zeros | | //strip the trailing zeros | |
| for(json_char * pos = &num_str_result[0]; *pos; ++pos){ | | for(json_char * pos = &num_str_result[0]; *pos; ++pos){ | |
|
| | | //HitScopeCoverage(_ftoa_coverage); | |
| if (json_unlikely(*pos == '.')){ //only care about after
the decimal | | if (json_unlikely(*pos == '.')){ //only care about after
the decimal | |
|
| | | //HitScopeCoverage(_ftoa_coverage); | |
| for(json_char * runner = pos + 1; *runner; ++runner
){ | | for(json_char * runner = pos + 1; *runner; ++runner
){ | |
|
| if (json_likely(*runner != JSON_TEXT('0'))) | | //HitScopeCoverage(_ftoa_coverage); | |
| pos = runner + 1; //have to go to the end 1.0001 | | if (json_likely(*runner != JSON_TEXT('0'))) | |
| | | { | |
| | | //HitScopeCoverage(_ftoa_coverage); | |
| | | pos = runner + 1; //have to go to | |
| | | the end 1.0001 | |
| | | } | |
| } | | } | |
| *pos = JSON_TEXT('\0'); | | *pos = JSON_TEXT('\0'); | |
| break; | | break; | |
| } | | } | |
| } | | } | |
| return json_string(num_str_result); | | return json_string(num_str_result); | |
| } | | } | |
| | | | |
| #if defined(JSON_SAFE) || defined(JSON_DEBUG) | | #if defined(JSON_SAFE) || defined(JSON_DEBUG) | |
| static bool isNumeric(const json_string & str) json_nothrow { | | static bool isNumeric(const json_string & str) json_nothrow { | |
| const json_char * p = str.c_str(); | | const json_char * p = str.c_str(); | |
| bool decimal = false; | | bool decimal = false; | |
| bool scientific = false; | | bool scientific = false; | |
| | | | |
|
| | | #ifdef JSON_STRICT | |
| | | bool leadingzero = false; | |
| | | #endif | |
| | | | |
| //first letter is weird | | //first letter is weird | |
| switch(*p){ | | switch(*p){ | |
|
| case '\0': | | case JSON_TEXT('\0'): | |
| | | HitScopeCoverage(isNumeric, emptystring); | |
| return false; | | return false; | |
|
| #ifndef JSON_STRICT | | #ifndef JSON_STRICT | |
| case '.': | | case JSON_TEXT('.'): | |
| decimal = true; | | HitScopeCoverage(isNumeric, leadingperiod); | |
| break; | | decimal = true; | |
| case '+': | | | |
| #endif | | | |
| case '-': | | | |
| case '1': | | | |
| case '2': | | | |
| case '3': | | | |
| case '4': | | | |
| case '5': | | | |
| case '6': | | | |
| case '7': | | | |
| case '8': | | | |
| case '9': | | | |
| break; | | break; | |
|
| case '0': | | case JSON_TEXT('+'): | |
| | | #endif | |
| | | case JSON_TEXT('-'): | |
| | | switch (*(p + 1)){ | |
| | | case JSON_TEXT('.'): | |
| | | case JSON_TEXT('e'): | |
| | | case JSON_TEXT('E'): | |
| | | case JSON_TEXT('\0'): | |
| | | HitScopeCoverage(isNumeric | |
| | | , minus_dot_e_null); | |
| | | return false; | |
| | | case JSON_TEXT('0'): | |
| | | HitScopeCoverage(isNumeric | |
| | | , minus_zero); | |
| | | #ifdef JSON_STRICT | |
| | | switch(*(p + 2)){ | |
| | | case JSON_TEXT('.' | |
| | | ): | |
| | | case JSON_TEXT('e' | |
| | | ): | |
| | | case JSON_TEXT('E' | |
| | | ): | |
| | | HitScopeCo | |
| | | verage(isNumeric, minus_zero_dot_e); | |
| | | leadingzer | |
| | | o = false; | |
| | | break; | |
| | | case JSON_TEXT('\0 | |
| | | '): | |
| | | HitScopeCo | |
| | | verage(isNumeric, minus_zero_null); | |
| | | return tru | |
| | | e; | |
| | | default: | |
| | | HitScopeCo | |
| | | verage(isNumeric, minus_zero_default); | |
| | | leadingzer | |
| | | o = true; | |
| | | break; | |
| | | } | |
| | | #endif | |
| | | ++p; | |
| | | break; | |
| | | default: | |
| | | HitScopeCoverage(isNumeric | |
| | | , minus_default); | |
| | | break; | |
| | | } | |
| | | break; | |
| | | case JSON_TEXT('1'): | |
| | | case JSON_TEXT('2'): | |
| | | case JSON_TEXT('3'): | |
| | | case JSON_TEXT('4'): | |
| | | case JSON_TEXT('5'): | |
| | | case JSON_TEXT('6'): | |
| | | case JSON_TEXT('7'): | |
| | | case JSON_TEXT('8'): | |
| | | case JSON_TEXT('9'): | |
| | | HitScopeCoverage(isNumeric, digit); | |
| | | break; | |
| | | case JSON_TEXT('0'): | |
| ++p; | | ++p; | |
|
| | | #ifdef JSON_STRICT | |
| | | leadingzero = true; | |
| | | #endif | |
| | | HitScopeCoverage(isNumeric, zero); | |
| switch(*p){ | | switch(*p){ | |
|
| case '.': | | case JSON_TEXT('.'): | |
| | | HitScopeCoverage(isNumeric, zero_ | |
| | | dot); | |
| decimal = true; | | decimal = true; | |
| break; | | break; | |
|
| case 'e': | | case JSON_TEXT('e'): | |
| case 'E': | | case JSON_TEXT('E'): | |
| | | #ifdef JSON_STRICT | |
| | | leadingzero = false; //not l | |
| | | eading, just a zero | |
| | | #endif | |
| | | HitScopeCoverage(isNumeric, | |
| | | zero_e); | |
| scientific = true; | | scientific = true; | |
| ++p; | | ++p; | |
| switch(*p){ | | switch(*p){ | |
|
| case '\0': | | case JSON_TEXT('\0'): | |
| | | HitScopeCoverage(is | |
| | | Numeric, zero_e_null); | |
| return false; | | return false; | |
|
| case '-': | | case JSON_TEXT('-'): | |
| case '+': | | case JSON_TEXT('+'): | |
| case '0': | | #ifndef JSON_STRICT | |
| case '1': | | case JSON_TEXT('0'): //ca | |
| case '2': | | nt have a leading zero in scrict | |
| case '3': | | HitScopeCoverage( | |
| case '4': | | isNumeric, zero_e_zero); | |
| case '5': | | #endif | |
| case '6': | | case JSON_TEXT('1'): | |
| case '7': | | case JSON_TEXT('2'): | |
| case '8': | | case JSON_TEXT('3'): | |
| case '9': | | case JSON_TEXT('4'): | |
| | | case JSON_TEXT('5'): | |
| | | case JSON_TEXT('6'): | |
| | | case JSON_TEXT('7'): | |
| | | case JSON_TEXT('8'): | |
| | | case JSON_TEXT('9'): | |
| | | HitScopeCoverage(is | |
| | | Numeric, zero_e_digit_sign); | |
| break; | | break; | |
| default: | | default: | |
|
| | | HitScopeCoverage(is
Numeric, zero_e_default); | |
| return false; | | return false; | |
| } | | } | |
| break; | | break; | |
| #ifndef JSON_STRICT | | #ifndef JSON_STRICT | |
|
| case 'x': | | case JSON_TEXT('x'): | |
| | | HitScopeCoverage(isNumeric | |
| | | , zero_x); | |
| return (str.find_first_not
_of(JSON_TEXT("0123456789ABCDEFabcdef"), 2) == json_string::npos); | | return (str.find_first_not
_of(JSON_TEXT("0123456789ABCDEFabcdef"), 2) == json_string::npos); | |
|
| case '1': | | case JSON_TEXT('1'): | |
| case '2': | | case JSON_TEXT('2'): | |
| case '3': | | case JSON_TEXT('3'): | |
| case '4': | | case JSON_TEXT('4'): | |
| case '5': | | case JSON_TEXT('5'): | |
| case '6': | | case JSON_TEXT('6'): | |
| case '7': | | case JSON_TEXT('7'): | |
| | | HitScopeCoverage(isNumeric | |
| | | , zero_octal); | |
| return (str.find_first_not
_of(JSON_TEXT("01234567"), 1) == json_string::npos); | | return (str.find_first_not
_of(JSON_TEXT("01234567"), 1) == json_string::npos); | |
| #endif | | #endif | |
|
| case '\0': //just 0 | | case JSON_TEXT('\0'): //just 0 | |
| | | HitScopeCoverage(isNumeric, zero_ | |
| | | null); | |
| return true; | | return true; | |
| default: | | default: | |
|
| | | HitScopeCoverage(isNumeric, zero_
default); | |
| return false; | | return false; | |
| } | | } | |
|
| | | HitScopeCoverage(isNumeric, zero_break); | |
| break; | | break; | |
| default: | | default: | |
|
| | | HitScopeCoverage(isNumeric, default_first); | |
| return false; | | return false; | |
| } | | } | |
| ++p; | | ++p; | |
| | | | |
| //next digits | | //next digits | |
| while (*p){ | | while (*p){ | |
| switch(*p){ | | switch(*p){ | |
|
| case '.': | | case JSON_TEXT('.'): | |
| if (json_unlikely(decimal)) return false | | if (json_unlikely(decimal)){ | |
| ; //multiple decimals | | HitScopeCoverage(isNumeric, | |
| if (json_unlikely(scientific)) return fa | | _dot_already); | |
| lse; | | return false; //multiple de | |
| | | cimals | |
| | | } | |
| | | HitScopeCoverage(isNumeric, _dot); | |
| | | | |
| | | if (json_unlikely(scientific)){ | |
| | | HitScopeCoverage(isNumeric, | |
| | | _dot_scientific); | |
| | | return false; | |
| | | } | |
| | | HitScopeCoverage(isNumeric, _dot_no | |
| | | tscientific); | |
| decimal = true; | | decimal = true; | |
| break; | | break; | |
|
| case 'e': | | case JSON_TEXT('e'): | |
| case 'E': | | case JSON_TEXT('E'): | |
| if (json_unlikely(scientific)) return fa | | if (json_unlikely(scientific)){ | |
| lse; | | | |
| | | //TODO Not hit in unit test | |
| | | s | |
| | | | |
| | | HitScopeCoverage(isNumeric, | |
| | | _e_scientific); | |
| | | return false; | |
| | | } | |
| | | HitScopeCoverage(isNumeric, _e_notsc | |
| | | ientific); | |
| scientific = true; | | scientific = true; | |
| ++p; | | ++p; | |
| switch(*p){ | | switch(*p){ | |
|
| case '\0': | | case JSON_TEXT('\0'): | |
| | | | |
| | | //TODO Not hit in un | |
| | | it tests | |
| | | | |
| | | HitScopeCoverage(isNumeric | |
| | | , _e_null); | |
| return false; | | return false; | |
|
| case '-': | | case JSON_TEXT('-'): | |
| case '+': | | case JSON_TEXT('+'): | |
| case '0': | | if (!isdigit(*(p + 1 | |
| case '1': | | ))){ | |
| case '2': | | | |
| case '3': | | //TODO Not h | |
| case '4': | | it in unit tests | |
| case '5': | | | |
| case '6': | | HitScopeCove | |
| case '7': | | rage(isNumeric, _e_sign_notdigit); | |
| case '8': | | return false | |
| case '9': | | ; | |
| | | } | |
| | | | |
| | | #ifdef JSON_STRICT | |
| | | if (*(p + 1) | |
| | | == JSON_TEXT('0')){ //no leading zeros on scientific notations | |
| | | HitS | |
| | | copeCoverage(isNumeric, _e_sign_zero); | |
| | | retu | |
| | | rn false; | |
| | | } | |
| | | #endif | |
| | | HitScopeCoverage(isN | |
| | | umeric, _e_sign); | |
| | | break; | |
| | | #ifndef JSON_STRICT | |
| | | case JSON_TEXT('0'): //cant have | |
| | | a leading zero in scrict | |
| | | #endif | |
| | | case JSON_TEXT('1'): | |
| | | case JSON_TEXT('2'): | |
| | | case JSON_TEXT('3'): | |
| | | case JSON_TEXT('4'): | |
| | | case JSON_TEXT('5'): | |
| | | case JSON_TEXT('6'): | |
| | | case JSON_TEXT('7'): | |
| | | case JSON_TEXT('8'): | |
| | | case JSON_TEXT('9'): | |
| | | HitScopeCoverage(isNumeric | |
| | | , _e_digit); | |
| break; | | break; | |
| default: | | default: | |
|
| | | | |
| | | //TODO Not hit in un | |
| | | it tests | |
| | | | |
| | | HitScopeCoverage(isNumeric | |
| | | , _e_default); | |
| return false; | | return false; | |
| } | | } | |
|
| | | HitScopeCoverage(isNumeric, _e_break
); | |
| break; | | break; | |
|
| case '0': | | case JSON_TEXT('0'): | |
| case '1': | | case JSON_TEXT('1'): | |
| case '2': | | case JSON_TEXT('2'): | |
| case '3': | | case JSON_TEXT('3'): | |
| case '4': | | case JSON_TEXT('4'): | |
| case '5': | | case JSON_TEXT('5'): | |
| case '6': | | case JSON_TEXT('6'): | |
| case '7': | | case JSON_TEXT('7'): | |
| case '8': | | case JSON_TEXT('8'): | |
| case '9': | | case JSON_TEXT('9'): | |
| | | HitScopeCoverage(isNumeric, _digit); | |
| break; | | break; | |
| default: | | default: | |
|
| | | HitScopeCoverage(isNumeric, _default
); | |
| return false; | | return false; | |
| } | | } | |
| ++p; | | ++p; | |
| } | | } | |
|
| | | #ifdef JSON_STRICT | |
| | | if (leadingzero && !decimal){ | |
| | | HitScopeCoverage(isNumeric, leadingzero_and_nodec | |
| | | imal); | |
| | | return false; | |
| | | } | |
| | | #endif | |
| | | HitScopeCoverage(isNumeric, returntrue); | |
| return true; | | return true; | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_STRICT | | #ifdef JSON_STRICT | |
| //much faster because no octal or hex support | | //much faster because no octal or hex support | |
|
| json_number _atof (json_char * num){ | | static json_number _atof (const json_char * num){ | |
| json_number sign = 1.0; | | json_number sign = (json_number)1.0; | |
| | | | |
| //sign | | //sign | |
|
| if (*num=='-'){ | | if (*num==JSON_TEXT('-')){ | |
| | | HitScopeCoverage(_atof, negative); | |
| sign = -1.0; | | sign = -1.0; | |
| ++num; | | ++num; | |
|
| | | } else { | |
| | | HitScopeCoverage(_atof, otnegative); | |
| } | | } | |
| | | | |
|
| //skip leading zeros | | //skip leading zero if one | |
| while (*num == '0'){ | | #if defined(JSON_SAFE) || defined(JSON_DEBUG) | |
| | | bool _leadingzeros = *num == JSON_TEXT('0'); | |
| | | bool _leadingdigits = false; | |
| | | #endif | |
| | | if (*num == JSON_TEXT('0')){ | |
| | | HitScopeCoverage(_atof, leadingzero); | |
| ++num; | | ++num; | |
| } | | } | |
|
| | | #ifdef JSON_STRICT | |
| | | else if (json_likely(*num < JSON_TEXT('1') || *num > | |
| | | JSON_TEXT('9'))){ | |
| | | return std::numeric_limits<json_number>::sig | |
| | | naling_NaN(); | |
| | | } | |
| | | #endif | |
| | | | |
| | | JSON_ASSERT_SAFE(*num != JSON_TEXT('0'), JSON_TEXT("multi | |
| | | ple leading zeros"), return std::numeric_limits<json_number>::signaling_NaN | |
| | | (); ); | |
| | | | |
| // Number | | // Number | |
|
| json_number n = 0.0 | | json_number n = (json_number)0.0; | |
| if (json_likely(*num >= '1' && *num <= '9')){ | | if (json_likely(*num >= JSON_TEXT('1') && *num <= JSON_TEX | |
| | | T('9'))){ | |
| | | #if defined(JSON_SAFE) || defined(JSON_DEBUG) | |
| | | _leadingdigits = true; | |
| | | #endif | |
| | | HitScopeCoverage(_atof, digits); | |
| do { | | do { | |
|
| n = (n * 10.0) + (*num++ - '0'); | | n = (n * 10.0) + (*num++ - JSON_TEXT('0')); | |
| } while (*num >= '0' && *num <= '9'); | | } while (*num >= JSON_TEXT('0') && *num <= JSON_TEX | |
| | | T('9')); | |
| | | } else { | |
| | | JSON_ASSERT_SAFE( | |
| | | (*num) == JSON_TE | |
| | | XT('.') || //.xxx | |
| | | (*num) == JSON_TE | |
| | | XT('e') || //0Exxx | |
| | | (*num) == JSON_TE | |
| | | XT('E') || //0exxx | |
| | | (*num) == JSON_TE | |
| | | XT('\0') //end of the number, just zero | |
| | | , JSON_TEXT("firs | |
| | | t digit not a number, e, period, or terminator"), return std::numeric_limit | |
| | | s<json_number>::signaling_NaN(); ); | |
| | | HitScopeCoverage(_atof, notdigits); | |
| } | | } | |
| | | | |
| // Fractional part | | // Fractional part | |
|
| json_number scale = 0.0; | | json_number scale = (json_number)0.0; | |
| if (*num=='.') { | | if (*num == JSON_TEXT('.')) { | |
| | | JSON_ASSERT_SAFE(_leadingzeros || _leadingdigits, | |
| | | JSON_TEXT("period without leading anything"), return std::numeric_limits<js | |
| | | on_number>::signaling_NaN(); ); | |
| | | HitScopeCoverage(_atof, decimal); | |
| ++num; | | ++num; | |
|
| do { | | for(; *num >= JSON_TEXT('0') && *num <= JSON_TEXT( | |
| n = (n * 10.0) + (*num++ - '0'); | | '9');){ | |
| | | HitScopeCoverage(_atof, decimalloop); | |
| | | n = (n * 10.0) + (*num++ - JSON_TEXT('0')); | |
| --scale; | | --scale; | |
|
| } while (*num>='0' && *num<='9'); | | }; | |
| | | } else { | |
| | | JSON_ASSERT_SAFE(!_leadingzeros || n == 0, JSON_TE | |
| | | XT("leading zero on an int"), return std::numeric_limits<json_number>::sign | |
| | | aling_NaN(); ); | |
| | | JSON_ASSERT_SAFE( | |
| | | (*num) == JSON_TE | |
| | | XT('e') || //0Exxx | |
| | | (*num) == JSON_TE | |
| | | XT('E') || //0exxx | |
| | | (*num) == JSON_TE | |
| | | XT('\0') //end of the number, just zero | |
| | | , JSON_TEXT("next | |
| | | char not an e or terminator"), return std::numeric_limits<json_number>::si | |
| | | gnaling_NaN(); ); | |
| | | HitScopeCoverage(_atof, nodecimal); | |
| } | | } | |
| | | | |
| // Exponent | | // Exponent | |
| int subscale = 0, signsubscale = 1; | | int subscale = 0, signsubscale = 1; | |
|
| if (json_unlikely(*num == 'e' || *num == 'E')){ | | if (json_unlikely(*num == JSON_TEXT('e') || *num == JSON_T | |
| | | EXT('E'))){ | |
| | | HitScopeCoverage(_atof, exponent); | |
| ++num; | | ++num; | |
| switch(*num){ | | switch(*num){ | |
|
| case '+': | | case JSON_TEXT('+'): | |
| | | HitScopeCoverage(_atof, positiveexp | |
| | | onent); | |
| ++num; | | ++num; | |
| break; | | break; | |
|
| case '-': | | case JSON_TEXT('-'): | |
| | | HitScopeCoverage(_atof, negativeexp | |
| | | onent); | |
| signsubscale = -1; | | signsubscale = -1; | |
| ++num; | | ++num; | |
|
| | | JSON_ASSERT_SAFE(*num != JSON_TEXT(
'0'), JSON_TEXT("negative cant be followed by leading zero even after E"),
return std::numeric_limits<json_number>::signaling_NaN(); ); | |
| break; | | break; | |
|
| | | default: | |
| | | HitScopeCoverage(_atof, nosignexpon | |
| | | ent); | |
| | | break; | |
| } | | } | |
|
| while (*num >= '0' && *num <= '9'){ | | JSON_ASSERT_SAFE(*num != JSON_TEXT('\0'), JSON_TEXT | |
| subscale=(subscale * 10) + (*num++ - '0'); | | ("no exponent for scientific notation"), return std::numeric_limits<json_nu | |
| | | mber>::signaling_NaN(); ); | |
| | | while (*num >= JSON_TEXT('0') && *num <= JSON_TEXT( | |
| | | '9')){ | |
| | | HitScopeCoverage(_atof, afterexponent); | |
| | | subscale=(subscale * 10) + (*num++ - JSON_TE | |
| | | XT('0')); | |
| } | | } | |
|
| | | } else { | |
| | | HitScopeCoverage(_atof, noexponent); | |
| } | | } | |
| | | | |
|
| return sign * n * pow(10.0, scale + subscale * signsubscal | | JSON_ASSERT_SAFE(*num == JSON_TEXT('\0'), JSON_TEXT("done | |
| e); // number = +/- number.fraction * 10^+/- exponent | | with number, not at terminator"), return std::numeric_limits<json_number>:: | |
| | | signaling_NaN(); ); | |
| | | return sign * n * pow((json_number)10.0, scale + subscale | |
| | | * signsubscale); // number = +/- number.fraction * 10^+/- exponent | |
| } | | } | |
| #endif | | #endif | |
| }; | | }; | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 60 change blocks. |
| 122 lines changed or deleted | | 391 lines changed or added | |
|
| internalJSONNode.h | | internalJSONNode.h | |
| #ifndef INTERNAL_JSONNODE_H | | #ifndef INTERNAL_JSONNODE_H | |
| #define INTERNAL_JSONNODE_H | | #define INTERNAL_JSONNODE_H | |
| | | | |
| #include "JSONDebug.h" | | #include "JSONDebug.h" | |
| #include "JSONChildren.h" | | #include "JSONChildren.h" | |
| #include "JSONMemory.h" | | #include "JSONMemory.h" | |
|
| | | #include "JSONGlobals.h" | |
| #ifdef JSON_DEBUG | | #ifdef JSON_DEBUG | |
| #include <climits> //to check int value | | #include <climits> //to check int value | |
| #endif | | #endif | |
|
| | | #include "JSONSharedString.h" | |
| | | | |
| #ifdef JSON_LESS_MEMORY | | #ifdef JSON_LESS_MEMORY | |
| #ifdef __GNUC__ | | #ifdef __GNUC__ | |
| #pragma pack(push, 1) | | #pragma pack(push, 1) | |
| #elif _MSC_VER | | #elif _MSC_VER | |
| #pragma pack(push, internalJSONNode_pack, 1) | | #pragma pack(push, internalJSONNode_pack, 1) | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| /* | | /* | |
| | | | |
| skipping to change at line 32 | | skipping to change at line 34 | |
| speed and memory reasons. | | speed and memory reasons. | |
| | | | |
| If JSON_REF_COUNT is not on, this internal structure still has an impor
tant | | If JSON_REF_COUNT is not on, this internal structure still has an impor
tant | |
| purpose, as it can be passed around by JSONNoders that are flagged as t
emporary | | purpose, as it can be passed around by JSONNoders that are flagged as t
emporary | |
| */ | | */ | |
| | | | |
| class JSONNode; //forward declaration | | class JSONNode; //forward declaration | |
| | | | |
| #ifndef JSON_LIBRARY | | #ifndef JSON_LIBRARY | |
| #define DECL_SET_INTEGER(type) void Set(type) json_nothrow json_write_p
riority; void Set(unsigned type) json_nothrow json_write_priority; | | #define DECL_SET_INTEGER(type) void Set(type) json_nothrow json_write_p
riority; void Set(unsigned type) json_nothrow json_write_priority; | |
|
| | | #define DECL_CAST_OP(type) operator type() const json_nothrow; operator
unsigned type() const json_nothrow; | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_MUTEX_CALLBACKS | | #ifdef JSON_MUTEX_CALLBACKS | |
| #define initializeMutex(x) ,mylock(x) | | #define initializeMutex(x) ,mylock(x) | |
| #else | | #else | |
| #define initializeMutex(x) | | #define initializeMutex(x) | |
| #endif | | #endif | |
| | | | |
| #if defined(JSON_PREPARSE) || !defined(JSON_READ_PRIORITY) | | #if defined(JSON_PREPARSE) || !defined(JSON_READ_PRIORITY) | |
| #define SetFetched(b) (void)0 | | #define SetFetched(b) (void)0 | |
| | | | |
| skipping to change at line 114 | | skipping to change at line 117 | |
| json_index_t size(void) const json_nothrow json_read_priority; | | json_index_t size(void) const json_nothrow json_read_priority; | |
| bool empty(void) const json_nothrow; | | bool empty(void) const json_nothrow; | |
| unsigned char type(void) const json_nothrow json_read_priority; | | unsigned char type(void) const json_nothrow json_read_priority; | |
| | | | |
| json_string name(void) const json_nothrow json_read_priority; | | json_string name(void) const json_nothrow json_read_priority; | |
| void setname(const json_string & newname) json_nothrow json_write_prior
ity; | | void setname(const json_string & newname) json_nothrow json_write_prior
ity; | |
| #ifdef JSON_COMMENTS | | #ifdef JSON_COMMENTS | |
| void setcomment(const json_string & comment) json_nothrow; | | void setcomment(const json_string & comment) json_nothrow; | |
| json_string getcomment(void) const json_nothrow; | | json_string getcomment(void) const json_nothrow; | |
| #endif | | #endif | |
|
| json_string as_string(void) const json_nothrow json_read_priority; | | | |
| long as_int(void) const json_nothrow json_read_priority; | | | |
| json_number as_float(void) const json_nothrow json_read_priority; | | | |
| bool as_bool(void) const json_nothrow json_read_priority; | | | |
| | | | |
| #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY) | | #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY) | |
| void preparse(void) json_nothrow; | | void preparse(void) json_nothrow; | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_LIBRARY | | #ifdef JSON_LIBRARY | |
| void push_back(JSONNode * node) json_nothrow; | | void push_back(JSONNode * node) json_nothrow; | |
| #else | | #else | |
| void push_back(const JSONNode & node) json_nothrow; | | void push_back(const JSONNode & node) json_nothrow; | |
| #endif | | #endif | |
| | | | |
| skipping to change at line 146 | | skipping to change at line 145 | |
| JSONNode * at(json_index_t pos) json_nothrow; | | JSONNode * at(json_index_t pos) json_nothrow; | |
| //These return ** because pop_back needs them | | //These return ** because pop_back needs them | |
| JSONNode ** at(const json_string & name_t) json_nothrow; | | JSONNode ** at(const json_string & name_t) json_nothrow; | |
| #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | | #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | |
| JSONNode ** at_nocase(const json_string & name_t) json_nothrow; | | JSONNode ** at_nocase(const json_string & name_t) json_nothrow; | |
| #endif | | #endif | |
| | | | |
| void Set(const json_string & val) json_nothrow json_write_priority; | | void Set(const json_string & val) json_nothrow json_write_priority; | |
| #ifdef JSON_LIBRARY | | #ifdef JSON_LIBRARY | |
| void Set(json_number val) json_nothrow json_write_priority; | | void Set(json_number val) json_nothrow json_write_priority; | |
|
| void Set(long val) json_nothrow json_write_priority; | | void Set(json_int_t val) json_nothrow json_write_priority; | |
| | | operator json_int_t() const json_nothrow; | |
| | | operator json_number() const json_nothrow; | |
| #else | | #else | |
| DECL_SET_INTEGER(char) | | DECL_SET_INTEGER(char) | |
| DECL_SET_INTEGER(short) | | DECL_SET_INTEGER(short) | |
| DECL_SET_INTEGER(int) | | DECL_SET_INTEGER(int) | |
| DECL_SET_INTEGER(long) | | DECL_SET_INTEGER(long) | |
| #ifndef JSON_ISO_STRICT | | #ifndef JSON_ISO_STRICT | |
| DECL_SET_INTEGER(long long) | | DECL_SET_INTEGER(long long) | |
|
| | | void Set(long double val) json_nothrow json_write_priority
; | |
| #endif | | #endif | |
|
| | | | |
| void Set(float val) json_nothrow json_write_priority; | | void Set(float val) json_nothrow json_write_priority; | |
| void Set(double val) json_nothrow json_write_priority; | | void Set(double val) json_nothrow json_write_priority; | |
|
| | | | |
| | | DECL_CAST_OP(char) | |
| | | DECL_CAST_OP(short) | |
| | | DECL_CAST_OP(int) | |
| | | DECL_CAST_OP(long) | |
| | | #ifndef JSON_ISO_STRICT | |
| | | DECL_CAST_OP(long long) | |
| | | operator long double() const json_nothrow; | |
| | | #endif | |
| | | operator float() const json_nothrow; | |
| | | operator double() const json_nothrow; | |
| #endif | | #endif | |
|
| | | operator json_string()const json_nothrow; | |
| | | operator bool() const json_nothrow; | |
| void Set(bool val) json_nothrow; | | void Set(bool val) json_nothrow; | |
| | | | |
| bool IsEqualTo(const json_string & val) const json_nothrow; | | bool IsEqualTo(const json_string & val) const json_nothrow; | |
| bool IsEqualTo(bool val) const json_nothrow; | | bool IsEqualTo(bool val) const json_nothrow; | |
| bool IsEqualTo(const internalJSONNode * val) const json_nothrow; | | bool IsEqualTo(const internalJSONNode * val) const json_nothrow; | |
| | | | |
| template<typename T> | | template<typename T> | |
| bool IsEqualToNum(T val) const json_nothrow; | | bool IsEqualToNum(T val) const json_nothrow; | |
| | | | |
| internalJSONNode * incRef(void) json_nothrow; | | internalJSONNode * incRef(void) json_nothrow; | |
| | | | |
| skipping to change at line 188 | | skipping to change at line 202 | |
| #ifdef JSON_MUTEX_CALLBACKS | | #ifdef JSON_MUTEX_CALLBACKS | |
| void _set_mutex(void * mutex, bool unset = true) json_nothrow jso
n_cold; | | void _set_mutex(void * mutex, bool unset = true) json_nothrow jso
n_cold; | |
| void _unset_mutex(void) json_nothrow json_cold; | | void _unset_mutex(void) json_nothrow json_cold; | |
| #endif | | #endif | |
| #ifdef JSON_UNIT_TEST | | #ifdef JSON_UNIT_TEST | |
| static void incinternalAllocCount(void) json_nothrow; | | static void incinternalAllocCount(void) json_nothrow; | |
| static void decinternalAllocCount(void) json_nothrow; | | static void decinternalAllocCount(void) json_nothrow; | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_WRITE_PRIORITY | | #ifdef JSON_WRITE_PRIORITY | |
|
| json_string WriteName(bool formatted, bool arrayChild) const json | | void WriteName(bool formatted, bool arrayChild, json_string & out | |
| _nothrow json_write_priority; | | put) const json_nothrow json_write_priority; | |
| json_string WriteChildren(unsigned int indent) json_nothrow json_ | | #ifdef JSON_ARRAY_SIZE_ON_ONE_LINE | |
| write_priority; | | void WriteChildrenOneLine(unsigned int indent, json_string | |
| json_string WriteComment(unsigned int indent) const json_nothrow | | & output) const json_nothrow json_write_priority; | |
| json_write_priority; | | #endif | |
| json_string Write(unsigned int indent, bool arrayChild) json_noth | | void WriteChildren(unsigned int indent, json_string & output) con | |
| row json_write_priority; | | st json_nothrow json_write_priority; | |
| | | void WriteComment(unsigned int indent, json_string & output) cons | |
| | | t json_nothrow json_write_priority; | |
| | | void Write(unsigned int indent, bool arrayChild, json_string & ou | |
| | | tput) const json_nothrow json_write_priority; | |
| #endif | | #endif | |
| | | | |
| inline bool isContainer(void) const json_nothrow { | | inline bool isContainer(void) const json_nothrow { | |
| return (_type == JSON_NODE || _type == JSON_ARRAY); | | return (_type == JSON_NODE || _type == JSON_ARRAY); | |
| } | | } | |
| inline bool isNotContainer(void) const json_nothrow { | | inline bool isNotContainer(void) const json_nothrow { | |
| return (_type != JSON_NODE && _type != JSON_ARRAY); | | return (_type != JSON_NODE && _type != JSON_ARRAY); | |
| } | | } | |
| | | | |
| #ifdef JSON_LESS_MEMORY | | #ifdef JSON_LESS_MEMORY | |
| | | | |
| skipping to change at line 286 | | skipping to change at line 303 | |
| | | | |
| #ifndef JSON_LESS_MEMORY | | #ifndef JSON_LESS_MEMORY | |
| jsonChildren * CHILDREN; | | jsonChildren * CHILDREN; | |
| #endif | | #endif | |
| }; | | }; | |
| | | | |
| inline internalJSONNode::internalJSONNode(char mytype) json_nothrow : _type
(mytype), _name(), _name_encoded(), _string(), _string_encoded(), _value() | | inline internalJSONNode::internalJSONNode(char mytype) json_nothrow : _type
(mytype), _name(), _name_encoded(), _string(), _string_encoded(), _value() | |
| initializeMutex(0) | | initializeMutex(0) | |
| initializeRefCount(1) | | initializeRefCount(1) | |
| initializeFetch(true) | | initializeFetch(true) | |
|
| initializeComment(EMPTY_JSON_STRING) | | initializeComment(json_global(EMPTY_JSON_STRING)) | |
| initializeChildren((_type == JSON_NODE || _type == JSON_ARRAY) ? jsonCh
ildren::newChildren() : 0){ | | initializeChildren((_type == JSON_NODE || _type == JSON_ARRAY) ? jsonCh
ildren::newChildren() : 0){ | |
| | | | |
| incinternalAllocCount(); | | incinternalAllocCount(); | |
| | | | |
| #ifdef JSON_LESS_MEMORY | | #ifdef JSON_LESS_MEMORY | |
| //if not less memory, its in the initialization list | | //if not less memory, its in the initialization list | |
| if (isContainer()){ | | if (isContainer()){ | |
| CHILDREN = jsonChildren::newChildren(); | | CHILDREN = jsonChildren::newChildren(); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| skipping to change at line 338 | | skipping to change at line 355 | |
| inline void internalJSONNode::setname(const json_string & newname) json_not
hrow { | | inline void internalJSONNode::setname(const json_string & newname) json_not
hrow { | |
| #ifdef JSON_LESS_MEMORY | | #ifdef JSON_LESS_MEMORY | |
| JSON_ASSERT(newname.capacity() == newname.length(), JSON_TEXT("na
me object too large")); | | JSON_ASSERT(newname.capacity() == newname.length(), JSON_TEXT("na
me object too large")); | |
| #endif | | #endif | |
| _name = newname; | | _name = newname; | |
| _name_encoded = true; | | _name_encoded = true; | |
| } | | } | |
| | | | |
| #ifdef JSON_COMMENTS | | #ifdef JSON_COMMENTS | |
| inline void internalJSONNode::setcomment(const json_string & comment) j
son_nothrow { | | inline void internalJSONNode::setcomment(const json_string & comment) j
son_nothrow { | |
|
| #ifdef JSON_LESS_MEMORY | | | |
| JSON_ASSERT(comment.capacity() == comment.length(), JSON_T | | | |
| EXT("comment object too large")); | | | |
| #endif | | | |
| _comment = comment; | | _comment = comment; | |
| } | | } | |
| | | | |
| inline json_string internalJSONNode::getcomment(void) const json_nothro
w { | | inline json_string internalJSONNode::getcomment(void) const json_nothro
w { | |
| return _comment; | | return _comment; | |
| } | | } | |
| #endif | | #endif | |
| | | | |
|
| inline json_string internalJSONNode::as_string(void) const json_nothrow { | | | |
| Fetch(); | | | |
| return _string; | | | |
| } | | | |
| | | | |
| inline long internalJSONNode::as_int(void) const json_nothrow { | | | |
| Fetch(); | | | |
| switch(type()){ | | | |
| case JSON_NULL: | | | |
| return 0; | | | |
| case JSON_BOOL: | | | |
| return _value._bool ? 1 : 0; | | | |
| case JSON_STRING: | | | |
| FetchNumber(); | | | |
| } | | | |
| JSON_ASSERT(type() == JSON_NUMBER, JSON_TEXT("as_int returning undefine | | | |
| d results")); | | | |
| JSON_ASSERT(_value._number > LONG_MIN, _string + JSON_TEXT(" is outside | | | |
| the lower range of long")); | | | |
| JSON_ASSERT(_value._number < LONG_MAX, _string + JSON_TEXT(" is outside | | | |
| the upper range of long")); | | | |
| JSON_ASSERT(_value._number == (json_number)((long)_value._number), json | | | |
| _string(JSON_TEXT("as_int will truncate ")) + _string); | | | |
| return (long)_value._number; | | | |
| } | | | |
| | | | |
| inline json_number internalJSONNode::as_float(void) const json_nothrow { | | | |
| Fetch(); | | | |
| switch(type()){ | | | |
| case JSON_NULL: | | | |
| return (json_number)0.0; | | | |
| case JSON_BOOL: | | | |
| return (json_number)(_value._bool ? 1.0 : 0.0); | | | |
| case JSON_STRING: | | | |
| FetchNumber(); | | | |
| } | | | |
| JSON_ASSERT(type() == JSON_NUMBER, JSON_TEXT("as_float returning undefi | | | |
| ned results")); | | | |
| return _value._number; | | | |
| } | | | |
| | | | |
| inline bool internalJSONNode::as_bool(void) const json_nothrow { | | | |
| Fetch(); | | | |
| switch(type()){ | | | |
| case JSON_NUMBER: | | | |
| return _value._number != 0.0f; | | | |
| case JSON_NULL: | | | |
| return false; | | | |
| } | | | |
| JSON_ASSERT(type() == JSON_BOOL, JSON_TEXT("as_bool returning undefined | | | |
| results")); | | | |
| return _value._bool; | | | |
| } | | | |
| | | | |
| inline bool internalJSONNode::IsEqualTo(const json_string & val) const json
_nothrow { | | inline bool internalJSONNode::IsEqualTo(const json_string & val) const json
_nothrow { | |
| if (type() != JSON_STRING) return false; | | if (type() != JSON_STRING) return false; | |
| Fetch(); | | Fetch(); | |
|
| return val == _string; | | return _string == val; | |
| } | | } | |
| | | | |
| inline bool internalJSONNode::IsEqualTo(bool val) const json_nothrow { | | inline bool internalJSONNode::IsEqualTo(bool val) const json_nothrow { | |
| if (type() != JSON_BOOL) return false; | | if (type() != JSON_BOOL) return false; | |
| Fetch(); | | Fetch(); | |
| return val == _value._bool; | | return val == _value._bool; | |
| } | | } | |
| | | | |
| template<typename T> | | template<typename T> | |
| inline bool internalJSONNode::IsEqualToNum(T val) const json_nothrow { | | inline bool internalJSONNode::IsEqualToNum(T val) const json_nothrow { | |
| | | | |
| skipping to change at line 455 | | skipping to change at line 421 | |
| | | | |
| inline bool internalJSONNode::Fetched(void) const json_nothrow { | | inline bool internalJSONNode::Fetched(void) const json_nothrow { | |
| #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY) | | #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY) | |
| return fetched; | | return fetched; | |
| #else | | #else | |
| return true; | | return true; | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| inline JSONNode ** internalJSONNode::begin(void) const json_nothrow { | | inline JSONNode ** internalJSONNode::begin(void) const json_nothrow { | |
|
| JSON_ASSERT_SAFE(isContainer(), JSON_TEXT("calling begin on non-contain
er type"), return 0;); | | JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON
_TEXT("begin"), return 0;); | |
| Fetch(); | | Fetch(); | |
| return CHILDREN -> begin(); | | return CHILDREN -> begin(); | |
| } | | } | |
| | | | |
| inline JSONNode ** internalJSONNode::end(void) const json_nothrow { | | inline JSONNode ** internalJSONNode::end(void) const json_nothrow { | |
|
| JSON_ASSERT_SAFE(isContainer(), JSON_TEXT("calling end on non-container
type"), return 0;); | | JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON
_TEXT("end"), return 0;); | |
| Fetch(); | | Fetch(); | |
| return CHILDREN -> end(); | | return CHILDREN -> end(); | |
| } | | } | |
| | | | |
| inline JSONNode * internalJSONNode::at(json_index_t pos) json_nothrow { | | inline JSONNode * internalJSONNode::at(json_index_t pos) json_nothrow { | |
| JSON_ASSERT_SAFE(isContainer(), JSON_TEXT("calling at on non-container
type"), return 0;); | | JSON_ASSERT_SAFE(isContainer(), JSON_TEXT("calling at on non-container
type"), return 0;); | |
| Fetch(); | | Fetch(); | |
| return (*CHILDREN)[pos]; | | return (*CHILDREN)[pos]; | |
| } | | } | |
| | | | |
| #if defined(JSON_LESS_MEMORY) && defined(__GNUC__) | | #if defined(JSON_LESS_MEMORY) && defined(__GNUC__) | |
|
| inline void internalJSONNode::reserve(json_index_t __attribute__((unuse
d)) siz) json_nothrow { | | inline void internalJSONNode::reserve(json_index_t __attribute__((unuse
d)) siz) json_nothrow | |
| #else | | #else | |
|
| inline void internalJSONNode::reserve(json_index_t siz) json_nothrow { | | inline void internalJSONNode::reserve(json_index_t siz) json_nothrow | |
| #endif | | #endif | |
|
| JSON_ASSERT_SAFE(isContainer(), JSON_TEXT("calling reserve on non-conta | | { | |
| iner type"), return;); | | JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON | |
| | | _TEXT("reserve"), return;); | |
| Fetch(); | | Fetch(); | |
| jsonChildren::reserve2(CHILDREN, siz); | | jsonChildren::reserve2(CHILDREN, siz); | |
| } | | } | |
| | | | |
| /* | | /* | |
|
| These functions are to allow allocation to be completely controlled by
the callbacks | | cast operators | |
| */ | | */ | |
|
| | | #ifndef JSON_LIBRARY | |
| inline void internalJSONNode::deleteInternal(internalJSONNode * ptr) json_n | | #ifdef JSON_ISO_STRICT | |
| othrow { | | #define BASE_CONVERT_TYPE long | |
| #ifdef JSON_MEMORY_CALLBACKS | | | |
| ptr -> ~internalJSONNode(); | | | |
| libjson_free<internalJSONNode>(ptr); | | | |
| #else | | #else | |
|
| delete ptr; | | #define BASE_CONVERT_TYPE long long | |
| #endif | | #endif | |
|
| } | | | |
| | | | |
|
| inline internalJSONNode * internalJSONNode::newInternal(char mytype) { | | #define IMP_SMALLER_INT_CAST_OP(_type, type_max, type_min)\ | |
| #ifdef JSON_MEMORY_CALLBACKS | | inline internalJSONNode::operator _type() const json_nothrow {\ | |
| return new(json_malloc<internalJSONNode>(1)) internalJSONNode(myt | | JSON_ASSERT(_value._number > type_min, _string + json_glob | |
| ype); | | al(ERROR_LOWER_RANGE) + JSON_TEXT(#_type));\ | |
| #else | | JSON_ASSERT(_value._number < type_max, _string + json_glob | |
| return new internalJSONNode(mytype); | | al(ERROR_UPPER_RANGE) + JSON_TEXT(#_type));\ | |
| #endif | | JSON_ASSERT(_value._number == (json_number)((_type)(_value | |
| } | | ._number)), json_string(JSON_TEXT("(")) + json_string(JSON_TEXT(#_type)) + | |
| | | json_string(JSON_TEXT(") will truncate ")) + _string);\ | |
| | | return (_type)static_cast<BASE_CONVERT_TYPE>(*this);\ | |
| | | } | |
| | | | |
|
| #ifdef JSON_READ_PRIORITY | | IMP_SMALLER_INT_CAST_OP(char, CHAR_MAX, CHAR_MIN) | |
| inline internalJSONNode * internalJSONNode::newInternal(const json_string & | | IMP_SMALLER_INT_CAST_OP(unsigned char, UCHAR_MAX, 0) | |
| unparsed) { | | IMP_SMALLER_INT_CAST_OP(short, SHRT_MAX, SHRT_MIN) | |
| #ifdef JSON_MEMORY_CALLBACKS | | IMP_SMALLER_INT_CAST_OP(unsigned short, USHRT_MAX, 0) | |
| return new(json_malloc<internalJSONNode>(1)) internalJSONNode(unp | | IMP_SMALLER_INT_CAST_OP(int, INT_MAX, INT_MIN) | |
| arsed); | | IMP_SMALLER_INT_CAST_OP(unsigned int, UINT_MAX, 0) | |
| #else | | | |
| return new internalJSONNode(unparsed); | | | |
| #endif | | | |
| } | | | |
| | | | |
|
| inline internalJSONNode * internalJSONNode::newInternal(const json_string & | | #ifndef JSON_ISO_STRICT | |
| name_t, const json_string & value_t) { | | IMP_SMALLER_INT_CAST_OP(long, LONG_MAX, LONG_MIN) | |
| #ifdef JSON_MEMORY_CALLBACKS | | IMP_SMALLER_INT_CAST_OP(unsigned long, ULONG_MAX, 0) | |
| return new(json_malloc<internalJSONNode>(1)) internalJSONNode(nam | | | |
| e_t, value_t); | | | |
| #else | | | |
| return new internalJSONNode(name_t, value_t); | | | |
| #endif | | #endif | |
|
| } | | | |
| #endif | | #endif | |
| | | | |
|
| inline internalJSONNode * internalJSONNode::newInternal(const internalJSONN | | inline internalJSONNode::operator json_string() const json_nothrow { | |
| ode & orig) { | | Fetch(); | |
| #ifdef JSON_MEMORY_CALLBACKS | | return _string; | |
| return new(json_malloc<internalJSONNode>(1)) internalJSONNode(ori | | } | |
| g); | | | |
| | | #ifndef JSON_LIBRARY | |
| | | #ifndef JSON_ISO_STRICT | |
| | | inline internalJSONNode::operator float() const json_nothrow { | |
| | | return static_cast<float>(static_cast<long double>(*this)) | |
| | | ; | |
| | | } | |
| | | inline internalJSONNode::operator double() const json_nothrow { | |
| | | return static_cast<double>(static_cast<long double>(*this) | |
| | | ); | |
| | | } | |
| #else | | #else | |
|
| return new internalJSONNode(orig); | | inline internalJSONNode::operator float() const json_nothrow { | |
| | | return static_cast<float>(static_cast<double>(*this)); | |
| | | } | |
| #endif | | #endif | |
|
| } | | #endif | |
| | | | |
| #ifdef JSON_LESS_MEMORY | | #ifdef JSON_LESS_MEMORY | |
| #ifdef __GNUC__ | | #ifdef __GNUC__ | |
| #pragma pack(pop) | | #pragma pack(pop) | |
| #elif _MSC_VER | | #elif _MSC_VER | |
| #pragma pack(pop, internalJSONNode_pack,) | | #pragma pack(pop, internalJSONNode_pack,) | |
| #endif | | #endif | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
End of changes. 30 change blocks. |
| 122 lines changed or deleted | | 85 lines changed or added | |
|
| libjson.h | | libjson.h | |
| | | | |
| skipping to change at line 68 | | skipping to change at line 68 | |
| void json_set_global_mutex(void * mutex); | | void json_set_global_mutex(void * mutex); | |
| void json_set_mutex(JSONNODE * node, void * mutex); | | void json_set_mutex(JSONNODE * node, void * mutex); | |
| void json_lock(JSONNODE * node, int threadid); | | void json_lock(JSONNODE * node, int threadid); | |
| void json_unlock(JSONNODE * node, int threadid); | | void json_unlock(JSONNODE * node, int threadid); | |
| #endif | | #endif | |
| #ifdef JSON_MEMORY_CALLBACKS | | #ifdef JSON_MEMORY_CALLBACKS | |
| void json_register_memory_callbacks(json_malloc_t m
al, json_realloc_t real, json_free_t fre); | | void json_register_memory_callbacks(json_malloc_t m
al, json_realloc_t real, json_free_t fre); | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_STREAM | | #ifdef JSON_STREAM | |
|
| JSONSTREAM * json_new_stream(json_stream_callback_t
callback); | | JSONSTREAM * json_new_stream(json_stream_callback_t
callback, json_stream_e_callback_t e_callback, void * identifier); | |
| void json_stream_push(JSONSTREAM * stream, json_con
st json_char * addendum); | | void json_stream_push(JSONSTREAM * stream, json_con
st json_char * addendum); | |
| void json_delete_stream(JSONSTREAM * stream); | | void json_delete_stream(JSONSTREAM * stream); | |
|
| | | void json_stream_reset(JSONSTREAM * stream); | |
| #endif | | #endif | |
| | | | |
| /* | | /* | |
| stuff that's in class JSONNode | | stuff that's in class JSONNode | |
| */ | | */ | |
| /* ctors */ | | /* ctors */ | |
| JSONNODE * json_new_a(json_const json_char * name, json_co
nst json_char * value); | | JSONNODE * json_new_a(json_const json_char * name, json_co
nst json_char * value); | |
|
| JSONNODE * json_new_i(json_const json_char * name, long va
lue); | | JSONNODE * json_new_i(json_const json_char * name, json_in
t_t value); | |
| JSONNODE * json_new_f(json_const json_char * name, json_nu
mber value); | | JSONNODE * json_new_f(json_const json_char * name, json_nu
mber value); | |
| JSONNODE * json_new_b(json_const json_char * name, json_bo
ol_t value); | | JSONNODE * json_new_b(json_const json_char * name, json_bo
ol_t value); | |
| JSONNODE * json_new(char type); | | JSONNODE * json_new(char type); | |
| JSONNODE * json_copy(json_const JSONNODE * orig); | | JSONNODE * json_copy(json_const JSONNODE * orig); | |
| JSONNODE * json_duplicate(json_const JSONNODE * orig); | | JSONNODE * json_duplicate(json_const JSONNODE * orig); | |
| | | | |
| /* assignment */ | | /* assignment */ | |
| void json_set_a(JSONNODE * node, json_const json_char * va
lue); | | void json_set_a(JSONNODE * node, json_const json_char * va
lue); | |
|
| void json_set_i(JSONNODE * node, long value); | | void json_set_i(JSONNODE * node, json_int_t value); | |
| void json_set_f(JSONNODE * node, json_number value); | | void json_set_f(JSONNODE * node, json_number value); | |
| void json_set_b(JSONNODE * node, json_bool_t value); | | void json_set_b(JSONNODE * node, json_bool_t value); | |
| void json_set_n(JSONNODE * node, json_const JSONNODE * ori
g); | | void json_set_n(JSONNODE * node, json_const JSONNODE * ori
g); | |
| | | | |
| /* inspectors */ | | /* inspectors */ | |
| char json_type(json_const JSONNODE * node); | | char json_type(json_const JSONNODE * node); | |
| json_index_t json_size(json_const JSONNODE * node); | | json_index_t json_size(json_const JSONNODE * node); | |
| json_bool_t json_empty(json_const JSONNODE * node); | | json_bool_t json_empty(json_const JSONNODE * node); | |
| json_char * json_name(json_const JSONNODE * node); | | json_char * json_name(json_const JSONNODE * node); | |
| #ifdef JSON_COMMENTS | | #ifdef JSON_COMMENTS | |
| json_char * json_get_comment(json_const JSONNODE *
node); | | json_char * json_get_comment(json_const JSONNODE *
node); | |
| #endif | | #endif | |
| json_char * json_as_string(json_const JSONNODE * node); | | json_char * json_as_string(json_const JSONNODE * node); | |
|
| long json_as_int(json_const JSONNODE * node); | | json_int_t json_as_int(json_const JSONNODE * node); | |
| json_number json_as_float(json_const JSONNODE * node); | | json_number json_as_float(json_const JSONNODE * node); | |
| json_bool_t json_as_bool(json_const JSONNODE * node); | | json_bool_t json_as_bool(json_const JSONNODE * node); | |
|
| JSONNODE * json_as_node(json_const JSONNODE * node); | | #ifdef JSON_CASTABLE | |
| JSONNODE * json_as_array(json_const JSONNODE * node); | | JSONNODE * json_as_node(json_const JSONNODE * node) | |
| | | ; | |
| | | JSONNODE * json_as_array(json_const JSONNODE * node | |
| | | ); | |
| | | #endif | |
| #ifdef JSON_BINARY | | #ifdef JSON_BINARY | |
| void * json_as_binary(json_const JSONNODE * node, u
nsigned long * size); | | void * json_as_binary(json_const JSONNODE * node, u
nsigned long * size); | |
| #endif | | #endif | |
| #ifdef JSON_WRITE_PRIORITY | | #ifdef JSON_WRITE_PRIORITY | |
| json_char * json_write(json_const JSONNODE * node); | | json_char * json_write(json_const JSONNODE * node); | |
| json_char * json_write_formatted(json_const JSONNOD
E * node); | | json_char * json_write_formatted(json_const JSONNOD
E * node); | |
| #endif | | #endif | |
| | | | |
| /* modifiers */ | | /* modifiers */ | |
| void json_set_name(JSONNODE * node, json_const json_char *
name); | | void json_set_name(JSONNODE * node, json_const json_char *
name); | |
| | | | |
| skipping to change at line 133 | | skipping to change at line 136 | |
| #if !defined (JSON_PREPARSE) && defined(JSON_READ_PRIORITY
) | | #if !defined (JSON_PREPARSE) && defined(JSON_READ_PRIORITY
) | |
| void json_preparse(JSONNODE * node); | | void json_preparse(JSONNODE * node); | |
| #endif | | #endif | |
| #ifdef JSON_BINARY | | #ifdef JSON_BINARY | |
| void json_set_binary(JSONNODE * node, json_const vo
id * data, unsigned long length); | | void json_set_binary(JSONNODE * node, json_const vo
id * data, unsigned long length); | |
| #endif | | #endif | |
| #ifdef JSON_EXPOSE_BASE64 | | #ifdef JSON_EXPOSE_BASE64 | |
| json_char * json_encode64(json_const void * binary,
json_index_t bytes); | | json_char * json_encode64(json_const void * binary,
json_index_t bytes); | |
| void * json_decode64(json_const json_char * text, u
nsigned long * size); | | void * json_decode64(json_const json_char * text, u
nsigned long * size); | |
| #endif | | #endif | |
|
| void json_cast(JSONNODE * node, char type); | | #ifdef JSON_CASTABLE | |
| | | void json_cast(JSONNODE * node, char type); | |
| | | #endif | |
| | | | |
| /* children access */ | | /* children access */ | |
| void json_reserve(JSONNODE * node, json_index_t siz); | | void json_reserve(JSONNODE * node, json_index_t siz); | |
| JSONNODE * json_at(JSONNODE * node, json_index_t pos); | | JSONNODE * json_at(JSONNODE * node, json_index_t pos); | |
| JSONNODE * json_get(JSONNODE * node, json_const json_char
* name); | | JSONNODE * json_get(JSONNODE * node, json_const json_char
* name); | |
| #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | | #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS | |
| JSONNODE * json_get_nocase(JSONNODE * node, json_co
nst json_char * name); | | JSONNODE * json_get_nocase(JSONNODE * node, json_co
nst json_char * name); | |
| JSONNODE * json_pop_back_nocase(JSONNODE * node, js
on_const json_char * name); | | JSONNODE * json_pop_back_nocase(JSONNODE * node, js
on_const json_char * name); | |
| #endif | | #endif | |
| void json_push_back(JSONNODE * node, JSONNODE * node2); | | void json_push_back(JSONNODE * node, JSONNODE * node2); | |
| | | | |
| skipping to change at line 169 | | skipping to change at line 174 | |
| #endif | | #endif | |
| | | | |
| /* comparison */ | | /* comparison */ | |
| json_bool_t json_equal(JSONNODE * node, JSONNODE * node2); | | json_bool_t json_equal(JSONNODE * node, JSONNODE * node2); | |
| | | | |
| #ifdef __cplusplus | | #ifdef __cplusplus | |
| } | | } | |
| #endif | | #endif | |
| #else | | #else | |
| #ifndef __cplusplus | | #ifndef __cplusplus | |
|
| #error Using the non-library requires C++ | | #error Turning off JSON_LIBRARY requires C++ | |
| #endif | | #endif | |
| #include "Source/JSONNode.h" //not used in this file, but libjson.h sh
ould be the only file required to use it embedded | | #include "Source/JSONNode.h" //not used in this file, but libjson.h sh
ould be the only file required to use it embedded | |
| #include "Source/JSONWorker.h" | | #include "Source/JSONWorker.h" | |
| #include "Source/JSONValidator.h" | | #include "Source/JSONValidator.h" | |
| #include "Source/JSONStream.h" | | #include "Source/JSONStream.h" | |
|
| | | #include "Source/JSONPreparse.h" | |
| #ifdef JSON_EXPOSE_BASE64 | | #ifdef JSON_EXPOSE_BASE64 | |
|
| #include "JSON_Base64.h" | | #include "Source/JSON_Base64.h" | |
| | | #endif | |
| | | #ifndef JSON_NO_EXCEPTIONS | |
| | | #include <stdexcept> //some methods throw exceptions | |
| #endif | | #endif | |
|
| #include <stdexcept> //some methods throw exceptions | | | |
| | | #include <cwchar> /* need wide characters */ | |
| | | #include <string> | |
| | | | |
| namespace libjson { | | namespace libjson { | |
| #ifdef JSON_EXPOSE_BASE64 | | #ifdef JSON_EXPOSE_BASE64 | |
|
| inline static json_string encode64(const unsigned char * b
inary, size_t bytes) json_nothrow json_cold { | | inline static json_string encode64(const unsigned char * b
inary, size_t bytes) json_nothrow { | |
| return JSONBase64::json_encode64(binary, bytes); | | return JSONBase64::json_encode64(binary, bytes); | |
| } | | } | |
| | | | |
|
| inline static std::string decode64(const json_string & enc
oded) json_nothrow json_cold { | | inline static std::string decode64(const json_string & enc
oded) json_nothrow { | |
| return JSONBase64::json_decode64(encoded); | | return JSONBase64::json_decode64(encoded); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
|
| | | //useful if you have json that you don't want to parse, just want | |
| | | to strip to cut down on space | |
| | | inline static json_string strip_white_space(const json_string & j | |
| | | son) json_nothrow { | |
| | | return JSONWorker::RemoveWhiteSpaceAndComments(json, false | |
| | | ); | |
| | | } | |
| | | | |
| | | #ifndef JSON_STRING_HEADER | |
| | | inline static std::string to_std_string(const json_s | |
| | | tring & str){ | |
| | | #if defined(JSON_UNICODE) ||defined(JSON_MEM | |
| | | ORY_CALLBACKS) || defined(JSON_MEMORY_POOL) | |
| | | return std::string(str.begin(), str. | |
| | | end()); | |
| | | #else | |
| | | return str; | |
| | | #endif | |
| | | } | |
| | | inline static std::wstring to_std_wstring(const json | |
| | | _string & str){ | |
| | | #if (!defined(JSON_UNICODE)) || defined(JSON | |
| | | _MEMORY_CALLBACKS) || defined(JSON_MEMORY_POOL) | |
| | | return std::wstring(str.begin(), str | |
| | | .end()); | |
| | | #else | |
| | | return str; | |
| | | #endif | |
| | | } | |
| | | | |
| | | inline static json_string to_json_string(const std:: | |
| | | string & str){ | |
| | | #if defined(JSON_UNICODE) ||defined(JSON_MEM | |
| | | ORY_CALLBACKS) || defined(JSON_MEMORY_POOL) | |
| | | return json_string(str.begin(), str. | |
| | | end()); | |
| | | #else | |
| | | return str; | |
| | | #endif | |
| | | } | |
| | | inline static json_string to_json_string(const std:: | |
| | | wstring & str){ | |
| | | #if (!defined(JSON_UNICODE)) || defined(JSON | |
| | | _MEMORY_CALLBACKS) || defined(JSON_MEMORY_POOL) | |
| | | return json_string(str.begin(), str. | |
| | | end()); | |
| | | #else | |
| | | return str; | |
| | | #endif | |
| | | } | |
| | | #endif | |
| | | | |
| #ifdef JSON_READ_PRIORITY | | #ifdef JSON_READ_PRIORITY | |
| //if json is invalid, it throws a std::invalid_argument ex
ception | | //if json is invalid, it throws a std::invalid_argument ex
ception | |
| inline static JSONNode parse(const json_string & json) jso
n_throws(std::invalid_argument) { | | inline static JSONNode parse(const json_string & json) jso
n_throws(std::invalid_argument) { | |
|
| return JSONWorker::parse(json); | | #ifdef JSON_PREPARSE | |
| | | #if defined JSON_DEBUG || defined JSON_SAFE | |
| | | json_char temp; | |
| | | json_auto<json_char> buffer(JSONWork | |
| | | er::RemoveWhiteSpace(json, temp, false)); | |
| | | #else | |
| | | json_auto<json_char> buffer(JSONWork | |
| | | er::RemoveWhiteSpace(json, false)); | |
| | | #endif | |
| | | return JSONPreparse::isValidRoot(buffer.ptr) | |
| | | ; | |
| | | #else | |
| | | return JSONWorker::parse(json); | |
| | | #endif | |
| } | | } | |
| | | | |
| inline static JSONNode parse_unformatted(const json_string
& json) json_throws(std::invalid_argument) { | | inline static JSONNode parse_unformatted(const json_string
& json) json_throws(std::invalid_argument) { | |
|
| return JSONWorker::parse_unformatted(json); | | #ifdef JSON_PREPARSE | |
| | | return JSONPreparse::isValidRoot(json); | |
| | | #else | |
| | | return JSONWorker::parse_unformatted(json); | |
| | | #endif | |
| } | | } | |
| | | | |
| #ifdef JSON_VALIDATE | | #ifdef JSON_VALIDATE | |
| inline static bool is_valid(const json_string & jso
n) json_nothrow { | | inline static bool is_valid(const json_string & jso
n) json_nothrow { | |
|
| return JSONValidator::isValidRoot(JSONWorker | | #ifdef JSON_SECURITY_MAX_STRING_LENGTH | |
| ::RemoveWhiteSpaceAndComments(json).c_str()); | | if (json_unlikely(json.length() > JSON_S | |
| | | ECURITY_MAX_STRING_LENGTH)){ | |
| | | JSON_FAIL(JSON_TEXT("Exceeding JS | |
| | | ON_SECURITY_MAX_STRING_LENGTH")); | |
| | | return false; | |
| | | } | |
| | | #endif | |
| | | return JSONValidator::isValidRoot(JSONWorker | |
| | | ::RemoveWhiteSpaceAndComments(json, false).c_str()); | |
| } | | } | |
| | | | |
| inline static bool is_valid_unformatted(const json_
string & json) json_nothrow { | | inline static bool is_valid_unformatted(const json_
string & json) json_nothrow { | |
|
| | | #ifdef JSON_SECURITY_MAX_STRING_LENGTH | |
| | | if (json_unlikely(json.length() > JSON_S | |
| | | ECURITY_MAX_STRING_LENGTH)){ | |
| | | JSON_FAIL(JSON_TEXT("Exceeding JS | |
| | | ON_SECURITY_MAX_STRING_LENGTH")); | |
| | | return false; | |
| | | } | |
| | | #endif | |
| return JSONValidator::isValidRoot(json.c_str
()); | | return JSONValidator::isValidRoot(json.c_str
()); | |
| } | | } | |
| #ifdef JSON_DEPRECATED_FUNCTIONS | | #ifdef JSON_DEPRECATED_FUNCTIONS | |
| #ifdef JSON_NO_EXCEPTIONS | | #ifdef JSON_NO_EXCEPTIONS | |
| #error, JSON_DEPRECATED_FUNCTIONS requir
es JSON_NO_EXCEPTIONS be off | | #error, JSON_DEPRECATED_FUNCTIONS requir
es JSON_NO_EXCEPTIONS be off | |
| #endif | | #endif | |
| //if json is invalid, it throws a std::inval
id_argument exception (differs from parse because this checks the entire tr
ee) | | //if json is invalid, it throws a std::inval
id_argument exception (differs from parse because this checks the entire tr
ee) | |
| inline static JSONNode json_deprecated(valid
ate(const json_string & json), "libjson::validate is deprecated, use libjso
n::is_valid and libjson::parse instead"); | | inline static JSONNode json_deprecated(valid
ate(const json_string & json), "libjson::validate is deprecated, use libjso
n::is_valid and libjson::parse instead"); | |
| #endif | | #endif | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
|
| //useful if you have json that you don't want to parse, just want | | | |
| to strip to cut down on space | | | |
| inline static json_string strip_white_space(const json_string & j | | | |
| son) json_nothrow { | | | |
| return JSONWorker::RemoveWhiteSpaceAndComments(json); | | | |
| } | | | |
| | | | |
| //When libjson errors, a callback allows the user to know what we
nt wrong | | //When libjson errors, a callback allows the user to know what we
nt wrong | |
| #if defined JSON_DEBUG && !defined JSON_STDERROR | | #if defined JSON_DEBUG && !defined JSON_STDERROR | |
| inline static void register_debug_callback(json_error_call
back_t callback) json_nothrow { | | inline static void register_debug_callback(json_error_call
back_t callback) json_nothrow { | |
| JSONDebug::register_callback(callback); | | JSONDebug::register_callback(callback); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| #ifdef JSON_MUTEX_CALLBACKS | | #ifdef JSON_MUTEX_CALLBACKS | |
| #ifdef JSON_MUTEX_MANAGE | | #ifdef JSON_MUTEX_MANAGE | |
| inline static void register_mutex_callbacks(json_mu
tex_callback_t lock, json_mutex_callback_t unlock, json_mutex_callback_t de
stroy, void * manager_lock) json_nothrow { | | inline static void register_mutex_callbacks(json_mu
tex_callback_t lock, json_mutex_callback_t unlock, json_mutex_callback_t de
stroy, void * manager_lock) json_nothrow { | |
| | | | |
End of changes. 19 change blocks. |
| 23 lines changed or deleted | | 114 lines changed or added | |
|