JSONChildren.h   JSONChildren.h 
#ifndef JSONCHILDREN_H #ifndef JSONCHILDREN_H
#define JSONCHILDREN_H #define JSONCHILDREN_H
#include "JSONMemory.h" #include "JSONMemory.h"
#include "JSONDebug.h" //for JSON_ASSERT macro #include "JSONDebug.h" //for JSON_ASSERT macro
#define json_foreach(children, iterator)\ #ifdef JSON_LESS_MEMORY
JSONNode ** iterator = children.begin();\ #ifdef __GNUC__
for(JSONNode ** iterator##_end = children.end(); iterator != iterator## #pragma pack(push, 1)
_end; ++iterator) #elif _MSC_VER
#pragma pack(push, jsonChildren, 1)
#endif
#endif
#define json_foreach(chldrn, itrtr)\
JSONNode ** itrtr = chldrn -> begin();\
for(JSONNode ** itrtr##_end = chldrn -> end(); itrtr != itrtr##_end; ++
itrtr)
/* /*
This class is essentially a vector that has been heavily optimized for the specific purpose This class is essentially a vector that has been heavily optimized for the specific purpose
of holding JSONNode children. It acts the same way as a vector, it has a automatically of holding JSONNode children. It acts the same way as a vector, it has a automatically
expanding array. On destruction, this container automatically destroys ev erything contained expanding array. On destruction, this container automatically destroys ev erything contained
in it as well, so that you libjson doesn't have to do that. in it as well, so that you libjson doesn't have to do that.
T is JSONNode*, I can't define it that way directly because JSONNode uses this container, and because T is JSONNode*, I can't define it that way directly because JSONNode uses this container, and because
the container deletes the children automatically, forward declaration can' t be used the container deletes the children automatically, forward declaration can' t be used
*/ */
class JSONNode; //forward declaration class JSONNode; //forward declaration
#ifdef JSON_LESS_MEMORY
#define childrenVirtual virtual
#else
#define childrenVirtual
#endif
#ifndef JSON_UNIT_TEST
#define addAllocCount() (void)0
#define subAllocCount() (void)0
#endif
class jsonChildren { class jsonChildren {
public: public:
//starts completely empty and the array is not allocated //starts completely empty and the array is not allocated
jsonChildren(void) : array(0), mysize(0), mycapacity(0) { } jsonChildren(void) json_nothrow : array(0), mysize(0), mycapacity(0) {
addAllocCount();
}
#ifdef JSON_LESS_MEMORY
jsonChildren(JSONNode** ar, json_index_t si, json_index_t ca) jso
n_nothrow : array(ar), mysize(si), mycapacity(ca) {
addAllocCount();
}
#endif
//deletes the array and everything that is contained within it (using d elete) //deletes the array and everything that is contained within it (using d elete)
~jsonChildren(void){ childrenVirtual ~jsonChildren(void) json_nothrow {
if (array){ //the following function calls are safe, but take mo if (json_unlikely(array != 0)){ //the following function calls a
re time than a check here re safe, but take more time than a check here
deleteAll(); deleteAll();
libjson_free<JSONNode*>(array); libjson_free<JSONNode*>(array);
} }
subAllocCount();
} }
#ifdef JSON_UNIT_TEST
void addAllocCount(void);
void subAllocCount(void);
#endif
//increase the size of the array //increase the size of the array
void inc(json_index_t amount); void inc(json_index_t amount) json_nothrow;
void inc(void); void inc(void) json_nothrow;
//Adds something to the vector, doubling the array if necessary //Adds something to the vector, doubling the array if necessary
void push_back(JSONNode * item){ void push_back(JSONNode * item) json_nothrow {
JSON_ASSERT(this != 0, JSON_TEXT("Children is null push_back"));
inc(); inc();
array[mysize++] = item; array[mysize++] = item;
} }
//Adds something to the front of the vector, doubling the array if nece ssary //Adds something to the front of the vector, doubling the array if nece ssary
void push_front(JSONNode * item){ void push_front(JSONNode * item) json_nothrow {
JSON_ASSERT(this != 0, JSON_TEXT("Children is null push_front"));
inc(); inc();
memmove(array + 1, array, mysize++ * sizeof(JSONNode *)); memmove(array + 1, array, mysize++ * sizeof(JSONNode *));
array[0] = item; array[0] = item;
} }
//gets an item out of the vector by it's position //gets an item out of the vector by it's position
inline JSONNode * operator[] (json_index_t position) const { inline JSONNode * operator[] (json_index_t position) const json_nothrow
{
JSON_ASSERT(this != 0, JSON_TEXT("Children is null []"));
JSON_ASSERT(position < mysize, JSON_TEXT("Using [] out of bounds" )); JSON_ASSERT(position < mysize, JSON_TEXT("Using [] out of bounds" ));
JSON_ASSERT(position < mycapacity, JSON_TEXT("Using [] out of bou nds")); JSON_ASSERT(position < mycapacity, JSON_TEXT("Using [] out of bou nds"));
JSON_ASSERT(array, JSON_TEXT("Array is null")); JSON_ASSERT(array != 0, JSON_TEXT("Array is null"));
return array[position]; return array[position];
} }
//returns the allocated capacity, but keep in mind that some might not be valid //returns the allocated capacity, but keep in mind that some might not be valid
inline json_index_t capacity() const { inline json_index_t capacity() const json_nothrow {
JSON_ASSERT(this != 0, JSON_TEXT("Children is null capacity"));
return mycapacity; return mycapacity;
} }
//returns the number of valid objects within the vector //returns the number of valid objects within the vector
inline json_index_t size() const { inline json_index_t size() const json_nothrow {
JSON_ASSERT(this != 0, JSON_TEXT("Children is null size"));
return mysize; return mysize;
} }
//tests whether or not the vector is empty //tests whether or not the vector is empty
inline bool empty() const { inline bool empty() const json_nothrow {
JSON_ASSERT(this != 0, JSON_TEXT("Children is null empty"));
return mysize == 0; return mysize == 0;
} }
//clears (and deletes) everything from the vector and sets it's size to 0 //clears (and deletes) everything from the vector and sets it's size to 0
inline void clear(){ inline void clear() json_nothrow {
if (array){ //don't bother clearing anything if there is nothing JSON_ASSERT(this != 0, JSON_TEXT("Children is null clear"));
in it if (json_likely(array != 0)){ //don't bother clearing anything i
f there is nothing in it
JSON_ASSERT(mycapacity != 0, JSON_TEXT("mycapacity is not zero, but array is null")); JSON_ASSERT(mycapacity != 0, JSON_TEXT("mycapacity is not zero, but array is null"));
deleteAll(); deleteAll();
mysize = 0; mysize = 0;
} }
JSON_ASSERT(mysize == 0, JSON_TEXT("mysize is not zero after clea r")); JSON_ASSERT(mysize == 0, JSON_TEXT("mysize is not zero after clea r"));
} }
//returns the beginning of the array //returns the beginning of the array
inline JSONNode ** begin(void) const { inline JSONNode ** begin(void) const json_nothrow {
JSON_ASSERT(this != 0, JSON_TEXT("Children is null begin"));
return array; return array;
} }
//returns the end of the array //returns the end of the array
inline JSONNode ** end(void) const { inline JSONNode ** end(void) const json_nothrow {
JSON_ASSERT(this != 0, JSON_TEXT("Children is null end"));
return array + mysize; return array + mysize;
} }
//makes sure that even after shirnking and expanding, the iterator is i n same relative position //makes sure that even after shirnking and expanding, the iterator is i n same relative position
struct iteratorKeeper { struct iteratorKeeper {
public: public:
#ifdef JSON_LIBRARY #ifdef JSON_LIBRARY
iteratorKeeper(jsonChildren * pthis, JSONNode ** & positio n) : iteratorKeeper(jsonChildren * pthis, JSONNode ** & positio n) json_nothrow :
myRelativeOffset((json_index_t)(position - pthis -> array)), myRelativeOffset((json_index_t)(position - pthis -> array)),
#else #else
iteratorKeeper(jsonChildren * pthis, JSONNode ** & positio n, bool reverse = false) : iteratorKeeper(jsonChildren * pthis, JSONNode ** & positio n, bool reverse = false) json_nothrow :
myRelativeOffset(reverse ? (json_index_t)(pthis -> array + (size_t)pthis -> mysize - position) : (json_index_t)(position - pth is -> array)), myRelativeOffset(reverse ? (json_index_t)(pthis -> array + (size_t)pthis -> mysize - position) : (json_index_t)(position - pth is -> array)),
myReverse(reverse), myReverse(reverse),
#endif #endif
myChildren(pthis), myChildren(pthis),
myPos(position){} myPos(position){}
~iteratorKeeper(void){ ~iteratorKeeper(void) json_nothrow {
#ifdef JSON_LIBRARY #ifdef JSON_LIBRARY
myPos = myChildren -> array + myRelativeOffset; myPos = myChildren -> array + myRelativeOffset;
#else #else
if (myReverse){ if (json_unlikely(myReverse)){
myPos = myChildren -> array + myChildren -> mysize - myRelativeOffset; myPos = myChildren -> array + myChildren -> mysize - myRelativeOffset;
} else { } else {
myPos = myChildren -> array + myRelativeOffs et; myPos = myChildren -> array + myRelativeOffs et;
} }
#endif #endif
} }
private: private:
iteratorKeeper(const iteratorKeeper &); iteratorKeeper(const iteratorKeeper &);
iteratorKeeper & operator = (const iteratorKeeper &); iteratorKeeper & operator = (const iteratorKeeper &);
json_index_t myRelativeOffset;
jsonChildren * myChildren; jsonChildren * myChildren;
JSONNode ** & myPos; JSONNode ** & myPos;
json_index_t myRelativeOffset;
#ifndef JSON_LIBRARY #ifndef JSON_LIBRARY
bool myReverse BITS(1); bool myReverse BITS(1);
#endif #endif
}; };
//This function DOES NOT delete the item it points to //This function DOES NOT delete the item it points to
inline void erase(JSONNode ** & position){ inline void erase(JSONNode ** & position) json_nothrow {
JSON_ASSERT(array, JSON_TEXT("erasing something from a null array JSON_ASSERT(this != 0, JSON_TEXT("Children is null erase"));
1")); JSON_ASSERT(array != 0, JSON_TEXT("erasing something from a null
array 1"));
JSON_ASSERT(position >= array, JSON_TEXT("position is beneath the start of the array 1")); JSON_ASSERT(position >= array, JSON_TEXT("position is beneath the start of the array 1"));
JSON_ASSERT(position <= array + mysize, JSON_TEXT("erasing out of bounds 1")); JSON_ASSERT(position <= array + mysize, JSON_TEXT("erasing out of bounds 1"));
memmove(position, position + 1, (mysize-- - (position - array) - 1) * sizeof(JSONNode *)); memmove(position, position + 1, (mysize-- - (position - array) - 1) * sizeof(JSONNode *));
iteratorKeeper ik(this, position); iteratorKeeper ik(this, position);
shrink(); shrink();
} }
//This function DOES NOT delete the item it points to //This function DOES NOT delete the item it points to
inline void erase(JSONNode ** & position, json_index_t number){ inline void erase(JSONNode ** & position, json_index_t number) json_not
hrow {
JSON_ASSERT(this != 0, JSON_TEXT("Children is null erase 2"));
doerase(position, number); doerase(position, number);
iteratorKeeper ik(this, position); iteratorKeeper ik(this, position);
shrink(); shrink();
} }
//This function DOES NOT delete the item it points to //This function DOES NOT delete the item it points to
inline void erase(JSONNode ** position, json_index_t number, JSONNode * inline void erase(JSONNode ** position, json_index_t number, JSONNode *
* & starter){ * & starter) json_nothrow {
JSON_ASSERT(this != 0, JSON_TEXT("Children is null erase 3"));
doerase(position, number); doerase(position, number);
iteratorKeeper ik(this, starter); iteratorKeeper ik(this, starter);
shrink(); shrink();
} }
#ifdef JSON_LIBRARY #ifdef JSON_LIBRARY
void insert(JSONNode ** & position, JSONNode * item){ void insert(JSONNode ** & position, JSONNode * item) json_nothrow {
#else #else
void insert(JSONNode ** & position, JSONNode * item, bool reverse = false){ void insert(JSONNode ** & position, JSONNode * item, bool reverse = false) json_nothrow {
#endif #endif
JSON_ASSERT(this != 0, JSON_TEXT("Children is null insert"));
//position isnt relative to array because of realloc //position isnt relative to array because of realloc
JSON_ASSERT(position >= array, JSON_TEXT("position is beneath the start of the array insert 1")); JSON_ASSERT(position >= array, JSON_TEXT("position is beneath the start of the array insert 1"));
JSON_ASSERT(position <= array + mysize, JSON_TEXT("position is ab ove the end of the array insert 1")); JSON_ASSERT(position <= array + mysize, JSON_TEXT("position is ab ove the end of the array insert 1"));
{ {
#ifdef JSON_LIBRARY #ifdef JSON_LIBRARY
iteratorKeeper ik(this, position); iteratorKeeper ik(this, position);
#else #else
iteratorKeeper ik(this, position, reverse); iteratorKeeper ik(this, position, reverse);
#endif #endif
inc(); inc();
} }
memmove(position + 1, position, (mysize++ - (position - array)) * sizeof(JSONNode *)); memmove(position + 1, position, (mysize++ - (position - array)) * sizeof(JSONNode *));
*position = item; *position = item;
} }
void insert(JSONNode ** & position, JSONNode ** items, json_index_t num void insert(JSONNode ** & position, JSONNode ** items, json_index_t num
){ ) json_nothrow {
JSON_ASSERT(this != 0, JSON_TEXT("Children is null insert 2"));
JSON_ASSERT(position >= array, JSON_TEXT("position is beneath the start of the array insert 2")); JSON_ASSERT(position >= array, JSON_TEXT("position is beneath the start of the array insert 2"));
JSON_ASSERT(position <= array + mysize, JSON_TEXT("position is ab ove the end of the array insert 2")); JSON_ASSERT(position <= array + mysize, JSON_TEXT("position is ab ove the end of the array insert 2"));
{ {
iteratorKeeper ik(this, position); iteratorKeeper ik(this, position);
inc(num); inc(num);
} }
const size_t ptrs = ((JSONNode **)(array + mysize)) - position; const size_t ptrs = ((JSONNode **)(array + mysize)) - position;
memmove(position + num, position, ptrs * sizeof(JSONNode *)); memmove(position + num, position, ptrs * sizeof(JSONNode *));
memcpy(position, items, num * sizeof(JSONNode *)); memcpy(position, items, num * sizeof(JSONNode *));
mysize += num; mysize += num;
} }
inline void reserve(json_index_t amount){ inline void reserve(json_index_t amount) json_nothrow {
JSON_ASSERT(!array, JSON_TEXT("reserve is not meant to expand a p JSON_ASSERT(this != 0, JSON_TEXT("Children is null reserve"));
reexisting array")); JSON_ASSERT(array == 0, JSON_TEXT("reserve is not meant to expand
JSON_ASSERT(!mycapacity, JSON_TEXT("reservec is not meant to expa a preexisting array"));
nd a preexisting array")); JSON_ASSERT(mycapacity == 0, JSON_TEXT("reservec is not meant to
JSON_ASSERT(!mysize, JSON_TEXT("reserves is not meant to expand a expand a preexisting array"));
preexisting array")); JSON_ASSERT(mysize == 0, JSON_TEXT("reserves is not meant to expa
nd a preexisting array"));
array = json_malloc<JSONNode*>(mycapacity = amount); array = json_malloc<JSONNode*>(mycapacity = amount);
} }
inline void reserve2(json_index_t amount){ static void reserve2(jsonChildren *& mine, json_index_t amount) json_no
if (array){ throw;
if (mycapacity < amount) inc(amount - mycapacity);
} else {
reserve(amount);
}
}
//shrinks the array to only as large as it needs to be to hold everythi ng within it //shrinks the array to only as large as it needs to be to hold everythi ng within it
inline void shrink(){ inline childrenVirtual void shrink() json_nothrow {
if (mysize == 0){ //size is zero, we should completely free the JSON_ASSERT(this != 0, JSON_TEXT("Children is null shrink"));
array if (json_unlikely(mysize == 0)){ //size is zero, we should compl
etely free the array
libjson_free<JSONNode*>(array); //free does checks for a null pointer, so don't bother checking libjson_free<JSONNode*>(array); //free does checks for a null pointer, so don't bother checking
array = 0; array = 0;
#ifdef JSON_LESS_MEMORY #ifdef JSON_LESS_MEMORY
} else { //need to shrink it, using realloc } else { //need to shrink it, using realloc
JSON_ASSERT(array, JSON_TEXT("shrinking a nu JSON_ASSERT(array != 0, JSON_TEXT("shrinking a null
ll array that is not size 0")); array that is not size 0"));
array = json_realloc<JSONNode*>(array, mysiz array = json_realloc<JSONNode*>(array, mysize);
e); #endif
#endif
} }
mycapacity = mysize; mycapacity = mysize;
} }
JSON_PRIVATE
//to make sure it's not copyable
jsonChildren(const jsonChildren &);
jsonChildren & operator = (const jsonChildren &);
void deleteAll(void); //implemented in JSONNode.cpp inline static void deleteChildren(jsonChildren * ptr) json_nothrow {
void doerase(JSONNode ** position, json_index_t number); #ifdef JSON_MEMORY_CALLBACKS
ptr -> ~jsonChildren();
libjson_free<jsonChildren>(ptr);
#else
delete ptr;
#endif
}
inline static jsonChildren * newChildren(void) {
#ifdef JSON_MEMORY_CALLBACKS
return new(json_malloc<jsonChildren>(1)) jsonChildren();
#else
return new jsonChildren();
#endif
}
JSONNode ** array; //the expandable array JSONNode ** array; //the expandable array
json_index_t mysize; //the number of valid items json_index_t mysize; //the number of valid items
json_index_t mycapacity; //the number of possible items json_index_t mycapacity; //the number of possible items
JSON_PROTECTED
//to make sure it's not copyable
jsonChildren(const jsonChildren &);
jsonChildren & operator = (const jsonChildren &);
void deleteAll(void) json_nothrow json_hot; //implemented in JSONNode.
cpp
void doerase(JSONNode ** position, json_index_t number) json_nothrow;
}; };
#ifdef JSON_LESS_MEMORY
class jsonChildren_Reserved : public jsonChildren {
public:
jsonChildren_Reserved(jsonChildren * orig, json_index_t siz) json
_nothrow : jsonChildren(orig -> array, orig -> mysize, orig -> mycapacity),
myreserved(siz) {
orig -> array = 0;
deleteChildren(orig);
addAllocCount();
}
jsonChildren_Reserved(const jsonChildren_Reserved & orig) json_no
throw : jsonChildren(orig.array, orig.mysize, orig.mycapacity), myreserved
(orig.myreserved){
addAllocCount();
}
inline virtual ~jsonChildren_Reserved() json_nothrow {
subAllocCount();
};
inline virtual void shrink() json_nothrow {
JSON_ASSERT(this != 0, JSON_TEXT("Children is null shrink
reserved"));
if (json_unlikely(mysize == 0)){ //size is zero, we shoul
d completely free the array
libjson_free<JSONNode*>(array); //free does checks
for a null pointer, so don't bother checking
array = 0;
} else if (mysize > myreserved){
JSON_ASSERT(array != 0, JSON_TEXT("shrinking a null
array that is not size 0"));
array = json_realloc<JSONNode*>(array, mysize);
}
}
#ifdef JSON_LESS_MEMORY
inline static jsonChildren * newChildren_Reserved(jsonChil
dren * orig, json_index_t siz) json_nothrow {
#ifdef JSON_MEMORY_CALLBACKS
return new(json_malloc<jsonChildren_Reserved
>(1)) jsonChildren_Reserved(orig, siz);
#else
return new jsonChildren_Reserved(orig, siz);
#endif
}
#endif
JSON_PRIVATE
jsonChildren_Reserved & operator = (const jsonChildren_Reserved &
);
json_index_t myreserved;
};
#endif
#ifdef JSON_LESS_MEMORY
#ifdef __GNUC__
#pragma pack(pop)
#elif _MSC_VER
#pragma pack(pop, jsonChildren)
#endif
#endif
#endif #endif
 End of changes. 38 change blocks. 
67 lines changed or deleted 189 lines changed or added


 JSONDebug.h   JSONDebug.h 
#ifndef JSON_DEBUG_H #ifndef JSON_DEBUG_H
#define JSON_DEBUG_H #define JSON_DEBUG_H
#include "JSONDefs.h" #include "JSONDefs.h"
#include "../JSONOptions.h"
#ifdef JSON_UNIT_TEST
#define JSON_PRIVATE
#else
#define JSON_PRIVATE private:
#endif
#ifdef JSON_DEBUG #ifdef JSON_DEBUG
#ifdef JSON_SAFE #ifdef JSON_SAFE
#define JSON_ASSERT_SAFE(condition, msg, code)\ #define JSON_ASSERT_SAFE(condition, msg, code)\
{\ {\
if (!(condition)){\ if (json_unlikely(!(condition))){\
JSON_FAIL(msg);\ JSON_FAIL(msg);\
code\ code\
}\ }\
} }
#define JSON_FAIL_SAFE(msg, code)\ #define JSON_FAIL_SAFE(msg, code)\
{\ {\
JSON_FAIL(msg);\ JSON_FAIL(msg);\
code\ code\
} }
#else #else
#define JSON_ASSERT_SAFE(condition, msg, code) JSON_ASSERT(condit ion, msg) #define JSON_ASSERT_SAFE(condition, msg, code) JSON_ASSERT(condit ion, msg)
#define JSON_FAIL_SAFE(msg, code) JSON_FAIL(msg) #define JSON_FAIL_SAFE(msg, code) JSON_FAIL(msg)
#endif #endif
#define JSON_FAIL JSONDebug::_JSON_FAIL #define JSON_FAIL(msg) JSONDebug::_JSON_FAIL(msg)
#define JSON_ASSERT JSONDebug::_JSON_ASSERT #define JSON_ASSERT(bo, msg) JSONDebug::_JSON_ASSERT(bo, msg)
class JSONDebug { class JSONDebug {
public: public:
#ifndef JSON_STDERROR #ifndef JSON_STDERROR
static void register_callback(json_error_callback_t callba ck); static void register_callback(json_error_callback_t callba ck) json_nothrow json_cold;
#endif #endif
static void _JSON_FAIL(const json_string & msg); static void _JSON_FAIL(const json_string & msg) json_nothrow json
static void _JSON_ASSERT(bool condition, const json_string & msg) _cold;
; static void _JSON_ASSERT(bool condition, const json_string & msg)
json_nothrow json_cold;
}; };
#else #else
#ifdef JSON_SAFE #ifdef JSON_SAFE
#define JSON_ASSERT_SAFE(condition, msg, code)\ #define JSON_ASSERT_SAFE(condition, msg, code)\
{\ {\
if (!(condition)){\ if (json_unlikely(!(condition))){\
code\ code\
}\ }\
} }
#define JSON_FAIL_SAFE(msg, code)\ #define JSON_FAIL_SAFE(msg, code)\
{\ {\
code\ code\
} }
#else #else
#define JSON_ASSERT_SAFE(condition, msg, code) #define JSON_ASSERT_SAFE(condition, msg, code)
#define JSON_FAIL_SAFE(msg, code) #define JSON_FAIL_SAFE(msg, code)
 End of changes. 6 change blocks. 
15 lines changed or deleted 9 lines changed or added


 JSONDefs.h   JSONDefs.h 
#ifndef JSONDEFS_H #ifndef JSONDEFS_H
#define JSONDEFS_H #define JSONDEFS_H
/* /*
Defines all of the types of functions and various other definitions Defines all of the types of functions and various other definitions
that are used in C applications, this is very useful if dynamically loa ding that are used in C applications, this is very useful if dynamically loa ding
the library instead of linking. the library instead of linking.
*/ */
#include "../JSONOptions.h" #include "../JSONOptions.h"
#include "JSONDefs/Unknown_C.h"
#include "JSONDefs/GNU_C.h"
#include "JSONDefs/Visual_C.h"
#include "JSONDefs/Strings_Defs.h"
#define __LIBJSON_MAJOR__ 7
#define __LIBJSON_MINOR__ 0
#define __LIBJSON_PATCH__ 0
#define __LIBJSON_VERSION__ (__LIBJSON_MAJOR__ * 10000 + __LIBJSON_MINOR__
* 100 + __LIBJSON_PATCH__)
#define JSON_NULL '\0' #define JSON_NULL '\0'
#define JSON_STRING '\1' #define JSON_STRING '\1'
#define JSON_NUMBER '\2' #define JSON_NUMBER '\2'
#define JSON_BOOL '\3' #define JSON_BOOL '\3'
#define JSON_ARRAY '\4' #define JSON_ARRAY '\4'
#define JSON_NODE '\5' #define JSON_NODE '\5'
#ifdef __cplusplus #ifdef __cplusplus
#ifdef JSON_STRING_HEADER #ifdef JSON_STRING_HEADER
#include JSON_STRING_HEADER #include JSON_STRING_HEADER
#else
#include <string>
#endif #endif
#endif #endif
#ifdef JSON_UNICODE #ifdef JSON_NO_EXCEPTIONS
#ifdef JSON_ISO_STRICT #define json_throw(x)
#error, You can not use unicode under ISO Strict C++ #define json_try
#define json_catch(exception, code)
#else
#define json_throw(x) throw(x)
#define json_try try
#define json_catch(exception, code) catch(exception){ code }
#endif
#ifdef JSON_STRICT
#ifndef JSON_UNICODE
#error, JSON_UNICODE is required for JSON_STRICT
#endif #endif
#define json_char wchar_t #ifdef JSON_COMMENTS
#define json_uchar wchar_t #error, JSON_COMMENTS is required to be off for JSON_STRICT
#ifdef __cplusplus #endif
#include <cwchar> //need wide characters #endif
#ifndef JSON_STRING_HEADER
typedef std::wstring json_string; #ifdef JSON_ISO_STRICT
#endif #ifdef JSON_UNICODE
#else #error, You can not use unicode under ANSI Strict C++
#include <wchar.h> //need wide characters
#endif #endif
#define JSON_TEXT(s) L ## s
#define json_strlen wcslen
#define json_strcmp wcscmp
#else #else
#define json_char char #ifdef __GNUC__
#define json_uchar unsigned char #ifdef JSON_ISO_STRICT
#ifdef __cplusplus #warning, Using -ansi GCC option, but JSON_ISO_STRICT not
#ifndef JSON_STRING_HEADER on, turning it on for you
typedef std::string json_string; #define JSON_ISO_STRICT
#endif #endif
#endif #endif
#define JSON_TEXT(s) s
#define json_strlen strlen
#define json_strcmp strcmp
#endif #endif
#ifdef JSON_LESS_MEMORY #ifdef JSON_LESS_MEMORY
#define BITS(x) :x //tells the compiler how many bits to use for a fie ld /* PACKED and BITS stored in compiler specific headers */
#define START_MEM_SCOPE { #define START_MEM_SCOPE {
#define END_MEM_SCOPE } #define END_MEM_SCOPE }
typedef float json_number; typedef float json_number;
#define JSON_FLOAT_THRESHHOLD 0.00001f
#else #else
#define PACKED(x)
#define BITS(x) #define BITS(x)
#define START_MEM_SCOPE #define START_MEM_SCOPE
#define END_MEM_SCOPE #define END_MEM_SCOPE
typedef double json_number; typedef double json_number;
#define JSON_FLOAT_THRESHHOLD 0.00001
#endif #endif
#if defined JSON_DEBUG || defined JSON_SAFE #if defined JSON_DEBUG || defined JSON_SAFE
#ifdef JSON_LIBRARY #ifdef JSON_LIBRARY
typedef void (*json_error_callback_t)(const json_char *); typedef void (*json_error_callback_t)(const json_char *);
#else #else
typedef void (*json_error_callback_t)(const json_string &); typedef void (*json_error_callback_t)(const json_string &);
#endif #endif
#endif #endif
skipping to change at line 95 skipping to change at line 107
#else #else
typedef int json_bool_t; typedef int json_bool_t;
#endif #endif
typedef void (*json_mutex_callback_t)(void *); typedef void (*json_mutex_callback_t)(void *);
typedef void (*json_free_t)(void *); typedef void (*json_free_t)(void *);
#ifndef JSON_LIBRARY #ifndef JSON_LIBRARY
typedef void * (*json_malloc_t)(size_t); typedef void * (*json_malloc_t)(size_t);
typedef void * (*json_realloc_t)(void *, size_t); typedef void * (*json_realloc_t)(void *, size_t);
#else #else
#define JSONNODE void //so that JSONNODE* is void* #define JSONNODE void /* so that JSONNODE* is void* */
typedef JSONNODE** JSONNODE_ITERATOR; typedef JSONNODE** JSONNODE_ITERATOR;
#ifdef JSON_STREAM
#define JSONSTREAM void
typedef void (*json_stream_callback_t)(JSONNODE *);
#endif
typedef void * (*json_malloc_t)(unsigned long); typedef void * (*json_malloc_t)(unsigned long);
typedef void * (*json_realloc_t)(void *, unsigned long); typedef void * (*json_realloc_t)(void *, unsigned long);
#endif #endif
#endif //JSONDEFS_H #ifdef JSON_DEBUG
#ifdef NDEBUG
#ifdef __GNUC__
#warning, Have JSON_DEBUG on in a release build
#else
#error, Have JSON_DEBUG on in a release build
#endif
#endif
#else
#ifndef NDEBUG
#ifdef __GNUC__
#warning, Release build of libjson, but NDEBUG is not on
#else
#error, Release build of libjson, but NDEBUG is not on
#endif
#endif
#endif
#ifdef JSON_UNIT_TEST
#define JSON_PRIVATE
#define JSON_PROTECTED
#else
#define JSON_PRIVATE private:
#define JSON_PROTECTED protected:
#endif
#ifdef JSON_STREAM
#ifndef JSON_READ_PRIORITY
#error, JSON_STREAM also requires JSON_READ_PRIORITY
#endif
#endif
#ifdef JSON_VALIDATE
#ifndef JSON_READ_PRIORITY
#error, JSON_VALIDATE also requires JSON_READ_PRIORITY
#endif
#endif
#endif
 End of changes. 14 change blocks. 
27 lines changed or deleted 45 lines changed or added


 JSONMemory.h   JSONMemory.h 
skipping to change at line 18 skipping to change at line 18
#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 #ifdef JSON_MEMORY_CALLBACKS
class JSONMemory { class JSONMemory {
public: public:
static void * json_malloc(size_t siz); #ifdef __GNUC__
static void * json_realloc(void * ptr, size_t siz); static void * json_malloc(size_t siz) json_malloc_attr;
static void json_free(void * ptr); static void * json_realloc(void * ptr, size_t siz) json_ma
static void registerMemoryCallbacks(json_malloc_t mal, json_reall lloc_attr;
oc_t real, json_free_t fre); #else
static void * json_malloc(size_t siz) json_nothrow;
static void * json_realloc(void * ptr, size_t siz) json_no
throw;
#endif
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;
}; };
template <typename T> static inline T * json_malloc(size_t count){ 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 {
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 template <typename T> static inline T * json_realloc(T * ptr, size_t co
unt){ unt) json_malloc_attr;
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){ 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){ 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 {
#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 = malloc(count * sizeof(T));
JSON_ASSERT(result, 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)); memset(result, '\0', count * sizeof(T));
#endif #endif
return (T *)result; return (T *)result;
#else #else
return (T *)malloc(count * sizeof(T)); return (T *)malloc(count * sizeof(T));
#endif #endif
} }
template <typename T> template <typename T> static inline void libjson_free(T * JSON_FREE_PAS
static inline void libjson_free(T * JSON_FREE_PASSTYPE ptr){ STYPE ptr) json_nothrow {
free(ptr); free(ptr);
#if defined(JSON_DEBUG) || defined(JSON_SAFE) //in debug or safe mode, set the pointer to 0 so that it can't be used again #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> template <typename T> static inline T * json_realloc(T * ptr, size_t co
static inline T * json_realloc(T * ptr, size_t count){ unt) json_malloc_attr;
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 = realloc(ptr, count * sizeof(T));
JSON_ASSERT(result, 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)); memset(result, '\0', count * sizeof(T));
#endif #endif
return (T *)result; return (T *)result;
#else #else
return (T *)realloc(ptr, count * sizeof(T)); return (T *)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) : mymap(){} auto_expand(void) json_nothrow : mymap(){}
~auto_expand(void){ purge(); } ~auto_expand(void) json_nothrow { purge(); }
void purge(void); void purge(void) json_nothrow;
inline void clear(void){ purge(); mymap.clear(); } inline void clear(void) json_nothrow { purge(); mymap.clear(); }
inline void * insert(void * ptr){ mymap[ptr] = ptr; return ptr; } inline void * insert(void * ptr) json_nothrow { mymap[ptr] = ptr;
inline void remove(void * ptr){ return ptr; }
inline void remove(void * ptr) json_nothrow {
std::map<void *, void *>::iterator i = mymap.find(ptr); std::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; std::map<void *, void *> mymap;
}; };
struct auto_expand_node { struct auto_expand_node {
auto_expand_node(void) : mymap(){} auto_expand_node(void) json_nothrow : mymap(){}
~auto_expand_node(void){ purge(); } ~auto_expand_node(void) json_nothrow { purge(); }
void purge(void); void purge(void) json_nothrow ;
inline void clear(void){ purge(); mymap.clear(); } inline void clear(void) json_nothrow { purge(); mymap.clear(); }
inline JSONNode * insert(JSONNode * ptr){ mymap[ptr] = ptr; retur inline JSONNode * insert(JSONNode * ptr) json_nothrow { mymap[ptr
n ptr; } ] = ptr; return ptr; }
inline void remove(void * ptr){ inline void remove(void * ptr) json_nothrow {
std::map<void *, JSONNode *>::iterator i = mymap.find(ptr) ; std::map<void *, JSONNode *>::iterator i = mymap.find(ptr) ;
if(i != mymap.end()) mymap.erase(i); if(json_likely(i != mymap.end())) mymap.erase(i);
} }
std::map<void *, JSONNode *> mymap; std::map<void *, JSONNode *> mymap;
}; };
#ifdef JSON_STREAM
class JSONStream;
struct auto_expand_stream {
auto_expand_stream(void) json_nothrow : mymap(){}
~auto_expand_stream(void) json_nothrow { purge(); }
void purge(void) json_nothrow ;
inline void clear(void) json_nothrow { purge(); mymap.clea
r(); }
inline JSONStream * insert(JSONStream * ptr) json_nothrow
{ mymap[ptr] = ptr; return ptr; }
inline void remove(void * ptr) json_nothrow {
std::map<void *, JSONStream *>::iterator i = mymap.
find(ptr);
if(json_likely(i != mymap.end())) mymap.erase(i);
}
std::map<void *, JSONStream *> mymap;
};
#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) : ptr(0){} json_auto(void) json_nothrow : ptr(0){}
json_auto(size_t count) : ptr(json_malloc<T>(count)){} json_auto(size_t count) json_nothrow : ptr(json_malloc<T>(count))
~json_auto(void){ {}
~json_auto(void) json_nothrow {
libjson_free<T>(ptr); libjson_free<T>(ptr);
} }
inline void set(T * p){ 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 &);
}; };
//Clears a string, if required, frees the memory //Clears a string, if required, frees the memory
static inline void clearString(json_string & str){ static inline void clearString(json_string & str) json_nothrow {
#ifdef JSON_LESS_MEMORY #ifdef JSON_LESS_MEMORY
json_string().swap(str); json_string().swap(str);
#else #else
str.clear(); str.clear();
#endif #endif
} }
//Shrinks a string //Shrinks a string
#ifdef JSON_LESS_MEMORY #ifdef JSON_LESS_MEMORY
static inline json_string shrinkString(const json_string & str){ static inline json_string shrinkString(const json_string & str) json_no throw {
if (str.capacity() == str.length()) return str; if (str.capacity() == str.length()) return str;
return str.c_str(); return json_string(str.c_str());
} }
#else #else
#define shrinkString(str) str #define shrinkString(str) str
#endif #endif
#endif #endif
 End of changes. 18 change blocks. 
38 lines changed or deleted 76 lines changed or added


 JSONNode.h   JSONNode.h 
#ifndef JSONNODE_H #ifndef JSONNODE_H
#define JSONNODE_H #define JSONNODE_H
#include "JSONDefs.h" //for string type #include "JSONDebug.h" //for string type
#include "internalJSONNode.h" //internal structure for json value #include "internalJSONNode.h" //internal structure for json value
#include <stdexcept> #include <stdexcept>
#include <cstdarg> //for the ... parameter #include <cstdarg> //for the ... parameter
#ifdef JSON_BINARY #ifdef JSON_BINARY
#include "JSON_Base64.h" #include "JSON_Base64.h"
#endif #endif
#ifdef JSON_LESS_MEMORY
#ifdef __GNUC__
#pragma pack(push, 1)
#elif _MSC_VER
#pragma pack(push, JSONNode_pack, 1)
#endif
#endif
#ifndef JSON_REF_COUNT #ifndef JSON_REF_COUNT
#define makeUniqueInternal() (void)0 #define makeUniqueInternal() (void)0
#endif #endif
#define JSON_CHECK_INTERNAL() JSON_ASSERT(internal, JSON_TEXT("no internal" )) #define JSON_CHECK_INTERNAL() JSON_ASSERT(internal != 0, JSON_TEXT("no inte rnal"))
#ifdef JSON_MUTEX_CALLBACKS #ifdef JSON_MUTEX_CALLBACKS
#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);\ foo(long)json_nothrow;\
foo(json_number);\ foo(json_number) json_nothrow;\
foo(bool);\ foo(bool) json_nothrow;\
foo(const json_string &); foo(const json_string &) json_nothrow;
#define DECLARE_FOR_ALL_TYPES_CONST(foo)\ #define DECLARE_FOR_ALL_TYPES_CONST(foo)\
foo(long) const;\ foo(long) const json_nothrow;\
foo(json_number) const;\ foo(json_number) const json_nothrow;\
foo(bool) const;\ foo(bool) const json_nothrow;\
foo(const json_string &) const;\ foo(const json_string &) const json_nothrow;\
foo(const JSONNode &) const; foo(const JSONNode &) const json_nothrow;
#define IMPLEMENT_FOR_ALL_NUMBERS(foo)\ #define IMPLEMENT_FOR_ALL_NUMBERS(foo)\
foo(long)\ foo(long)\
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
#define DECLARE_FOR_ALL_TYPES(foo)\ #define DECLARE_FOR_ALL_TYPES(foo)\
foo(char); foo(unsigned char);\ foo(char) json_nothrow; foo(unsigned char) json_nothrow;\
foo(short); foo(unsigned short);\ foo(short) json_nothrow; foo(unsigned short) json_nothrow;\
foo(int); foo(unsigned int);\ foo(int) json_nothrow; foo(unsigned int) json_nothrow;\
foo(long); foo(unsigned long);\ foo(long) json_nothrow; foo(unsigned long) json_nothrow;\
foo(float); foo(double);\ foo(float) json_nothrow; foo(double) json_nothrow;\
foo(bool);\ foo(bool) json_nothrow;\
foo(const json_string &);\ foo(const json_string &) json_nothrow;\
foo(const json_char *); foo(const json_char *) json_nothrow;
#define DECLARE_FOR_ALL_TYPES_CONST(foo)\ #define DECLARE_FOR_ALL_TYPES_CONST(foo)\
foo(char) const; foo(unsigned char) const;\ foo(char) const json_nothrow; foo(unsigned char) const jso
foo(short) const; foo(unsigned short) const;\ n_nothrow;\
foo(int) const; foo(unsigned int) const;\ foo(short) const json_nothrow; foo(unsigned short) const js
foo(long) const; foo(unsigned long) const;\ on_nothrow;\
foo(float) const; foo(double) const;\ foo(int) const json_nothrow; foo(unsigned int) const json_nothrow
foo(bool) const;\ ;\
foo(const json_string &) const;\ foo(long) const json_nothrow; foo(unsigned long) const jso
foo(const JSONNode &) const;\ n_nothrow;\
foo(const json_char *) const; foo(float) const json_nothrow; foo(double) const json_nothr
ow;\
foo(bool) const json_nothrow;\
foo(const json_string &) const json_nothrow;\
foo(const JSONNode &) 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)
#endif #endif
skipping to change at line 93 skipping to change at line 101
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); 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) JSONNode(const json_string & name_t, type va lue_t)
DECLARE_FOR_ALL_TYPES(DECLARE_CTOR) DECLARE_FOR_ALL_TYPES(DECLARE_CTOR)
JSONNode(const JSONNode & orig); JSONNode(const JSONNode & orig) json_nothrow json_hot;
~JSONNode(void); ~JSONNode(void) json_nothrow json_hot;
json_index_t size(void) const; json_index_t size(void) const json_nothrow json_read_priority;
bool empty(void) const; bool empty(void) const json_nothrow json_read_priority;
void clear(void); void clear(void) json_nothrow json_cold;
unsigned char type(void) const; unsigned char type(void) const json_nothrow json_read_priority;
json_string name(void) const; json_string name(void) const json_nothrow json_read_priority;
void set_name(const json_string & newname); 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); void set_comment(const json_string & comment) json_nothrow;
json_string get_comment(void) const; json_string get_comment(void) const json_nothrow;
#endif
#ifndef JSON_PREPARSE
void preparse(void);
#endif #endif
#ifdef JSON_VALIDATE #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
#ifndef JSON_SAFE void preparse(void) json_nothrow json_read_priority;
#error JSON_VALIDATE also requires JSON_SAFE
#endif
bool validate(void);
#endif #endif
json_string as_string(void) const; json_string as_string(void) const json_nothrow json_read_priority;
long as_int(void) const; long as_int(void) const json_nothrow json_read_priority;
json_number as_float(void) const; json_number as_float(void) const json_nothrow json_read_priority;
bool as_bool(void) const; bool as_bool(void) const json_nothrow json_read_priority;
JSONNode as_node(void) const; JSONNode as_node(void) const json_nothrow json_read_priority;
JSONNode as_array(void) const; JSONNode as_array(void) const json_nothrow json_read_priority;
#ifdef JSON_BINARY #ifdef JSON_BINARY
std::string as_binary(void) const; std::string as_binary(void) const json_nothrow json_cold;
void set_binary(const unsigned char * bin, size_t bytes); void set_binary(const unsigned char * bin, size_t bytes) json_not
hrow json_cold;
#endif #endif
JSONNode & at(json_index_t pos); JSONNode & at(json_index_t pos) json_throws(std::out_of_range);
const JSONNode & at(json_index_t pos) const; const JSONNode & at(json_index_t pos) const json_throws(std::out_of_ran
JSONNode & operator[](json_index_t pos); ge);
const JSONNode & operator[](json_index_t pos) const; JSONNode & operator[](json_index_t pos) json_nothrow;
const JSONNode & operator[](json_index_t pos) const json_nothrow;
JSONNode & at(const json_string & name_t); JSONNode & at(const json_string & name_t) json_throws(std::out_of_range
const JSONNode & at(const json_string & name_t) const; );
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); JSONNode & at_nocase(const json_string & name_t) json_throws(std:
const JSONNode & at_nocase(const json_string & name_t) const; :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); JSONNode & operator[](const json_string & name_t) json_nothrow;
const JSONNode & operator[](const json_string & name_t) const; const JSONNode & operator[](const json_string & name_t) const json_noth
row;
#ifdef JSON_LIBRARY #ifdef JSON_LIBRARY
void push_back(JSONNode * node); void push_back(JSONNode * node) json_nothrow;
#else #else
void push_back(const JSONNode & node); void push_back(const JSONNode & node) json_nothrow;
#endif #endif
void reserve(json_index_t siz); void reserve(json_index_t siz) json_nothrow;
JSONNode JSON_PTR_LIB pop_back(json_index_t pos); JSONNode JSON_PTR_LIB pop_back(json_index_t pos) json_throws(std::out_o
JSONNode JSON_PTR_LIB pop_back(const json_string & name_t); f_range);
JSONNode JSON_PTR_LIB pop_back(const json_string & name_t) json_throws(
std::out_of_range);
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
JSONNode JSON_PTR_LIB pop_back_nocase(const json_string & name_t) ; JSONNode JSON_PTR_LIB pop_back_nocase(const json_string & name_t) json_throws(std::out_of_range);
#endif #endif
DECLARE_FOR_ALL_TYPES(JSONNode & operator =) DECLARE_FOR_ALL_TYPES(JSONNode & operator =)
JSONNode & operator = (const JSONNode &); 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); void nullify(void) json_nothrow;
void swap(JSONNode & other); void swap(JSONNode & other) json_nothrow;
void merge(JSONNode & other); void merge(JSONNode & other) json_nothrow json_cold;
void merge(unsigned int num, ...); void merge(unsigned int num, ...) json_nothrow json_cold;
JSONNode duplicate(void) const; JSONNode duplicate(void) const json_nothrow;
void cast(char newtype); 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 { struct iterator {
inline iterator& operator ++(void){ ++it; return *t inline iterator& operator ++(void) json_nothrow { +
his; } +it; return *this; }
inline iterator& operator --(void){ --it; return *t inline iterator& operator --(void) json_nothrow { -
his; } -it; return *this; }
inline iterator& operator +=(long i){ it += i; retu inline iterator& operator +=(long i) json_nothrow {
rn *this; } it += i; return *this; }
inline iterator& operator -=(long i){ it -= i; retu inline iterator& operator -=(long i) json_nothrow {
rn *this; } it -= i; return *this; }
inline iterator operator ++(int){ inline iterator operator ++(int) json_nothrow {
iterator result(*this); iterator result(*this);
++it; ++it;
return result; return result;
} }
inline iterator operator --(int){ inline iterator operator --(int) json_nothrow {
iterator result(*this); iterator result(*this);
--it; --it;
return result; return result;
} }
inline iterator operator +(long i) const { inline iterator operator +(long i) const json_nothr ow {
iterator result(*this); iterator result(*this);
result.it += i; result.it += i;
return result; return result;
} }
inline iterator operator -(long i) const { inline iterator operator -(long i) const json_nothr ow {
iterator result(*this); iterator result(*this);
result.it -= i; result.it -= i;
return result; return result;
} }
inline JSONNode& operator [](size_t pos) const { re inline JSONNode& operator [](size_t pos) const json
turn *it[pos]; }; _nothrow { return *it[pos]; };
inline JSONNode& operator *(void) const { return *( inline JSONNode& operator *(void) const json_nothro
*it); } w { return *(*it); }
inline bool operator == (const iterator & other) co inline bool operator == (const iterator & other) co
nst { return it == other.it; } nst json_nothrow { return it == other.it; }
inline bool operator != (const iterator & other) co inline bool operator != (const iterator & other) co
nst { return it != other.it; } nst json_nothrow { return it != other.it; }
inline bool operator > (const iterator & other) con inline bool operator > (const iterator & other) con
st { return it > other.it; } st json_nothrow { return it > other.it; }
inline bool operator >= (const iterator & other) co inline bool operator >= (const iterator & other) co
nst { return it >= other.it; } nst json_nothrow { return it >= other.it; }
inline bool operator < (const iterator & other) con inline bool operator < (const iterator & other) con
st { return it < other.it; } st json_nothrow { return it < other.it; }
inline bool operator <= (const iterator & other) co inline bool operator <= (const iterator & other) co
nst { return it <= other.it; } nst json_nothrow { return it <= other.it; }
inline iterator & operator = (const iterator & orig inline iterator & operator = (const iterator & orig
){ it = orig.it; return *this; } ) json_nothrow { it = orig.it; return *this; }
iterator (const iterator & orig) : it(orig.it) {} iterator (const iterator & orig) json_nothrow : it(
orig.it) {}
private: private:
JSONNode ** it; JSONNode ** it;
iterator(JSONNode ** starter) : it(starter) {} iterator(JSONNode ** starter) json_nothrow : it(sta rter) {}
friend class JSONNode; friend class JSONNode;
}; };
typedef iterator json_iterator; typedef iterator json_iterator;
struct const_iterator { struct const_iterator {
inline const_iterator& operator ++(void){ ++it; ret inline const_iterator& operator ++(void) json_nothr
urn *this; } ow { ++it; return *this; }
inline const_iterator& operator --(void){ --it; ret inline const_iterator& operator --(void) json_nothr
urn *this; } ow { --it; return *this; }
inline const_iterator& operator +=(long i){ it += i inline const_iterator& operator +=(long i) json_not
; return *this; } hrow { it += i; return *this; }
inline const_iterator& operator -=(long i){ it -= i inline const_iterator& operator -=(long i) json_not
; return *this; } hrow { it -= i; return *this; }
inline const_iterator operator ++(int){ inline const_iterator operator ++(int) json_nothrow
{
const_iterator result(*this); const_iterator result(*this);
++it; ++it;
return result; return result;
} }
inline const_iterator operator --(int){ inline const_iterator operator --(int) json_nothrow {
const_iterator result(*this); const_iterator result(*this);
--it; --it;
return result; return result;
} }
inline const_iterator operator +(long i) const { 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_iterator operator -(long i) const { 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 inline const JSONNode& operator [](size_t pos) cons
t { return const_cast<const JSONNode&>(*it[pos]); }; t json_nothrow { return const_cast<const JSONNode&>(*it[pos]); };
inline const JSONNode& operator *(void) const { ret inline const JSONNode& operator *(void) const json_
urn const_cast<const JSONNode&>(*(*it)); } nothrow { return const_cast<const JSONNode&>(*(*it)); }
inline bool operator == (const const_iterator & oth inline bool operator == (const const_iterator & oth
er) const { return it == other.it; } er) const json_nothrow { return it == other.it; }
inline bool operator != (const const_iterator & oth inline bool operator != (const const_iterator & oth
er) const { return it != other.it; } er) const json_nothrow { return it != other.it; }
inline bool operator > (const const_iterator & othe inline bool operator > (const const_iterator & othe
r) const { return it > other.it; } r) const json_nothrow { return it > other.it; }
inline bool operator >= (const const_iterator & oth inline bool operator >= (const const_iterator & oth
er) const { return it >= other.it; } er) const json_nothrow { return it >= other.it; }
inline bool operator < (const const_iterator & othe inline bool operator < (const const_iterator & othe
r) const { return it < other.it; } r) const json_nothrow { return it < other.it; }
inline bool operator <= (const const_iterator & oth inline bool operator <= (const const_iterator & oth
er) const { return it <= other.it; } er) const json_nothrow { return it <= other.it; }
inline const_iterator & operator =(const const_iter inline const_iterator & operator =(const const_iter
ator & orig){ it = orig.it; return *this; } ator & orig) json_nothrow { it = orig.it; return *this; }
const_iterator (const const_iterator & orig) : it(o const_iterator (const const_iterator & orig) json_n
rig.it) {} 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;
}; };
const_iterator begin(void) const; const_iterator begin(void) const json_nothrow;
const_iterator end(void) const; const_iterator end(void) const json_nothrow;
struct reverse_iterator { struct reverse_iterator {
inline reverse_iterator& operator ++(void){ --it; r inline reverse_iterator& operator ++(void) json_not
eturn *this; } hrow { --it; return *this; }
inline reverse_iterator& operator --(void){ ++it; r inline reverse_iterator& operator --(void) json_not
eturn *this; } hrow { ++it; return *this; }
inline reverse_iterator& operator +=(long i){ it -= inline reverse_iterator& operator +=(long i) json_n
i; return *this; } othrow { it -= i; return *this; }
inline reverse_iterator& operator -=(long i){ it += inline reverse_iterator& operator -=(long i) json_n
i; return *this; } othrow { it += i; return *this; }
inline reverse_iterator operator ++(int){ inline reverse_iterator operator ++(int) json_nothr
ow {
reverse_iterator result(*this); reverse_iterator result(*this);
--it; --it;
return result; return result;
} }
inline reverse_iterator operator --(int){ inline reverse_iterator operator --(int) json_nothr ow {
reverse_iterator result(*this); reverse_iterator result(*this);
++it; ++it;
return result; return result;
} }
inline reverse_iterator operator +(long i) const { inline reverse_iterator operator +(long i) const js on_nothrow {
reverse_iterator result(*this); reverse_iterator result(*this);
result.it -= i; result.it -= i;
return result; return result;
} }
inline reverse_iterator operator -(long i) const { inline reverse_iterator operator -(long i) const js on_nothrow {
reverse_iterator result(*this); reverse_iterator result(*this);
result.it += i; result.it += i;
return result; return result;
} }
inline JSONNode& operator [](size_t pos) const { re inline JSONNode& operator [](size_t pos) const json
turn *it[pos]; }; _nothrow { return *it[pos]; };
inline JSONNode& operator *(void) const { return *( inline JSONNode& operator *(void) const json_nothro
*it); } w { return *(*it); }
inline bool operator == (const reverse_iterator & o inline bool operator == (const reverse_iterator & o
ther) const { return it == other.it; } ther) const json_nothrow { return it == other.it; }
inline bool operator != (const reverse_iterator & o inline bool operator != (const reverse_iterator & o
ther) const { return it != other.it; } ther) const json_nothrow { return it != other.it; }
inline bool operator < (const reverse_iterator & ot inline bool operator < (const reverse_iterator & ot
her) const { return it > other.it; } her) const json_nothrow { return it > other.it; }
inline bool operator <= (const reverse_iterator & o inline bool operator <= (const reverse_iterator & o
ther) const { return it >= other.it; } ther) const json_nothrow { return it >= other.it; }
inline bool operator > (const reverse_iterator & ot inline bool operator > (const reverse_iterator & ot
her) const { return it < other.it; } her) const json_nothrow { return it < other.it; }
inline bool operator >= (const reverse_iterator & o inline bool operator >= (const reverse_iterator & o
ther) const { return it <= other.it; } ther) const json_nothrow { return it <= other.it; }
inline reverse_iterator & operator = (const reverse inline reverse_iterator & operator = (const reverse
_iterator & orig){ it = orig.it; return *this; } _iterator & orig) json_nothrow { it = orig.it; return *this; }
reverse_iterator (const reverse_iterator & orig) : reverse_iterator (const reverse_iterator & orig) js
it(orig.it) {} on_nothrow : it(orig.it) {}
private: private:
JSONNode ** it; JSONNode ** it;
reverse_iterator(JSONNode ** starter) : it(starter) {} reverse_iterator(JSONNode ** starter) json_nothrow : it(starter) {}
friend class JSONNode; friend class JSONNode;
}; };
reverse_iterator rbegin(void); reverse_iterator rbegin(void) json_nothrow;
reverse_iterator rend(void); reverse_iterator rend(void) json_nothrow;
struct reverse_const_iterator { struct reverse_const_iterator {
inline reverse_const_iterator& operator ++(void){ - inline reverse_const_iterator& operator ++(void) js
-it; return *this; } on_nothrow{ --it; return *this; }
inline reverse_const_iterator& operator --(void){ + inline reverse_const_iterator& operator --(void) js
+it; return *this; } on_nothrow{ ++it; return *this; }
inline reverse_const_iterator& operator +=(long i){ inline reverse_const_iterator& operator +=(long i)
it -= i; return *this; } json_nothrow{ it -= i; return *this; }
inline reverse_const_iterator& operator -=(long i){ inline reverse_const_iterator& operator -=(long i)
it += i; return *this; } json_nothrow{ it += i; return *this; }
inline reverse_const_iterator operator ++(int){ inline reverse_const_iterator operator ++(int) json
_nothrow{
reverse_const_iterator result(*this); reverse_const_iterator result(*this);
--it; --it;
return result; return result;
} }
inline reverse_const_iterator operator --(int){ inline reverse_const_iterator operator --(int) json _nothrow{
reverse_const_iterator result(*this); reverse_const_iterator result(*this);
++it; ++it;
return result; return result;
} }
inline reverse_const_iterator operator +(long i) co nst { 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 reverse_const_iterator operator -(long i) co nst { 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 inline const JSONNode& operator [](size_t pos) cons
t { return const_cast<const JSONNode&>(*it[pos]); }; t json_nothrow { return const_cast<const JSONNode&>(*it[pos]); };
inline const JSONNode& operator *(void) const { ret inline const JSONNode& operator *(void) const json_
urn const_cast<const JSONNode&>(*(*it)); } nothrow { return const_cast<const JSONNode&>(*(*it)); }
inline bool operator == (const reverse_const_iterat inline bool operator == (const reverse_const_iterat
or & other) const { return it == other.it; } or & other) const json_nothrow { return it == other.it; }
inline bool operator != (const reverse_const_iterat inline bool operator != (const reverse_const_iterat
or & other) const { return it != other.it; } or & other) const json_nothrow { return it != other.it; }
inline bool operator < (const reverse_const_iterato inline bool operator < (const reverse_const_iterato
r & other) const { return it > other.it; } r & other) const json_nothrow { return it > other.it; }
inline bool operator <= (const reverse_const_iterat inline bool operator <= (const reverse_const_iterat
or & other) const { return it >= other.it; } or & other) const json_nothrow { return it >= other.it; }
inline bool operator > (const reverse_const_iterato inline bool operator > (const reverse_const_iterato
r & other) const { return it < other.it; } r & other) const json_nothrow { return it < other.it; }
inline bool operator >= (const reverse_const_iterat inline bool operator >= (const reverse_const_iterat
or & other) const { return it <= other.it; } or & other) const json_nothrow { return it <= other.it; }
inline reverse_const_iterator & operator = (const r inline reverse_const_iterator & operator = (const r
everse_const_iterator & orig){ it = orig.it; return *this; } everse_const_iterator & orig) json_nothrow { it = orig.it; return *this; }
reverse_const_iterator (const reverse_const_iterato reverse_const_iterator (const reverse_const_iterato
r & orig) : it(orig.it) {} r & orig) json_nothrow : it(orig.it) {}
private: private:
JSONNode ** it; JSONNode ** it;
reverse_const_iterator(JSONNode ** starter) : it(st arter) {} reverse_const_iterator(JSONNode ** starter) json_no throw : it(starter) {}
friend class JSONNode; friend class JSONNode;
}; };
reverse_const_iterator rbegin(void) const; reverse_const_iterator rbegin(void) const json_nothrow;
reverse_const_iterator rend(void) const; reverse_const_iterator rend(void) const json_nothrow;
const_iterator find(const json_string & name_t) const; 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; const_iterator find_nocase(const json_string & name _t) const json_nothrow;
#endif #endif
reverse_iterator erase(reverse_iterator pos); reverse_iterator erase(reverse_iterator pos) json_nothrow;
reverse_iterator erase(reverse_iterator start, const rever reverse_iterator erase(reverse_iterator start, const rever
se_iterator & end); se_iterator & end) json_nothrow;
iterator insert(iterator pos, const JSONNode & x); iterator insert(iterator pos, const JSONNode & x) json_not
reverse_iterator insert(reverse_iterator pos, const JSONNo hrow;
de & x); reverse_iterator insert(reverse_iterator pos, const JSONNo
iterator insert(iterator pos, const reverse_iterator & _st de & x) json_nothrow;
art, const reverse_iterator & _end); iterator insert(iterator pos, const reverse_iterator & _st
reverse_iterator insert(reverse_iterator pos, const iterat art, const reverse_iterator & _end) json_nothrow;
or & _start, const iterator & _end); reverse_iterator insert(reverse_iterator pos, const iterat
reverse_iterator insert(reverse_iterator pos, const revers or & _start, const iterator & _end) json_nothrow;
e_iterator & _start, const reverse_iterator & _end); reverse_iterator insert(reverse_iterator pos, const revers
e_iterator & _start, const reverse_iterator & _end) json_nothrow;
json_iterator insert(json_iterator pos, const const_iterat json_iterator insert(json_iterator pos, const const_iterat
or & _start, const const_iterator & _end); or & _start, const const_iterator & _end) json_nothrow;
reverse_iterator insert(reverse_iterator pos, const const_ reverse_iterator insert(reverse_iterator pos, const const_
iterator & _start, const const_iterator & _end); iterator & _start, const const_iterator & _end) json_nothrow;
json_iterator insert(json_iterator pos, const reverse_cons json_iterator insert(json_iterator pos, const reverse_cons
t_iterator & _start, const reverse_const_iterator & _end); t_iterator & _start, const reverse_const_iterator & _end) json_nothrow;
reverse_iterator insert(reverse_iterator pos, const revers reverse_iterator insert(reverse_iterator pos, const revers
e_const_iterator & _start, const reverse_const_iterator & _end); e_const_iterator & _start, const reverse_const_iterator & _end) json_nothro
w;
#else #else
typedef JSONNode** json_iterator; typedef JSONNode** json_iterator;
#define json_iterator_ptr(iter) iter #define json_iterator_ptr(iter) iter
#define ptr_to_json_iterator(iter) iter #define ptr_to_json_iterator(iter) iter
json_iterator insert(json_iterator pos, JSONNode * x); json_iterator insert(json_iterator pos, JSONNode * x) json _nothrow;
#endif #endif
json_iterator begin(void); json_iterator begin(void) json_nothrow;
json_iterator end(void); json_iterator end(void) json_nothrow;
json_iterator find(const json_string & name_t); json_iterator find(const json_string & name_t) json_nothrow;
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
json_iterator find_nocase(const json_string & name_t); json_iterator find_nocase(const json_string & name_t) json _nothrow;
#endif #endif
json_iterator erase(json_iterator pos); json_iterator erase(json_iterator pos) json_nothrow;
json_iterator erase(json_iterator start, const json_iterator & en json_iterator erase(json_iterator start, const json_iterator & en
d); d) json_nothrow;
json_iterator insert(json_iterator pos, const json_iterator & _st json_iterator insert(json_iterator pos, const json_iterator & _st
art, const json_iterator & _end); art, const json_iterator & _end) json_nothrow;
#endif #endif
#ifdef JSON_MUTEX_CALLBACKS #ifdef JSON_MUTEX_CALLBACKS
static void register_mutex_callbacks(json_mutex_callback_t lock, json_mutex_callback_t unlock, void * manager_lock); static void register_mutex_callbacks(json_mutex_callback_t lock, json_mutex_callback_t unlock, void * manager_lock) json_nothrow json_cold;
#ifdef JSON_MUTEX_MANAGE #ifdef JSON_MUTEX_MANAGE
static void register_mutex_destructor(json_mutex_callback_ t destroy); static void register_mutex_destructor(json_mutex_callback_ t destroy) json_nothrow json_cold;
#endif #endif
static void set_global_mutex(void * mutex); static void set_global_mutex(void * mutex) json_nothrow json_cold
void set_mutex(void * mutex); ;
void lock(int thread); void set_mutex(void * mutex) json_nothrow json_cold;
void unlock(int thread); void lock(int thread) json_nothrow json_cold;
void unlock(int thread) json_nothrow json_cold;
struct auto_lock { struct auto_lock {
public: public:
auto_lock(JSONNode & node, int thread) : mynode(&no de), mythread(thread){ auto_lock(JSONNode & node, int thread) json_nothro w: mynode(&node), mythread(thread){
mynode -> lock(mythread); mynode -> lock(mythread);
} }
auto_lock(JSONNode * node, int thread) : mynode(nod e), mythread(thread){ auto_lock(JSONNode * node, int thread) json_nothro w: mynode(node), mythread(thread){
mynode -> lock(mythread); mynode -> lock(mythread);
} }
~auto_lock(void){ ~auto_lock(void) json_nothrow{
mynode -> unlock(mythread); mynode -> unlock(mythread);
} }
private: private:
auto_lock & operator = (const auto_lock &); auto_lock & operator = (const auto_lock &);
auto_lock(const auto_lock &); auto_lock(const auto_lock &);
JSONNode * mynode; JSONNode * mynode;
int mythread; int mythread;
}; };
static void * getThisLock(JSONNode * pthis); static void * getThisLock(JSONNode * pthis) json_nothrow json_col d;
#endif #endif
#ifdef JSON_UNIT_TEST #ifdef JSON_UNIT_TEST
static int getNodeAllocationCount(void); static int getNodeAllocationCount(void);
static int getNodeDeallocationCount(void); static int getNodeDeallocationCount(void);
static int getInternalAllocationCount(void); static int getInternalAllocationCount(void);
static int getInternalDeallocationCount(void); static int getInternalDeallocationCount(void);
static int getChildrenAllocationCount(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 decChildrenAllocCount(void);
#endif #endif
#ifdef JSON_WRITER #ifdef JSON_WRITE_PRIORITY
json_string write(void); json_string write(void) json_nothrow json_write_priority;
json_string write_formatted(void); json_string write_formatted(void) json_nothrow json_write_priorit
y;
#endif #endif
#ifdef JSON_DEBUG #ifdef JSON_DEBUG
#ifndef JSON_LIBRARY #ifndef JSON_LIBRARY
JSONNode dump(void) const; JSONNode dump(void) const json_nothrow;
#endif #endif
#endif #endif
static void deleteJSONNode(JSONNode * ptr); static void deleteJSONNode(JSONNode * ptr) json_nothrow json_hot;
static JSONNode * newJSONNode_Shallow(const JSONNode & orig); static JSONNode * newJSONNode_Shallow(const JSONNode & orig) json_hot;
JSON_PRIVATE JSON_PRIVATE
static JSONNode * newJSONNode(const JSONNode & orig JSON_MUTEX_COPY static JSONNode * newJSONNode(const JSONNode & orig JSON_MUTEX_COPY
_DECL2); _DECL2) json_hot;
static JSONNode * newJSONNode(internalJSONNode * internal_t); static JSONNode * newJSONNode(internalJSONNode * internal_t) json_hot;
//used by JSONWorker #ifdef JSON_READ_PRIORITY
JSONNode(const json_string & unparsed) : internal(internalJSONNode::new //used by JSONWorker
Internal(unparsed)){ //root, specialized because it can only be array or no JSONNode(const json_string & unparsed) json_nothrow : internal(in
de ternalJSONNode::newInternal(unparsed)){ //root, specialized because it can
incAllocCount(); only be array or node
} incAllocCount();
JSONNode(internalJSONNode * internal_t) : internal(internal_t){ //do no }
t increment anything, this is only used in one case and it's already taken #endif
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
incAllocCount(); incAllocCount();
} }
JSONNode(bool, JSONNode & orig); JSONNode(bool, JSONNode & orig) json_nothrow json_hot;
void decRef(void); //decrements internal's counter, deletes it if need ed void decRef(void) json_nothrow json_hot; //decrements internal's count er, deletes it if needed
#ifdef JSON_REF_COUNT #ifdef JSON_REF_COUNT
void makeUniqueInternal(void); //makes internal it's own void makeUniqueInternal(void) json_nothrow; //makes internal it's
void merge(JSONNode * other); own
void merge(JSONNode * other) json_nothrow json_cold;
#endif #endif
#ifdef JSON_DEBUG #ifdef JSON_DEBUG
#ifndef JSON_LIBRARY #ifndef JSON_LIBRARY
JSONNode dump(size_t & totalmemory); JSONNode dump(size_t & totalmemory) json_nothrow;
#endif #endif
#endif #endif
#ifdef JSON_ITERATORS #ifdef JSON_ITERATORS
#ifndef JSON_LIBRARY #ifndef JSON_LIBRARY
json_iterator insertFRR(json_iterator pos, JSONNode ** con json_iterator insertFRR(json_iterator pos, JSONNode ** con
st _start, JSONNode ** const _end); st _start, JSONNode ** const _end) json_nothrow;
reverse_iterator insertRRR(reverse_iterator pos, JSONNode reverse_iterator insertRRR(reverse_iterator pos, JSONNode
** const _start, JSONNode ** const _end); ** const _start, JSONNode ** const _end) json_nothrow;
reverse_iterator insertRFF(reverse_iterator pos, JSONNode reverse_iterator insertRFF(reverse_iterator pos, JSONNode
** const _start, JSONNode ** const _end); ** const _start, JSONNode ** const _end) json_nothrow;
#endif #endif
json_iterator insertFFF(json_iterator pos, JSONNode ** const _sta rt, JSONNode ** const _end); json_iterator insertFFF(json_iterator pos, JSONNode ** const _sta rt, JSONNode ** const _end) json_nothrow;
#endif #endif
inline void clear_name(void) json_nothrow {
JSON_CHECK_INTERNAL();
makeUniqueInternal();
internal -> clearname();
}
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.
*/ */
inline JSONNode::JSONNode(char mytype) : internal(internalJSONNode::newInte rnal(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();
} }
inline JSONNode::JSONNode(const JSONNode & orig): internal(orig.internal -> incRef()){ inline JSONNode::JSONNode(const JSONNode & orig) json_nothrow : internal(or ig.internal -> incRef()){
incAllocCount(); incAllocCount();
} }
//this allows a temp node to simply transfer its contents, even with ref co unting off //this allows a temp node to simply transfer its contents, even with ref co unting off
inline JSONNode::JSONNode(bool, JSONNode & orig): internal(orig.internal){ inline JSONNode::JSONNode(bool, JSONNode & orig) json_nothrow : internal(or ig.internal){
orig.internal = 0; orig.internal = 0;
incAllocCount(); incAllocCount();
} }
inline JSONNode::~JSONNode(void){ inline JSONNode::~JSONNode(void) json_nothrow{
if (internal) decRef(); if (internal != 0) decRef();
decAllocCount(); decAllocCount();
} }
inline json_index_t JSONNode::size(void) const { inline json_index_t JSONNode::size(void) const json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return internal -> size(); return internal -> size();
} }
inline bool JSONNode::empty(void) const { inline bool JSONNode::empty(void) const json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return internal -> empty(); return internal -> empty();
} }
inline void JSONNode::clear(void){ inline void JSONNode::clear(void) json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
if (!empty()){ if (!empty()){
makeUniqueInternal(); makeUniqueInternal();
internal -> Children.clear(); internal -> CHILDREN -> clear();
} }
} }
inline unsigned char JSONNode::type(void) const { inline unsigned char JSONNode::type(void) const json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return internal -> type(); return internal -> type();
} }
inline json_string JSONNode::name(void) const { inline json_string JSONNode::name(void) const json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return internal -> name(); return internal -> name();
} }
inline void JSONNode::set_name(const json_string & newname){ inline void JSONNode::set_name(const json_string & newname) json_nothrow{
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
makeUniqueInternal(); makeUniqueInternal();
internal -> setname(newname); internal -> setname(newname);
} }
#ifdef JSON_COMMENTS #ifdef JSON_COMMENTS
inline void JSONNode::set_comment(const json_string & newname){ inline void JSONNode::set_comment(const json_string & newname) json_not hrow{
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
makeUniqueInternal(); makeUniqueInternal();
internal -> setcomment(newname); internal -> setcomment(newname);
} }
inline json_string JSONNode::get_comment(void) const { 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 { inline json_string JSONNode::as_string(void) const json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return internal -> as_string(); return internal -> as_string();
} }
inline long JSONNode::as_int(void) const { inline long JSONNode::as_int(void) const json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return internal -> as_int(); return internal -> as_int();
} }
inline json_number JSONNode::as_float(void) const { inline json_number JSONNode::as_float(void) const json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return internal -> as_float(); return internal -> as_float();
} }
inline bool JSONNode::as_bool(void) const { inline bool JSONNode::as_bool(void) const json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return internal -> as_bool(); return internal -> as_bool();
} }
#ifdef JSON_BINARY #ifdef JSON_BINARY
inline void JSONNode::set_binary(const unsigned char * bin, size_t byte s){ 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 { 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 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){ 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 { 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)));
} }
#ifdef JSON_LIBRARY #ifdef JSON_LIBRARY
inline void JSONNode::push_back(JSONNode * child){ inline void JSONNode::push_back(JSONNode * child) json_nothrow{
#else #else
inline void JSONNode::push_back(const JSONNode & child){ inline void JSONNode::push_back(const JSONNode & child) json_nothrow{
#endif #endif
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
makeUniqueInternal(); makeUniqueInternal();
internal -> push_back(child); internal -> push_back(child);
} }
inline void JSONNode::reserve(json_index_t siz){ inline void JSONNode::reserve(json_index_t siz) json_nothrow{
makeUniqueInternal(); makeUniqueInternal();
internal -> reserve(siz); internal -> reserve(siz);
} }
inline JSONNode & JSONNode::operator = (const JSONNode & orig){ inline JSONNode & JSONNode::operator = (const JSONNode & orig) json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
#ifdef JSON_REF_COUNT #ifdef JSON_REF_COUNT
if (internal == orig.internal) return *this; //don't want it acc identally deleting itself if (internal == orig.internal) return *this; //don't want it acc identally deleting itself
#endif #endif
decRef(); //dereference my current one decRef(); //dereference my current one
internal = orig.internal -> incRef(); //increase reference of original internal = orig.internal -> incRef(); //increase reference of original
return *this; return *this;
} }
#ifndef JSON_LIBRARY #ifndef JSON_LIBRARY
inline JSONNode & JSONNode::operator = (const json_char * val){ inline JSONNode & JSONNode::operator = (const json_char * val) json_not hrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
*this = json_string(val); *this = json_string(val);
return *this; return *this;
} }
#endif #endif
#define NODE_SET_TYPED(type)\ #define NODE_SET_TYPED(type)\
inline JSONNode & JSONNode::operator = (type val){\ inline JSONNode & JSONNode::operator = (type val) json_nothrow {\
JSON_CHECK_INTERNAL();\ JSON_CHECK_INTERNAL();\
makeUniqueInternal();\ makeUniqueInternal();\
internal -> Set(val);\ internal -> Set(val);\
return *this;\ return *this;\
} }
IMPLEMENT_FOR_ALL_TYPES(NODE_SET_TYPED) IMPLEMENT_FOR_ALL_TYPES(NODE_SET_TYPED)
/* /*
This section is the equality operators This section is the equality operators
*/ */
#define NODE_CHECK_EQUALITY(type)\ #define NODE_CHECK_EQUALITY(type)\
inline bool JSONNode::operator == (type val) const {\ inline bool JSONNode::operator == (type val) const json_nothrow {\
JSON_CHECK_INTERNAL();\ JSON_CHECK_INTERNAL();\
return internal -> IsEqualToNum<type>(val);\ return internal -> IsEqualToNum<type>(val);\
} }
IMPLEMENT_FOR_ALL_NUMBERS(NODE_CHECK_EQUALITY) IMPLEMENT_FOR_ALL_NUMBERS(NODE_CHECK_EQUALITY)
inline bool JSONNode::operator == (const json_string & val) const { inline bool JSONNode::operator == (const json_string & val) const json_noth row {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return internal -> IsEqualTo(val); return internal -> IsEqualTo(val);
} }
#ifndef JSON_LIBRARY #ifndef JSON_LIBRARY
inline bool JSONNode::operator == (const json_char * val) const { inline bool JSONNode::operator == (const json_char * val) const json_no throw {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return *this == json_string(val); return *this == json_string(val);
} }
#endif #endif
inline bool JSONNode::operator == (bool val) const { inline bool JSONNode::operator == (bool val) const json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return internal -> IsEqualTo(val); return internal -> IsEqualTo(val);
} }
inline bool JSONNode::operator == (const JSONNode & val) const { inline bool JSONNode::operator == (const JSONNode & val) const json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
return internal -> IsEqualTo(val.internal); return internal -> IsEqualTo(val.internal);
} }
/* /*
This section is the inequality operators This section is the inequality operators
*/ */
#define NODE_CHECK_INEQUALITY(type)\ #define NODE_CHECK_INEQUALITY(type)\
inline bool JSONNode::operator != (type val) const {\ inline bool JSONNode::operator != (type val) const json_nothrow {\
JSON_CHECK_INTERNAL();\ JSON_CHECK_INTERNAL();\
return !(*this == val);\ return !(*this == val);\
} }
IMPLEMENT_FOR_ALL_TYPES(NODE_CHECK_INEQUALITY) IMPLEMENT_FOR_ALL_TYPES(NODE_CHECK_INEQUALITY)
NODE_CHECK_INEQUALITY(const JSONNode &) NODE_CHECK_INEQUALITY(const JSONNode &)
#ifndef JSON_LIBRARY #ifndef JSON_LIBRARY
NODE_CHECK_INEQUALITY(const json_char * ) NODE_CHECK_INEQUALITY(const json_char * )
#endif #endif
inline void JSONNode::nullify(void){ inline void JSONNode::nullify(void) json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
makeUniqueInternal(); makeUniqueInternal();
internal -> Nullify(); internal -> Nullify();
} }
inline void JSONNode::swap(JSONNode & other){ inline void JSONNode::swap(JSONNode & other) json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
internalJSONNode * temp = other.internal; internalJSONNode * temp = other.internal;
other.internal = internal; other.internal = internal;
internal = temp; internal = temp;
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
} }
inline void JSONNode::decRef(void){ //decrements internal's counter, delete s it if needed inline void JSONNode::decRef(void) json_nothrow { //decrements internal's c ounter, deletes it if needed
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
#ifdef JSON_REF_COUNT #ifdef JSON_REF_COUNT
internal -> decRef(); internal -> decRef();
if (internal -> hasNoReferences()){ if (internal -> hasNoReferences()){
internalJSONNode::deleteInternal(internal); internalJSONNode::deleteInternal(internal);
} }
#else #else
internalJSONNode::deleteInternal(internal); internalJSONNode::deleteInternal(internal);
#endif #endif
} }
#ifdef JSON_REF_COUNT #ifdef JSON_REF_COUNT
inline void JSONNode::makeUniqueInternal(){ //makes internal 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){ 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_TEX T("iterating a non-iteratable node"));
makeUniqueInternal(); makeUniqueInternal();
return json_iterator(internal -> begin()); return json_iterator(internal -> begin());
} }
inline JSONNode::json_iterator JSONNode::end(void){ 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_TEX T("iterating a non-iteratable node"));
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 { 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_TEXT("iterating a non-iteratable node"));
return JSONNode::const_iterator(internal -> begin()); return JSONNode::const_iterator(internal -> begin());
} }
inline JSONNode::const_iterator JSONNode::end(void) const { 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_TEXT("iterating a non-iteratable node"));
return JSONNode::const_iterator(internal -> end()); return JSONNode::const_iterator(internal -> end());
} }
inline JSONNode::reverse_iterator JSONNode::rbegin(void){ 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_TEXT("iterating a non-iteratable node"));
makeUniqueInternal(); makeUniqueInternal();
return JSONNode::reverse_iterator(internal -> end() - 1); return JSONNode::reverse_iterator(internal -> end() - 1);
} }
inline JSONNode::reverse_iterator JSONNode::rend(void){ 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_TEXT("iterating a non-iteratable node"));
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 { 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_TEXT("iterating a non-iteratable node"));
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 { 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_TEXT("iterating a non-iteratable node"));
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){ 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){ 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);
} }
inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat or pos, const iterator & _start, const iterator & _end){ inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat or pos, const iterator & _start, const iterator & _end) json_nothrow {
return insertRFF(pos, _start.it, _end.it); return insertRFF(pos, _start.it, _end.it);
} }
inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat or pos, const reverse_const_iterator & _start, const reverse_const_iterator & _end){ inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat or pos, const reverse_const_iterator & _start, const reverse_const_iterator & _end) json_nothrow {
return insertRRR(pos, _start.it, _end.it); return insertRRR(pos, _start.it, _end.it);
} }
inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat or pos, const reverse_iterator & _start, const reverse_iterator & _end){ inline JSONNode::reverse_iterator JSONNode::insert(reverse_iterat or pos, const reverse_iterator & _start, const reverse_iterator & _end) jso n_nothrow {
return insertRRR(pos, _start.it, _end.it); return insertRRR(pos, _start.it, _end.it);
} }
inline JSONNode::iterator JSONNode::insert(json_iterator pos, con st reverse_const_iterator & _start, const reverse_const_iterator & _end){ inline JSONNode::iterator JSONNode::insert(json_iterator pos, con st reverse_const_iterator & _start, const reverse_const_iterator & _end) js on_nothrow {
return insertFRR(pos, _start.it, _end.it); return insertFRR(pos, _start.it, _end.it);
} }
inline JSONNode::iterator JSONNode::insert(iterator pos, const re verse_iterator & _start, const reverse_iterator & _end){ inline JSONNode::iterator JSONNode::insert(iterator pos, const re verse_iterator & _start, const reverse_iterator & _end) json_nothrow {
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){ 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_WRITER #ifdef JSON_WRITE_PRIORITY
inline json_string JSONNode::write(void){ inline json_string JSONNode::write(void) json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSO N_TEXT("Writing a non-writable node"), return EMPTY_JSON_STRING;); JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSO N_TEXT("Writing a non-writable node"), return EMPTY_JSON_STRING;);
return internal -> Write(0xFFFFFFFF, true); return internal -> Write(0xFFFFFFFF, true);
} }
inline json_string JSONNode::write_formatted(void){ inline json_string JSONNode::write_formatted(void) json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSO N_TEXT("Writing a non-writable node"), return EMPTY_JSON_STRING;); JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSO N_TEXT("Writing a non-writable node"), return EMPTY_JSON_STRING;);
return internal -> Write(0, true); return internal -> Write(0, true);
} }
#endif #endif
#ifndef JSON_PREPARSE #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
inline void JSONNode::preparse(void){ inline void JSONNode::preparse(void) json_nothrow {
JSON_CHECK_INTERNAL(); JSON_CHECK_INTERNAL();
internal -> preparse(); internal -> preparse();
} }
#endif #endif
#ifdef JSON_VALIDATE
inline bool JSONNode::validate(void){
JSON_CHECK_INTERNAL();
if (type() == JSON_NULL) return false;
JSON_ASSERT_SAFE(type() == JSON_NODE || type() == JSON_ARRAY, JSO
N_TEXT("Validating non root node"), return false;);
#ifndef JSON_PREPARSE
internal -> Fetch(); //will nullify it if it's bad
#endif
if (type() == JSON_NULL) return false;
return internal -> validate();
}
#endif
#ifdef JSON_DEBUG #ifdef JSON_DEBUG
#ifndef JSON_LIBRARY #ifndef JSON_LIBRARY
inline JSONNode JSONNode::dump(void) const { inline JSONNode JSONNode::dump(void) const json_nothrow {
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)));
size_t total = 0; size_t total = 0;
JSONNode node = internal -> Dump(total); JSONNode node(internal -> Dump(total));
dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("total bytes used"), total))); dumpage.push_back(JSON_NEW(JSONNode(JSON_TEXT("total bytes used"), total)));
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(node)); dumpage.push_back(JSON_NEW(node));
return dumpage; return dumpage;
} }
inline JSONNode JSONNode::dump(size_t & totalmemory){ inline JSONNode JSONNode::dump(size_t & totalmemory) json_nothrow {
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){ inline void JSONNode::deleteJSONNode(JSONNode * ptr) json_nothrow {
#ifdef JSON_MEMORY_CALLBACKS #ifdef JSON_MEMORY_CALLBACKS
ptr -> ~JSONNode(); ptr -> ~JSONNode();
libjson_free<JSONNode>(ptr); libjson_free<JSONNode>(ptr);
#else #else
delete ptr; delete ptr;
#endif #endif
} }
inline JSONNode * _newJSONNode(const JSONNode & orig){ inline JSONNode * _newJSONNode(const JSONNode & orig) {
#ifdef JSON_MEMORY_CALLBACKS #ifdef JSON_MEMORY_CALLBACKS
return new(json_malloc<JSONNode>(1)) JSONNode(orig); return new(json_malloc<JSONNode>(1)) JSONNode(orig);
#else #else
return new JSONNode(orig); return new JSONNode(orig);
#endif #endif
} }
inline JSONNode * JSONNode::newJSONNode(const JSONNode & orig JSON_MUTEX _COPY_DECL){ inline JSONNode * JSONNode::newJSONNode(const JSONNode & orig JSON_MUTEX _COPY_DECL) {
#ifdef JSON_MUTEX_CALLBACKS #ifdef JSON_MUTEX_CALLBACKS
if (parentMutex){ if (parentMutex != 0){
JSONNode * temp = _newJSONNode(orig); JSONNode * temp = _newJSONNode(orig);
temp -> set_mutex(parentMutex); temp -> set_mutex(parentMutex);
return temp; return temp;
} }
#endif #endif
return _newJSONNode(orig); return _newJSONNode(orig);
} }
inline JSONNode * JSONNode::newJSONNode(internalJSONNode * internal_t){ inline JSONNode * JSONNode::newJSONNode(internalJSONNode * internal_t) {
#ifdef JSON_MEMORY_CALLBACKS #ifdef JSON_MEMORY_CALLBACKS
return new(json_malloc<JSONNode>(1)) JSONNode(internal_t); return new(json_malloc<JSONNode>(1)) JSONNode(internal_t);
#else #else
return new JSONNode(internal_t); return new JSONNode(internal_t);
#endif #endif
} }
inline JSONNode * JSONNode::newJSONNode_Shallow(const JSONNode & orig){ inline JSONNode * JSONNode::newJSONNode_Shallow(const JSONNode & orig) {
#ifdef JSON_MEMORY_CALLBACKS #ifdef JSON_MEMORY_CALLBACKS
return new(json_malloc<JSONNode>(1)) JSONNode(true, const_cast<JS ONNode &>(orig)); return new(json_malloc<JSONNode>(1)) JSONNode(true, const_cast<JS ONNode &>(orig));
#else #else
return new JSONNode(true, const_cast<JSONNode &>(orig)); return new JSONNode(true, const_cast<JSONNode &>(orig));
#endif #endif
} }
#ifdef JSON_LESS_MEMORY
#ifdef __GNUC__
#pragma pack(pop)
#elif _MSC_VER
#pragma pack(pop, JSONNode_pack)
#endif
#endif
#endif #endif
 End of changes. 148 change blocks. 
368 lines changed or deleted 400 lines changed or added


 JSONOptions.h   JSONOptions.h 
skipping to change at line 16 skipping to change at line 16
* that you don't have to remember them, or look them up all the time * that you don't have to remember them, or look them up all the time
*/ */
/* /*
* JSON_LIBRARY must be declared if libjson is compiled as a static or dyn amic * JSON_LIBRARY must be declared if libjson is compiled as a static or dyn amic
* library. This exposes a C-style interface, but none of the inner worki ngs of libjson * library. This exposes a C-style interface, but none of the inner worki ngs of libjson
*/ */
#define JSON_LIBRARY #define JSON_LIBRARY
/* /*
* JSON_STRICT removes all of libjson's extensions. Meaning no comments,
no special numbers
*/
//#define JSON_STRICT
/*
* JSON_DEBUG is used to perform extra error checking. Because libjson us ually * JSON_DEBUG is used to perform extra error checking. Because libjson us ually
* does on the fly parsing, validation is impossible, so this option will allow * does on the fly parsing, validation is impossible, so this option will allow
* you to register an error callback so that you can record what is going wrong * you to register an error callback so that you can record what is going wrong
* before the library crashes. This option does not protect from these er rors, * before the library crashes. This option does not protect from these er rors,
* it simply tells you about them, which is nice for debugging, but not pr eferable * it simply tells you about them, which is nice for debugging, but not pr eferable
* for release candidates * for release candidates
*/ */
//#define JSON_DEBUG //#define JSON_DEBUG
/* /*
* JSON_ISO_STRICT turns off all code that uses non-standard C++. This re
moves all
* references to long long and long double as well as a few others
*/
//#define JSON_ISO_STRICT
/*
* JSON_SAFE performs similarly to JSON_DEBUG, except this option does pro tect * JSON_SAFE performs similarly to JSON_DEBUG, except this option does pro tect
* from the errors that it encounters. This option is recommended for tho se who * from the errors that it encounters. This option is recommended for tho se who
* feel it's possible for their program to encounter invalid json. * feel it's possible for their program to encounter invalid json.
*/ */
#define JSON_SAFE #define JSON_SAFE
/* /*
* JSON_STDERROR routes error messages to cerr instead of a callback, this * JSON_STDERROR routes error messages to cerr instead of a callback, this
* option hides the callback registering function. This will usually disp lay * option hides the callback registering function. This will usually disp lay
* messages in the console * messages in the console
skipping to change at line 78 skipping to change at line 89
*/ */
#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
* and decoding. This may be useful if you want to obfuscate your json, o
r send binary data over
* a network
*/
//#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
* your json into a stream, which will automatically hit a callback when f
ull nodes are
* completed
*/
//#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 costomizability, 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 mot 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
skipping to change at line 117 skipping to change at line 142
//#define JSON_MUTEX_CALLBACKS //#define JSON_MUTEX_CALLBACKS
/* /*
* JSON_MUTEX_MANAGE lets you set mutexes and forget them, libjson will no t only keep * JSON_MUTEX_MANAGE lets you set mutexes and forget them, libjson will no t only keep
* track of the mutex, but also keep a count of how many nodes are using i t, and delete * track of the mutex, but also keep a count of how many nodes are using i t, and delete
* it when there are no more references * it when there are no more references
*/ */
//#define JSON_MUTEX_MANAGE //#define JSON_MUTEX_MANAGE
/* /*
* JSON_ISO_STRICT turns off all code that uses non-standard C++. This re
moves all
* references to long long and long double as well as a few others
*/
//#define JSON_ISO_STRICT
/*
* JSON_NO_C_CONSTS removes consts from the C interface. It still acts th e same way, but * JSON_NO_C_CONSTS removes consts from the C interface. It still acts th e same way, but
* this may be useful for using the header with languages or variants that don't have const * this may be useful for using the header with languages or variants that don't have const
*/ */
//#define JSON_NO_C_CONSTS //#define JSON_NO_C_CONSTS
/* /*
* JSON_WRITER turns on libjson's writing capabilties. Without this libjs * JSON_OCTAL allows libjson to use octal values in numbers.
on can only
* read and parse json, this allows it to write back out
*/ */
#define JSON_WRITER //#define JSON_OCTAL
/*
* JSON_WRITE_PRIORITY turns on libjson's writing capabilties. Without th
is libjson can only
* read and parse json, this allows it to write back out. Changing the va
lue of the writer
* changes how libjson compiles, and how fast it will go when writing
*/
#define JSON_WRITE_PRIORITY MED
/*
* JSON_READ_PRIORITY turns on libjson's reading capabilties. Changing th
e value of the reader
* changes how libjson compiles, and how fast it will go when writing
*/
#define JSON_READ_PRIORITY HIGH
/* /*
* JSON_NEWLINE affects how libjson writes. If this option is turned on, libjson * JSON_NEWLINE affects how libjson writes. If this option is turned on, libjson
* will use whatever it's defined as for the newline signifier, otherwise, it will use * will use whatever it's defined as for the newline signifier, otherwise, it will use
* standard unix \n. * standard unix \n.
*/ */
//#define JSON_NEWLINE "\r\n" //\r\n is standard for most windows and dos programs //#define JSON_NEWLINE "\r\n" //\r\n is standard for most windows and dos programs
/* /*
* JSON_INDENT affects how libjson writes. If this option is turned on, l ibjson * JSON_INDENT affects how libjson writes. If this option is turned on, l ibjson
skipping to change at line 214 skipping to change at line 245
*/ */
//#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
* internally, but the interface will never throw anything.
*/
//#define JSON_NO_EXCEPTIONS
/*
* 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
* over to the new equivalents
*/
#define JSON_DEPRECATED_FUNCTIONS
#endif #endif
 End of changes. 8 change blocks. 
11 lines changed or deleted 65 lines changed or added


 JSONWorker.h   JSONWorker.h 
#ifndef JSON_WORKER_H #ifndef JSON_WORKER_H
#define JSON_WORKER_H #define JSON_WORKER_H
#include "JSONNode.h" #include "JSONNode.h"
class JSONWorker { class JSONWorker {
public: public:
static JSONNode parse(const json_string & json); static json_string RemoveWhiteSpaceAndComments(const json_string & valu
#ifdef JSON_VALIDATE e_t) json_nothrow json_read_priority;
static JSONNode validate(const json_string & json);
#endif
#if defined JSON_DEBUG || defined JSON_SAFE
static json_char * RemoveWhiteSpace(const json_string & value_t,
json_char & last);
#else
static json_char * RemoveWhiteSpace(const json_string & value_t);
#endif
static json_string RemoveWhiteSpaceAndComments(const json_string & valu
e_t);
static void DoArray(const internalJSONNode * parent, const json_string #ifdef JSON_READ_PRIORITY
& value_t); static JSONNode parse(const json_string & json) json_throws(std::
static void DoNode(const internalJSONNode * parent, const json_string & invalid_argument) json_read_priority;
value_t); static JSONNode parse_unformatted(const json_string & json) json_
throws(std::invalid_argument) json_read_priority;
#ifdef JSON_LESS_MEMORY #if defined JSON_DEBUG || defined JSON_SAFE
#define NAME_ENCODED this, true static JSONNode _parse_unformatted(const json_char * json,
#define STRING_ENCODED this, false json_char & lastchar) json_throws(std::invalid_argument) json_read_priorit
static json_string FixString(const json_string & value_t, const i y;
nternalJSONNode * flag, bool which); #else
#else static JSONNode _parse_unformatted(const json_char * json)
#define NAME_ENCODED _name_encoded json_throws(std::invalid_argument) json_read_priority;
#define STRING_ENCODED _string_encoded #endif
static json_string FixString(const json_string & value_t, bool &
flag); #if defined JSON_DEBUG || defined JSON_SAFE
static json_char * RemoveWhiteSpace(const json_string & va
lue_t, json_char & last) json_nothrow json_read_priority;
#else
static json_char * RemoveWhiteSpace(const json_string & va
lue_t) json_nothrow json_read_priority;
#endif
static void DoArray(const internalJSONNode * parent, const json_s
tring & value_t) json_nothrow json_read_priority;
static void DoNode(const internalJSONNode * parent, const json_st
ring & value_t) json_nothrow json_read_priority;
#ifdef JSON_LESS_MEMORY
#define NAME_ENCODED this, true
#define STRING_ENCODED this, false
static json_string FixString(const json_string & value_t,
const internalJSONNode * flag, bool which) json_nothrow json_read_priority;
#else
#define NAME_ENCODED _name_encoded
#define STRING_ENCODED _string_encoded
static json_string FixString(const json_string & value_t,
bool & flag) json_nothrow json_read_priority;
#endif
#endif #endif
static json_string UnfixString(const json_string & value_t, bool flag);
#if defined(JSON_READ_PRIORITY) || defined(JSON_STREAM)
static size_t FindNextRelevant(json_char ch, const json_string &
value_t, const size_t pos) json_nothrow json_read_priority;
#endif
static json_string UnfixString(const json_string & value_t, bool flag)
json_nothrow;
JSON_PRIVATE JSON_PRIVATE
static json_char Hex(const json_char * & pos); #ifdef JSON_READ_PRIORITY
static json_uchar UTF8(const json_char * & pos); static json_char Hex(const json_char * & pos) json_nothrow;
static json_uchar UTF8(const json_char * & pos) json_nothrow;
#endif
#ifdef JSON_ESCAPE_WRITES #ifdef JSON_ESCAPE_WRITES
static json_string toUTF8(json_uchar p); static json_string toUTF8(json_uchar p) json_nothrow;
#endif #endif
#ifdef JSON_UNICODE #ifdef JSON_UNICODE
static json_string UTF(const json_char * & pos); static json_string UTF(const json_char * & pos) json_nothrow;
#ifdef JSON_ESCAPE_WRITES #ifdef JSON_ESCAPE_WRITES
static json_string toSurrogatePair(json_uchar pos); static json_string toSurrogatePair(json_uchar pos) json_no throw;
#endif #endif
#endif #endif
static void SpecialChar(const json_char * & pos, json_string & res); #ifdef JSON_READ_PRIORITY
static size_t FindNextRelevant(json_char ch, const json_string & value_ static void SpecialChar(const json_char * & pos, json_string & re
t, const size_t pos); s) json_nothrow;
static void NewNode(const internalJSONNode * parent, const json_string static void NewNode(const internalJSONNode * parent, const json_s
& name, const json_string & value, bool array); tring & name, const json_string & value, bool array) json_nothrow;
#endif
}; };
#endif #endif
 End of changes. 9 change blocks. 
37 lines changed or deleted 60 lines changed or added


 JSON_Base64.h   JSON_Base64.h 
#ifndef JSON_BASE64_H #ifndef JSON_BASE64_H
#define JSON_BASE64_H #define JSON_BASE64_H
#include "JSONDebug.h" #include "JSONDebug.h"
#ifdef JSON_BINARY //if this is not needed, don't waste space compiling it #if defined(JSON_BINARY) || defined(JSON_EXPOSE_BASE64) //if this is not n eeded, don't waste space compiling it
#include <string> #include <string>
class JSONBase64 { class JSONBase64 {
public: public:
static json_string json_encode64(const unsigned char * binary, size_t b static json_string json_encode64(const unsigned char * binary, size_t b
ytes); ytes) json_nothrow json_cold;
static std::string json_decode64(const json_string & encoded); static std::string json_decode64(const json_string & encoded) json_noth
row json_cold;
}; };
#endif #endif
#endif #endif
 End of changes. 2 change blocks. 
4 lines changed or deleted 5 lines changed or added


 NumberToString.h   NumberToString.h 
#ifndef NUMBERTOSTRING_H #ifndef NUMBERTOSTRING_H
#define NUMBERTOSTRING_H #define NUMBERTOSTRING_H
#include "JSONDebug.h" #include "JSONDebug.h"
#include "JSONMemory.h" #ifdef JSON_LESS_MEMORY
#include "JSONMemory.h"
#endif
#include <cstdio> #include <cstdio>
#ifdef JSON_STRICT
#include <cmath>
#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};
}; };
template<> template<>
struct getLenSize<1>{ struct getLenSize<1>{
enum {GETLEN = 5}; enum {GETLEN = 5};
}; };
skipping to change at line 34 skipping to change at line 38
template <> template <>
struct getLenSize<4>{ struct getLenSize<4>{
enum {GETLEN = 12}; enum {GETLEN = 12};
}; };
template <> template <>
struct getLenSize<8>{ struct getLenSize<8>{
enum {GETLEN = 22}; enum {GETLEN = 22};
}; };
static inline bool _floatsAreEqual(const json_number & one, const json_numb
er & two) json_pure;
static inline bool _floatsAreEqual(const json_number & one, const json_numb
er & two) json_nothrow {
return (one > two) ? (one - two) < JSON_FLOAT_THRESHHOLD : (one - two)
> -JSON_FLOAT_THRESHHOLD;
}
#ifdef JSON_LESS_MEMORY
#define num_str_result s.ptr
#endif
class NumberToString { class NumberToString {
public: public:
template<typename T> template<typename T>
static json_string _itoa(T val){ static json_string _itoa(T val) json_nothrow {
json_char result[getLenSize<sizeof(T)>::GETLEN]; #ifdef JSON_LESS_MEMORY
result[getLenSize<sizeof(T)>::GETLEN - 1] = JSON_TEXT('\0'); //nu json_auto<json_char> s(getLenSize<sizeof(T)>::GETLEN);
ll terminator #else
json_char * runner = &result[getLenSize<sizeof(T)>::GETLEN - 2]; json_char num_str_result[getLenSize<sizeof(T)>::GETLEN];
#endif
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];
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 tive //first thing, check if it's negative, if so, make it posi tive
if (value < 0){ if (value < 0){
value = -value; value = -value;
negative = true; negative = true;
} else { } else {
negative = false; negative = false;
} }
//create the string //create the string
do { do {
*runner-- = (json_char)(value % 10) + JSON_TEXT('0' ); *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
json_string res;
if (negative){ if (negative){
*runner = JSON_TEXT('-'); *runner = JSON_TEXT('-');
res = runner; return json_string(runner);
} else {
res = runner + 1;
} }
return res; return json_string(runner + 1);
} }
#ifndef JSON_LIBRARY #ifndef JSON_LIBRARY
template<typename T> template<typename T>
static json_string _uitoa(T val){ static json_string _uitoa(T val) json_nothrow {
json_char result[getLenSize<sizeof(T)>::GETLEN]; #ifdef JSON_LESS_MEMORY
result[getLenSize<sizeof(T)>::GETLEN - 1] = JSON_TEXT('\0' json_auto<json_char> s(getLenSize<sizeof(T)>::GETLE
); //null terminator N);
json_char * runner = &result[getLenSize<sizeof(T)>::GETLEN #else
- 2]; json_char num_str_result[getLenSize<sizeof(T)>::GET
LEN];
#endif
num_str_result[getLenSize<sizeof(T)>::GETLEN - 1] = JSON_T
EXT('\0'); //null terminator
json_char * runner = &num_str_result[getLenSize<sizeof(T)>
::GETLEN - 2];
//create the string //create the string
START_MEM_SCOPE START_MEM_SCOPE
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
json_string res = runner + 1; return json_string(runner + 1);
return res;
} }
#endif #endif
template<typename T> static json_string _ftoa(json_number value) json_nothrow {
static json_string _ftoa(T value){ #ifndef JSON_LIBRARY
json_char result[64]; if (json_unlikely(value > 0.0 && _floatsAreEqual(value, (j
son_number)((unsigned long)value)))){
return _uitoa<unsigned long>((unsigned long)value);
} else
#endif
if (json_unlikely(_floatsAreEqual(value, (json_number)((long)valu
e)))){
return _itoa<long>((long)value);
}
#ifdef JSON_LESS_MEMORY
json_auto<json_char> s(64);
#else
json_char num_str_result[64];
#endif
#ifdef JSON_UNICODE #ifdef JSON_UNICODE
swprintf(result, 63, L"%f", value); swprintf(num_str_result, 63, L"%f", value);
#else #else
//Thanks to Salvor Hardin for this Visual C++ fix //Thanks to Salvor Hardin for this Visual C++ fix
#if _MSC_VER #ifdef _MSC_VER
_snprintf_s(result, 63, 63, "%f", value); //yes, 63 _snprintf_s(num_str_result, 63, 63, "%f", value); /
appears twice using _snprintf_s() /yes, 63 appears twice using _snprintf_s()
#else #else
snprintf(result, 63, "%f", value); snprintf(num_str_result, 63, "%f", value);
#endif #endif
#endif #endif
//strip the trailing zeros //strip the trailing zeros
for(json_char * pos = &result[0]; *pos; ++pos){ for(json_char * pos = &num_str_result[0]; *pos; ++pos){
if (*pos == '.'){ //only care about after the decimal if (json_unlikely(*pos == '.')){ //only care about after
the decimal
for(json_char * runner = pos + 1; *runner; ++runner ){ for(json_char * runner = pos + 1; *runner; ++runner ){
if (*runner != JSON_TEXT('0')) pos = runner + 1; //have to go to the end 1.0001 if (json_likely(*runner != JSON_TEXT('0'))) pos = runner + 1; //have to go to the end 1.0001
} }
*pos = JSON_TEXT('\0'); *pos = JSON_TEXT('\0');
break; break;
} }
} }
return result; return json_string(num_str_result);
} }
static inline bool areEqual(const json_number & one, const json_number #if defined(JSON_SAFE) || defined(JSON_DEBUG)
& two){ static bool isNumeric(const json_string & str) json_nothrow {
const json_number temp = one - two; const json_char * p = str.c_str();
return (temp > 0.0) ? temp < 0.00001 : temp > -0.00001; bool decimal = false;
} bool scientific = false;
//first letter is weird
switch(*p){
case '\0':
return false;
#ifndef JSON_STRICT
case '.':
decimal = true;
break;
case '+':
#endif
case '-':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
case '0':
++p;
switch(*p){
case '.':
decimal = true;
break;
case 'e':
case 'E':
scientific = true;
++p;
switch(*p){
case '\0':
return false;
case '-':
case '+':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
default:
return false;
}
break;
#ifndef JSON_STRICT
case 'x':
return (str.find_first_not
_of(JSON_TEXT("0123456789ABCDEFabcdef"), 2) == json_string::npos);
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
return (str.find_first_not
_of(JSON_TEXT("01234567"), 1) == json_string::npos);
#endif
case '\0': //just 0
return true;
default:
return false;
}
break;
default:
return false;
}
++p;
//next digits
while (*p){
switch(*p){
case '.':
if (json_unlikely(decimal)) return false
; //multiple decimals
if (json_unlikely(scientific)) return fa
lse;
decimal = true;
break;
case 'e':
case 'E':
if (json_unlikely(scientific)) return fa
lse;
scientific = true;
++p;
switch(*p){
case '\0':
return false;
case '-':
case '+':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
default:
return false;
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
default:
return false;
}
++p;
}
return true;
}
#endif
#ifdef JSON_STRICT
//much faster because no octal or hex support
json_number _atof (json_char * num){
json_number sign = 1.0;
//sign
if (*num=='-'){
sign = -1.0;
++num;
}
//skip leading zeros
while (*num == '0'){
++num;
}
// Number
json_number n = 0.0
if (json_likely(*num >= '1' && *num <= '9')){
do {
n = (n * 10.0) + (*num++ - '0');
} while (*num >= '0' && *num <= '9');
}
// Fractional part
json_number scale = 0.0;
if (*num=='.') {
++num;
do {
n = (n * 10.0) + (*num++ - '0');
--scale;
} while (*num>='0' && *num<='9');
}
// Exponent
int subscale = 0, signsubscale = 1;
if (json_unlikely(*num == 'e' || *num == 'E')){
++num;
switch(*num){
case '+':
++num;
break;
case '-':
signsubscale = -1;
++num;
break;
}
while (*num >= '0' && *num <= '9'){
subscale=(subscale * 10) + (*num++ - '0');
}
}
return sign * n * pow(10.0, scale + subscale * signsubscal
e); // number = +/- number.fraction * 10^+/- exponent
}
#endif
}; };
#endif #endif
 End of changes. 17 change blocks. 
37 lines changed or deleted 264 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"
#ifdef JSON_DEBUG #ifdef JSON_DEBUG
#include <climits> //to check int value #include <climits> //to check int value
#endif #endif
#ifdef JSON_LESS_MEMORY
#ifdef __GNUC__
#pragma pack(push, 1)
#elif _MSC_VER
#pragma pack(push, internalJSONNode_pack, 1)
#endif
#endif
/* /*
This class is the work horse of libjson, it handles all of the This class is the work horse of libjson, it handles all of the
functinality of JSONNode. This object is reference counted for functinality of JSONNode. This object is reference counted for
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); void Set(unsigned type); #define DECL_SET_INTEGER(type) void Set(type) json_nothrow json_write_p riority; void Set(unsigned type) json_nothrow json_write_priority;
#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
#ifdef JSON_PREPARSE #if defined(JSON_PREPARSE) || !defined(JSON_READ_PRIORITY)
#define SetFetched(b) (void)0 #define SetFetched(b) (void)0
#define Fetch() (void)0 #define Fetch() (void)0
#define initializeFetch(x) #define initializeFetch(x)
#else #else
#define initializeFetch(x) ,fetched(x) #define initializeFetch(x) ,fetched(x)
#endif #endif
#ifdef JSON_REF_COUNT #ifdef JSON_REF_COUNT
#define initializeRefCount(x) ,refcount(x) #define initializeRefCount(x) ,refcount(x)
#else #else
skipping to change at line 59 skipping to change at line 67
#define initializeComment(x) #define initializeComment(x)
#endif #endif
#ifndef JSON_UNIT_TEST #ifndef JSON_UNIT_TEST
#define incAllocCount() (void)0 #define incAllocCount() (void)0
#define decAllocCount() (void)0 #define decAllocCount() (void)0
#define incinternalAllocCount() (void)0 #define incinternalAllocCount() (void)0
#define decinternalAllocCount() (void)0 #define decinternalAllocCount() (void)0
#endif #endif
#ifdef JSON_VALIDATE #ifdef JSON_LESS_MEMORY
#define initializeValid(x) ,isValid(x) #define CHILDREN _value.Children
#define DELETE_CHILDREN()\
if (isContainer()){\
jsonChildren::deleteChildren(CHILDREN);\
}
#define CHILDREN_TO_NULL() (void)0
#define initializeChildren(x)
#else #else
#define initializeValid(x) #define CHILDREN Children
#define DELETE_CHILDREN()\
if (CHILDREN != 0) jsonChildren::deleteChildren(CHILDREN);
#define CHILDREN_TO_NULL() CHILDREN = 0
#define makeNotContainer() (void)0
#define makeContainer() if (!CHILDREN) CHILDREN = jsonChildren::newChil
dren()
#define initializeChildren(x) ,CHILDREN(x)
#endif #endif
class internalJSONNode { class internalJSONNode {
public: public:
internalJSONNode(char mytype = JSON_NULL); internalJSONNode(char mytype = JSON_NULL) json_nothrow json_hot;
internalJSONNode(const json_string & unparsed); #ifdef JSON_READ_PRIORITY
internalJSONNode(const json_string & name_t, const json_string & value_ internalJSONNode(const json_string & unparsed) json_nothrow json_
t); hot;
internalJSONNode(const internalJSONNode & orig); internalJSONNode(const json_string & name_t, const json_string &
internalJSONNode & operator = (const internalJSONNode &); value_t) json_nothrow json_read_priority;
~internalJSONNode(void); #endif
internalJSONNode(const internalJSONNode & orig) json_nothrow json_hot;
internalJSONNode & operator = (const internalJSONNode &) json_nothrow j
son_hot;
~internalJSONNode(void) json_nothrow json_hot;
static internalJSONNode * newInternal(char mytype = JSON_NULL); static internalJSONNode * newInternal(char mytype = JSON_NULL) json_hot
static internalJSONNode * newInternal(const json_string & unparsed); ;
static internalJSONNode * newInternal(const json_string & name_t, const #ifdef JSON_READ_PRIORITY
json_string & value_t); static internalJSONNode * newInternal(const json_string & unparse
static internalJSONNode * newInternal(const internalJSONNode & orig); d) json_hot;
//not copyable, only by this class static internalJSONNode * newInternal(const json_string & name_t,
static void deleteInternal(internalJSONNode * ptr); const json_string & value_t) json_hot;
#endif
static internalJSONNode * newInternal(const internalJSONNode & orig) js
on_hot; //not copyable, only by this class
static void deleteInternal(internalJSONNode * ptr) json_nothrow json_ho
t;
json_index_t size(void) const; json_index_t size(void) const json_nothrow json_read_priority;
bool empty(void) const; bool empty(void) const json_nothrow;
unsigned char type(void) const; unsigned char type(void) const json_nothrow json_read_priority;
json_string name(void) const; json_string name(void) const json_nothrow json_read_priority;
void setname(const json_string & newname); void setname(const json_string & newname) json_nothrow json_write_prior
ity;
#ifdef JSON_COMMENTS #ifdef JSON_COMMENTS
void setcomment(const json_string & comment); void setcomment(const json_string & comment) json_nothrow;
json_string getcomment(void) const; json_string getcomment(void) const json_nothrow;
#endif #endif
json_string as_string(void) const; json_string as_string(void) const json_nothrow json_read_priority;
long as_int(void) const; long as_int(void) const json_nothrow json_read_priority;
json_number as_float(void) const; json_number as_float(void) const json_nothrow json_read_priority;
bool as_bool(void) const; bool as_bool(void) const json_nothrow json_read_priority;
#ifndef JSON_PREPARSE #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
void preparse(void); void preparse(void) json_nothrow;
#endif #endif
#ifdef JSON_LIBRARY #ifdef JSON_LIBRARY
void push_back(JSONNode * node); void push_back(JSONNode * node) json_nothrow;
#else #else
void push_back(const JSONNode & node); void push_back(const JSONNode & node) json_nothrow;
#endif #endif
void reserve(json_index_t siz); void reserve(json_index_t siz) json_nothrow;
void push_front(const JSONNode & node); void push_front(const JSONNode & node) json_nothrow;
JSONNode * pop_back(json_index_t pos); JSONNode * pop_back(json_index_t pos) json_nothrow;
JSONNode * pop_back(const json_string & name_t); JSONNode * pop_back(const json_string & name_t) json_nothrow;
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
JSONNode * pop_back_nocase(const json_string & name_t); JSONNode * pop_back_nocase(const json_string & name_t) json_nothr ow;
#endif #endif
JSONNode * at(json_index_t pos); 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); 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); JSONNode ** at_nocase(const json_string & name_t) json_nothrow;
#endif #endif
void Set(const json_string & val); void Set(const json_string & val) json_nothrow json_write_priority;
#ifdef JSON_LIBRARY #ifdef JSON_LIBRARY
void Set(json_number val); void Set(json_number val) json_nothrow json_write_priority;
void Set(long val); void Set(long val) json_nothrow json_write_priority;
#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)
#endif #endif
void Set(float val); void Set(float val) json_nothrow json_write_priority;
void Set(double val); void Set(double val) json_nothrow json_write_priority;
#endif #endif
void Set(bool val); void Set(bool val) json_nothrow;
bool IsEqualTo(const json_string & val)const ; bool IsEqualTo(const json_string & val) const json_nothrow;
bool IsEqualTo(bool val) const; bool IsEqualTo(bool val) const json_nothrow;
bool IsEqualTo(const internalJSONNode * val) const; bool IsEqualTo(const internalJSONNode * val) const json_nothrow;
template<typename T> template<typename T>
bool IsEqualToNum(T val) const; bool IsEqualToNum(T val) const json_nothrow;
internalJSONNode * incRef(void); internalJSONNode * incRef(void) json_nothrow;
#ifdef JSON_REF_COUNT #ifdef JSON_REF_COUNT
void decRef(void); void decRef(void) json_nothrow json_hot;
bool hasNoReferences(void); bool hasNoReferences(void) json_nothrow json_hot;
#endif #endif
internalJSONNode * makeUnique(void); internalJSONNode * makeUnique(void) json_nothrow json_hot;
JSONNode ** begin(void) const; JSONNode ** begin(void) const json_nothrow;
JSONNode ** end(void) const; JSONNode ** end(void) const json_nothrow;
#ifdef JSON_REF_COUNT bool Fetched(void) const json_nothrow json_hot;
size_t refcount BITS(20);
#endif
bool Fetched(void) const;
#ifdef JSON_MUTEX_CALLBACKS #ifdef JSON_MUTEX_CALLBACKS
void * mylock; void _set_mutex(void * mutex, bool unset = true) json_nothrow jso
void _set_mutex(void * mutex, bool unset = true); n_cold;
void _unset_mutex(void); void _unset_mutex(void) json_nothrow json_cold;
#endif #endif
#ifdef JSON_UNIT_TEST #ifdef JSON_UNIT_TEST
static void incinternalAllocCount(void); static void incinternalAllocCount(void) json_nothrow;
static void decinternalAllocCount(void); static void decinternalAllocCount(void) json_nothrow;
#endif #endif
#ifdef JSON_WRITER #ifdef JSON_WRITE_PRIORITY
json_string WriteName(bool formatted, bool arrayChild) const; json_string WriteName(bool formatted, bool arrayChild) const json
json_string WriteChildren(unsigned int indent); _nothrow json_write_priority;
json_string WriteComment(unsigned int indent) const; json_string WriteChildren(unsigned int indent) json_nothrow json_
json_string Write(unsigned int indent, bool arrayChild); write_priority;
json_string WriteComment(unsigned int indent) const json_nothrow
json_write_priority;
json_string Write(unsigned int indent, bool arrayChild) json_noth
row json_write_priority;
#endif
inline bool isContainer(void) const json_nothrow {
return (_type == JSON_NODE || _type == JSON_ARRAY);
}
inline bool isNotContainer(void) const json_nothrow {
return (_type != JSON_NODE && _type != JSON_ARRAY);
}
#ifdef JSON_LESS_MEMORY
inline void makeNotContainer(void){
if (isContainer()){
jsonChildren::deleteChildren(CHILDREN);
}
}
inline void makeContainer(void){
if (isNotContainer()){
CHILDREN = jsonChildren::newChildren();
}
}
#endif
void Nullify(void) const json_nothrow;
#if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
void SetFetched(bool val) const json_nothrow json_hot;
void Fetch(void) const json_nothrow json_hot; //it's const becau
se it doesn't change the VALUE of the function
#endif #endif
#ifdef JSON_READ_PRIORITY
void FetchString(void) const json_nothrow json_read_priority;
void FetchNode(void) const json_nothrow json_read_priority;
void FetchArray(void) const json_nothrow json_read_priority;
#endif
void FetchNumber(void) const json_nothrow json_read_priority;
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
static bool AreEqualNoCase(const json_char * ch_one, const json_c
har * ch_two) json_nothrow json_read_priority;
#endif
inline void clearname(void) json_nothrow {
clearString(_name);
}
#ifdef JSON_DEBUG #ifdef JSON_DEBUG
#ifndef JSON_LIBRARY #ifndef JSON_LIBRARY
JSONNode Dump(size_t & totalmemory) const; JSONNode Dump(size_t & totalmemory) const json_nothrow;
JSONNode DumpMutex(void) const; JSONNode DumpMutex(void) const json_nothrow;
#endif #endif
#endif #endif
//json parts
mutable unsigned char _type BITS(3); mutable unsigned char _type BITS(3);
mutable bool _name_encoded BITS(1); //must be above name due to initia lization list order
json_string _name; json_string _name;
mutable bool _name_encoded BITS(1); //must be above name due to initia lization list order
mutable json_string _string; //these are both mutable because the str ing can change when it's fetched mutable json_string _string; //these are both mutable because the str ing can change when it's fetched
mutable bool _string_encoded BITS(1); mutable bool _string_encoded BITS(1);
//the value of the json //the value of the json
union value_union_t { union value_union_t {
bool _bool; bool _bool BITS(1);
json_number _number; json_number _number;
#ifdef JSON_LESS_MEMORY
jsonChildren * Children;
#endif
}; };
mutable value_union_t _value; //internal structure changes depending on type mutable value_union_t _value; //internal structure changes depending on type
jsonChildren Children; //container that holds all of my children #ifdef JSON_MUTEX_CALLBACKS
void * mylock;
#endif
#ifdef JSON_VALIDATE #ifdef JSON_REF_COUNT
mutable bool isValid BITS(1); //this does not need to be initial size_t refcount PACKED(20);
ized, it's only used if it's null
void Nullify(bool validation = true) const;
bool validate(void);
#else
void Nullify(void) const;
#endif #endif
//Fetching and such #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
#ifndef JSON_PREPARSE
mutable bool fetched BITS(1); mutable bool fetched BITS(1);
void SetFetched(bool val) const;
void Fetch(void) const; //it's const because it doesn't change t
he VALUE of the function
#endif #endif
#ifdef JSON_COMMENTS #ifdef JSON_COMMENTS
json_string _comment; json_string _comment;
#endif #endif
void FetchString(void) const; #ifndef JSON_LESS_MEMORY
void FetchNode(void) const; jsonChildren * CHILDREN;
void FetchArray(void) const;
void FetchNumber(void) const;
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
static bool AreEqualNoCase(const json_char * ch_one, const json_c
har * ch_two);
#endif #endif
}; };
inline internalJSONNode::internalJSONNode(char mytype) : _type(mytype), Chi ldren(), _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() initializeComment(EMPTY_JSON_STRING)
initializeValid(true){ initializeChildren((_type == JSON_NODE || _type == JSON_ARRAY) ? jsonCh
ildren::newChildren() : 0){
incinternalAllocCount(); incinternalAllocCount();
#ifdef JSON_LESS_MEMORY
//if not less memory, its in the initialization list
if (isContainer()){
CHILDREN = jsonChildren::newChildren();
}
#endif
} }
inline internalJSONNode * internalJSONNode::incRef(void){ inline internalJSONNode * internalJSONNode::incRef(void) json_nothrow {
#ifdef JSON_REF_COUNT #ifdef JSON_REF_COUNT
++refcount; ++refcount;
return this; return this;
#else #else
return makeUnique(); return makeUnique();
#endif #endif
} }
inline json_index_t internalJSONNode::size(void) const { inline json_index_t internalJSONNode::size(void) const json_nothrow {
if (isNotContainer()) return 0;
Fetch(); Fetch();
return Children.size(); return CHILDREN -> size();
} }
inline bool internalJSONNode::empty(void) const { inline bool internalJSONNode::empty(void) const json_nothrow {
if (type() != JSON_NODE && type() != JSON_ARRAY) return true; if (isNotContainer()) return true;
Fetch(); Fetch();
return Children.empty(); return CHILDREN -> empty();
} }
inline unsigned char internalJSONNode::type(void) const { inline unsigned char internalJSONNode::type(void) const json_nothrow {
return _type; return _type;
} }
inline json_string internalJSONNode::name(void) const { inline json_string internalJSONNode::name(void) const json_nothrow {
return _name; return _name;
} }
inline void internalJSONNode::setname(const json_string & newname){ 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){ inline void internalJSONNode::setcomment(const json_string & comment) j son_nothrow {
#ifdef JSON_LESS_MEMORY #ifdef JSON_LESS_MEMORY
JSON_ASSERT(comment.capacity() == comment.length(), JSON_T EXT("comment object too large")); JSON_ASSERT(comment.capacity() == comment.length(), JSON_T EXT("comment object too large"));
#endif #endif
_comment = comment; _comment = comment;
} }
inline json_string internalJSONNode::getcomment(void) const { inline json_string internalJSONNode::getcomment(void) const json_nothro w {
return _comment; return _comment;
} }
#endif #endif
inline json_string internalJSONNode::as_string(void) const { inline json_string internalJSONNode::as_string(void) const json_nothrow {
Fetch(); Fetch();
return _string; return _string;
} }
inline long internalJSONNode::as_int(void) const { inline long internalJSONNode::as_int(void) const json_nothrow {
Fetch(); Fetch();
switch(type()){ switch(type()){
case JSON_NULL: case JSON_NULL:
return 0; return 0;
case JSON_BOOL: case JSON_BOOL:
return _value._bool ? 1 : 0; return _value._bool ? 1 : 0;
case JSON_STRING: case JSON_STRING:
FetchNumber(); FetchNumber();
} }
JSON_ASSERT(type() == JSON_NUMBER, JSON_TEXT("as_int returning undefine d results")); 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_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 < LONG_MAX, _string + JSON_TEXT(" is outside the upper range of long"));
JSON_ASSERT(_value._number == (json_number)((int)_value._number), json_ JSON_ASSERT(_value._number == (json_number)((long)_value._number), json
string(JSON_TEXT("as_int will truncate ")) + _string); _string(JSON_TEXT("as_int will truncate ")) + _string);
return (int)_value._number; return (long)_value._number;
} }
inline json_number internalJSONNode::as_float(void) const { inline json_number internalJSONNode::as_float(void) const json_nothrow {
Fetch(); Fetch();
switch(type()){ switch(type()){
case JSON_NULL: case JSON_NULL:
return (json_number)0.0; return (json_number)0.0;
case JSON_BOOL: case JSON_BOOL:
return (json_number)(_value._bool ? 1.0 : 0.0); return (json_number)(_value._bool ? 1.0 : 0.0);
case JSON_STRING: case JSON_STRING:
FetchNumber(); FetchNumber();
} }
JSON_ASSERT(type() == JSON_NUMBER, JSON_TEXT("as_float returning undefi ned results")); JSON_ASSERT(type() == JSON_NUMBER, JSON_TEXT("as_float returning undefi ned results"));
return _value._number; return _value._number;
} }
inline bool internalJSONNode::as_bool(void) const { inline bool internalJSONNode::as_bool(void) const json_nothrow {
Fetch(); Fetch();
switch(type()){ switch(type()){
case JSON_NUMBER: case JSON_NUMBER:
return _value._number != 0.0f; return _value._number != 0.0f;
case JSON_NULL: case JSON_NULL:
return false; return false;
} }
JSON_ASSERT(type() == JSON_BOOL, JSON_TEXT("as_bool returning undefined results")); JSON_ASSERT(type() == JSON_BOOL, JSON_TEXT("as_bool returning undefined results"));
return _value._bool; return _value._bool;
} }
inline bool internalJSONNode::IsEqualTo(const json_string & val) const { 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 val == _string;
} }
inline bool internalJSONNode::IsEqualTo(bool val) const { 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 { inline bool internalJSONNode::IsEqualToNum(T val) const json_nothrow {
if (type() != JSON_NUMBER) return false; if (type() != JSON_NUMBER) return false;
Fetch(); Fetch();
return (json_number)val == _value._number; return (json_number)val == _value._number;
} }
#ifdef JSON_REF_COUNT #ifdef JSON_REF_COUNT
inline void internalJSONNode::decRef(void){ inline void internalJSONNode::decRef(void) json_nothrow {
JSON_ASSERT(refcount != 0, JSON_TEXT("decRef on a 0 refcount inte rnal")); JSON_ASSERT(refcount != 0, JSON_TEXT("decRef on a 0 refcount inte rnal"));
--refcount; --refcount;
} }
inline bool internalJSONNode::hasNoReferences(void){ inline bool internalJSONNode::hasNoReferences(void) json_nothrow {
return refcount == 0; return refcount == 0;
} }
#endif #endif
inline internalJSONNode * internalJSONNode::makeUnique(void){ inline internalJSONNode * internalJSONNode::makeUnique(void) json_nothrow {
#ifdef JSON_REF_COUNT #ifdef JSON_REF_COUNT
if (refcount > 1){ if (refcount > 1){
decRef(); decRef();
return newInternal(*this); return newInternal(*this);
} }
JSON_ASSERT(refcount == 1, JSON_TEXT("makeUnique on a 0 refcount internal")); JSON_ASSERT(refcount == 1, JSON_TEXT("makeUnique on a 0 refcount internal"));
return this; return this;
#else #else
return newInternal(*this); return newInternal(*this);
#endif #endif
} }
#ifndef JSON_PREPARSE #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
inline void internalJSONNode::SetFetched(bool val) const { inline void internalJSONNode::SetFetched(bool val) const json_nothrow {
fetched = val; fetched = val;
} }
#endif #endif
inline bool internalJSONNode::Fetched(void) const { inline bool internalJSONNode::Fetched(void) const json_nothrow {
#ifndef JSON_PREPARSE #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 { inline JSONNode ** internalJSONNode::begin(void) const json_nothrow {
JSON_ASSERT_SAFE(isContainer(), JSON_TEXT("calling begin on non-contain
er type"), return 0;);
Fetch(); Fetch();
return Children.begin(); return CHILDREN -> begin();
} }
inline JSONNode ** internalJSONNode::end(void) const { inline JSONNode ** internalJSONNode::end(void) const json_nothrow {
JSON_ASSERT_SAFE(isContainer(), JSON_TEXT("calling end on non-container
type"), return 0;);
Fetch(); Fetch();
return Children.end(); return CHILDREN -> end();
} }
inline JSONNode * internalJSONNode::at(json_index_t pos){ inline JSONNode * internalJSONNode::at(json_index_t pos) json_nothrow {
JSON_ASSERT_SAFE(isContainer(), JSON_TEXT("calling at on non-container
type"), return 0;);
Fetch(); Fetch();
return Children[pos]; return (*CHILDREN)[pos];
} }
inline void internalJSONNode::reserve(json_index_t siz){ #if defined(JSON_LESS_MEMORY) && defined(__GNUC__)
#ifndef JSON_LESS_MEMORY inline void internalJSONNode::reserve(json_index_t __attribute__((unuse
Fetch(); d)) siz) json_nothrow {
Children.reserve2(siz); #else
#endif inline void internalJSONNode::reserve(json_index_t siz) json_nothrow {
#endif
JSON_ASSERT_SAFE(isContainer(), JSON_TEXT("calling reserve on non-conta
iner type"), return;);
Fetch();
jsonChildren::reserve2(CHILDREN, siz);
} }
/* /*
These functions are to allow allocation to be completely controlled by the callbacks These functions are to allow allocation to be completely controlled by the callbacks
*/ */
inline void internalJSONNode::deleteInternal(internalJSONNode * ptr){ inline void internalJSONNode::deleteInternal(internalJSONNode * ptr) json_n othrow {
#ifdef JSON_MEMORY_CALLBACKS #ifdef JSON_MEMORY_CALLBACKS
ptr -> ~internalJSONNode(); ptr -> ~internalJSONNode();
libjson_free<internalJSONNode>(ptr); libjson_free<internalJSONNode>(ptr);
#else #else
delete ptr; delete ptr;
#endif #endif
} }
inline internalJSONNode * internalJSONNode::newInternal(char mytype){ inline internalJSONNode * internalJSONNode::newInternal(char mytype) {
#ifdef JSON_MEMORY_CALLBACKS #ifdef JSON_MEMORY_CALLBACKS
return new(json_malloc<internalJSONNode>(1)) internalJSONNode(myt ype); return new(json_malloc<internalJSONNode>(1)) internalJSONNode(myt ype);
#else #else
return new internalJSONNode(mytype); return new internalJSONNode(mytype);
#endif #endif
} }
inline internalJSONNode * internalJSONNode::newInternal(const json_string & #ifdef JSON_READ_PRIORITY
unparsed){ inline internalJSONNode * internalJSONNode::newInternal(const json_string &
unparsed) {
#ifdef JSON_MEMORY_CALLBACKS #ifdef JSON_MEMORY_CALLBACKS
return new(json_malloc<internalJSONNode>(1)) internalJSONNode(unp arsed); return new(json_malloc<internalJSONNode>(1)) internalJSONNode(unp arsed);
#else #else
return new internalJSONNode(unparsed); return new internalJSONNode(unparsed);
#endif #endif
} }
inline internalJSONNode * internalJSONNode::newInternal(const json_string & name_t, const json_string & value_t){ inline internalJSONNode * internalJSONNode::newInternal(const json_string & name_t, const json_string & value_t) {
#ifdef JSON_MEMORY_CALLBACKS #ifdef JSON_MEMORY_CALLBACKS
return new(json_malloc<internalJSONNode>(1)) internalJSONNode(nam e_t, value_t); return new(json_malloc<internalJSONNode>(1)) internalJSONNode(nam e_t, value_t);
#else #else
return new internalJSONNode(name_t, value_t); return new internalJSONNode(name_t, value_t);
#endif #endif
} }
#endif
inline internalJSONNode * internalJSONNode::newInternal(const internalJSONN ode & orig){ inline internalJSONNode * internalJSONNode::newInternal(const internalJSONN ode & orig) {
#ifdef JSON_MEMORY_CALLBACKS #ifdef JSON_MEMORY_CALLBACKS
return new(json_malloc<internalJSONNode>(1)) internalJSONNode(ori g); return new(json_malloc<internalJSONNode>(1)) internalJSONNode(ori g);
#else #else
return new internalJSONNode(orig); return new internalJSONNode(orig);
#endif #endif
} }
#ifdef JSON_LESS_MEMORY
#ifdef __GNUC__
#pragma pack(pop)
#elif _MSC_VER
#pragma pack(pop, internalJSONNode_pack,)
#endif
#endif
#endif #endif
 End of changes. 84 change blocks. 
145 lines changed or deleted 242 lines changed or added


 libjson.h   libjson.h 
skipping to change at line 15 skipping to change at line 15
/* /*
This is the C interface to libjson. This is the C interface to libjson.
This file also declares various things that are needed for This file also declares various things that are needed for
C++ programming C++ programming
*/ */
#ifdef JSON_LIBRARY //compiling the library, hide the interface #ifdef JSON_LIBRARY //compiling the library, hide the interface
#ifdef __cplusplus #ifdef __cplusplus
#ifdef JSON_UNIT_TEST
#include "Source/JSONNode.h"
#endif
extern "C" { extern "C" {
#endif #endif
#ifdef JSON_NO_C_CONSTS #ifdef JSON_NO_C_CONSTS
//The interface has no consts in it, but ther must be const_cast internally /* The interface has no consts in it, but ther must be const_cast internally */
#define json_const #define json_const
#define TOCONST_CSTR(x) const_cast<const json_char *>(x) #define TOCONST_CSTR(x) const_cast<const json_char *>(x)
#else #else
#define json_const const #define json_const const
#define TOCONST_CSTR(x) x #define TOCONST_CSTR(x) x
#endif #endif
/* /*
stuff that's in namespace libjson stuff that's in namespace libjson
*/ */
void json_free(void * str); void json_free(void * str);
void json_delete(JSONNODE * node); void json_delete(JSONNODE * node);
#ifdef JSON_MEMORY_MANAGE #ifdef JSON_MEMORY_MANAGE
void json_free_all(void); void json_free_all(void);
void json_delete_all(void); void json_delete_all(void);
#endif #endif
JSONNODE * json_parse(json_const json_char * json); #ifdef JSON_READ_PRIORITY
JSONNODE * json_parse(json_const json_char * json);
JSONNODE * json_parse_unformatted(json_const json_c
har * json);
#endif
json_char * json_strip_white_space(json_const json_char * json); json_char * json_strip_white_space(json_const json_char * json);
#ifdef JSON_VALIDATE #ifdef JSON_VALIDATE
JSONNODE * json_validate(json_const json_char * jso #ifdef JSON_DEPRECATED_FUNCTIONS
n); JSONNODE * json_deprecated(json_validate(jso
n_const json_char * json), "json_validate is deprecated, use json_is_valid
and json_parse instead");
#endif
json_bool_t json_is_valid(json_const json_char * js
on);
json_bool_t json_is_valid_unformatted(json_const js
on_char * json);
#endif #endif
#if defined JSON_DEBUG && !defined JSON_STDERROR #if defined JSON_DEBUG && !defined JSON_STDERROR
//When libjson errors, a callback allows the user t o know what went wrong /* When libjson errors, a callback allows the user to know what went wrong */
void json_register_debug_callback(json_error_callba ck_t callback); void json_register_debug_callback(json_error_callba ck_t callback);
#endif #endif
#ifdef JSON_MUTEX_CALLBACKS #ifdef JSON_MUTEX_CALLBACKS
#ifdef JSON_MUTEX_MANAGE #ifdef JSON_MUTEX_MANAGE
void json_register_mutex_callbacks(json_mute x_callback_t lock, json_mutex_callback_t unlock, json_mutex_callback_t dest roy, void * manager_lock); void json_register_mutex_callbacks(json_mute x_callback_t lock, json_mutex_callback_t unlock, json_mutex_callback_t dest roy, void * manager_lock);
#else #else
void json_register_mutex_callbacks(json_mute x_callback_t lock, json_mutex_callback_t unlock, void * manager_lock); void json_register_mutex_callbacks(json_mute x_callback_t lock, json_mutex_callback_t unlock, void * manager_lock);
#endif #endif
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
JSONSTREAM * json_new_stream(json_stream_callback_t
callback);
void json_stream_push(JSONSTREAM * stream, json_con
st json_char * addendum);
void json_delete_stream(JSONSTREAM * stream);
#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, long va lue);
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, long 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); long 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); JSONNODE * json_as_node(json_const JSONNODE * node);
JSONNODE * json_as_array(json_const JSONNODE * node); JSONNODE * json_as_array(json_const JSONNODE * node);
#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_WRITER #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);
#ifdef JSON_COMMENTS #ifdef JSON_COMMENTS
void json_set_comment(JSONNODE * node, json_const j son_char * comment); void json_set_comment(JSONNODE * node, json_const j son_char * comment);
#endif #endif
void json_clear(JSONNODE * node); void json_clear(JSONNODE * node);
void json_nullify(JSONNODE * node); void json_nullify(JSONNODE * node);
void json_swap(JSONNODE * node, JSONNODE * node2); void json_swap(JSONNODE * node, JSONNODE * node2);
void json_merge(JSONNODE * node, JSONNODE * node2); void json_merge(JSONNODE * node, JSONNODE * node2);
#ifndef JSON_PREPARSE #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
json_char * json_encode64(json_const void * binary,
json_index_t bytes);
void * json_decode64(json_const json_char * text, u
nsigned long * size);
#endif
void json_cast(JSONNODE * node, char type); void json_cast(JSONNODE * node, char type);
//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);
JSONNODE * json_pop_back_at(JSONNODE * node, json_index_t pos); JSONNODE * json_pop_back_at(JSONNODE * node, json_index_t pos);
JSONNODE * json_pop_back(JSONNODE * node, json_const json_ char * name); JSONNODE * json_pop_back(JSONNODE * node, json_const json_ char * name);
#ifdef JSON_ITERATORS #ifdef JSON_ITERATORS
JSONNODE_ITERATOR json_find(JSONNODE * node, json_c onst json_char * name); JSONNODE_ITERATOR json_find(JSONNODE * node, json_c onst json_char * name);
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
JSONNODE_ITERATOR json_find_nocase(JSONNODE * node, json_const json_char * name); JSONNODE_ITERATOR json_find_nocase(JSONNODE * node, json_const json_char * name);
#endif #endif
JSONNODE_ITERATOR json_erase(JSONNODE * node, JSONN ODE_ITERATOR it); JSONNODE_ITERATOR json_erase(JSONNODE * node, JSONN ODE_ITERATOR it);
JSONNODE_ITERATOR json_erase_multi(JSONNODE * node, JSONNODE_ITERATOR start, JSONNODE_ITERATOR end); JSONNODE_ITERATOR json_erase_multi(JSONNODE * node, JSONNODE_ITERATOR start, JSONNODE_ITERATOR end);
JSONNODE_ITERATOR json_insert(JSONNODE * node, JSON NODE_ITERATOR it, JSONNODE * node2); JSONNODE_ITERATOR json_insert(JSONNODE * node, JSON NODE_ITERATOR it, JSONNODE * node2);
JSONNODE_ITERATOR json_insert_multi(JSONNODE * node , JSONNODE_ITERATOR it, JSONNODE_ITERATOR start, JSONNODE_ITERATOR end); JSONNODE_ITERATOR json_insert_multi(JSONNODE * node , JSONNODE_ITERATOR it, JSONNODE_ITERATOR start, JSONNODE_ITERATOR end);
//iterator functions /* iterator functions */
JSONNODE_ITERATOR json_begin(JSONNODE * node); JSONNODE_ITERATOR json_begin(JSONNODE * node);
JSONNODE_ITERATOR json_end(JSONNODE * node); JSONNODE_ITERATOR json_end(JSONNODE * node);
#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 Using the non-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/JSONStream.h"
#ifdef JSON_EXPOSE_BASE64
#include "JSON_Base64.h"
#endif
#include <stdexcept> //some methods throw exceptions #include <stdexcept> //some methods throw exceptions
namespace libjson { namespace libjson {
//if json is invalid, it throws a std::invalid_argument exception #ifdef JSON_EXPOSE_BASE64
inline static JSONNode parse(const json_string & json){ inline static json_string encode64(const unsigned char * b
return JSONWorker::parse(json); inary, size_t bytes) json_nothrow json_cold {
} return JSONBase64::json_encode64(binary, bytes);
}
//useful if you have json that you don't want to parse, just want inline static std::string decode64(const json_string & enc
to strip to cut down on space oded) json_nothrow json_cold {
inline static json_string strip_white_space(const json_string & j return JSONBase64::json_decode64(encoded);
son){ }
return JSONWorker::RemoveWhiteSpaceAndComments(json); #endif
}
//if json is invalid, it throws a std::invalid_argument exception #ifdef JSON_READ_PRIORITY
(differs from parse because this checks the entire tree) //if json is invalid, it throws a std::invalid_argument ex
#ifdef JSON_VALIDATE ception
inline static JSONNode validate(const json_string & json){ inline static JSONNode parse(const json_string & json) jso
return JSONWorker::validate(json); n_throws(std::invalid_argument) {
return JSONWorker::parse(json);
} }
inline static JSONNode parse_unformatted(const json_string
& json) json_throws(std::invalid_argument) {
return JSONWorker::parse_unformatted(json);
}
#ifdef JSON_VALIDATE
inline static bool is_valid(const json_string & jso
n) json_nothrow {
return JSONValidator::isValidRoot(JSONWorker
::RemoveWhiteSpaceAndComments(json).c_str());
}
inline static bool is_valid_unformatted(const json_
string & json) json_nothrow {
return JSONValidator::isValidRoot(json.c_str
());
}
#ifdef JSON_DEPRECATED_FUNCTIONS
#ifdef JSON_NO_EXCEPTIONS
#error, JSON_DEPRECATED_FUNCTIONS requir
es JSON_NO_EXCEPTIONS be off
#endif
//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");
#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){ 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){ 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 {
JSONNode::register_mutex_callbacks(lock, unl ock, manager_lock); JSONNode::register_mutex_callbacks(lock, unl ock, manager_lock);
JSONNode::register_mutex_destructor(destroy) ; JSONNode::register_mutex_destructor(destroy) ;
} }
#else #else
inline static void register_mutex_callbacks(json_mu tex_callback_t lock, json_mutex_callback_t unlock, void * manager_lock){ inline static void register_mutex_callbacks(json_mu tex_callback_t lock, json_mutex_callback_t unlock, void * manager_lock) jso n_nothrow {
JSONNode::register_mutex_callbacks(lock, unl ock, manager_lock); JSONNode::register_mutex_callbacks(lock, unl ock, manager_lock);
} }
#endif #endif
inline static void set_global_mutex(void * mutex){ inline static void set_global_mutex(void * mutex) json_not hrow {
JSONNode::set_global_mutex(mutex); JSONNode::set_global_mutex(mutex);
} }
#endif #endif
#ifdef JSON_MEMORY_CALLBACKS #ifdef JSON_MEMORY_CALLBACKS
inline static void register_memory_callbacks(json_malloc_t mal, json_realloc_t real, json_free_t fre){ inline static void register_memory_callbacks(json_malloc_t mal, json_realloc_t real, json_free_t fre) json_nothrow {
JSONMemory::registerMemoryCallbacks(mal, real, fre) ; JSONMemory::registerMemoryCallbacks(mal, real, fre) ;
} }
#endif #endif
} }
#ifdef JSON_VALIDATE
#ifdef JSON_DEPRECATED_FUNCTIONS
//if json is invalid, it throws a std::invalid_argument ex
ception (differs from parse because this checks the entire tree)
inline static JSONNode libjson::validate(const json_string
& json) {
if (json_likely(is_valid(json))){
return parse(json);
}
throw std::invalid_argument("");
}
#endif
#endif
#endif //JSON_LIBRARY #endif //JSON_LIBRARY
#endif //LIBJSON_H #endif //LIBJSON_H
 End of changes. 28 change blocks. 
37 lines changed or deleted 116 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/