1 #ifndef INTERNAL_JSONNODE_H
2 #define INTERNAL_JSONNODE_H
5 #include "JSONChildren.h"
6 #include "JSONMemory.h"
7 #include "JSONGlobals.h"
11 #include "JSONSharedString.h"
13 #ifdef JSON_LESS_MEMORY
17 #pragma pack(push, internalJSONNode_pack, 1)
33 #define DECL_SET_INTEGER(type) void Set(type) json_nothrow json_write_priority; void Set(unsigned type) json_nothrow json_write_priority;
34 #define DECL_CAST_OP(type) operator type() const json_nothrow; operator unsigned type() const json_nothrow;
37 #ifdef JSON_MUTEX_CALLBACKS
38 #define initializeMutex(x) ,mylock(x)
40 #define initializeMutex(x)
43 #if defined(JSON_PREPARSE) || !defined(JSON_READ_PRIORITY)
44 #define SetFetched(b) (void)0
45 #define Fetch() (void)0
46 #define initializeFetch(x)
48 #define initializeFetch(x) ,fetched(x)
52 #define initializeRefCount(x) ,refcount(x)
54 #define initializeRefCount(x)
58 #define initializeComment(x) ,_comment(x)
60 #define initializeComment(x)
63 #ifdef JSON_LESS_MEMORY
64 #define CHILDREN _value.Children
65 #define DELETE_CHILDREN()\
67 jsonChildren::deleteChildren(CHILDREN);\
69 #define CHILDREN_TO_NULL() (void)0
70 #define initializeChildren(x)
72 #define CHILDREN Children
73 #define DELETE_CHILDREN()\
74 if (CHILDREN != 0) jsonChildren::deleteChildren(CHILDREN);
75 #define CHILDREN_TO_NULL() CHILDREN = 0
76 #define makeNotContainer() (void)0
77 #define makeContainer() if (!CHILDREN) CHILDREN = jsonChildren::newChildren()
78 #define initializeChildren(x) ,CHILDREN(x)
81 class internalJSONNode {
83 LIBJSON_OBJECT(internalJSONNode);
84 internalJSONNode(
char mytype = JSON_NULL) json_nothrow json_hot;
85 #ifdef JSON_READ_PRIORITY
86 internalJSONNode(
const json_string & unparsed) json_nothrow json_hot;
87 internalJSONNode(
const json_string & name_t,
const json_string & value_t) json_nothrow json_read_priority;
89 internalJSONNode(
const internalJSONNode & orig) json_nothrow json_hot;
90 internalJSONNode & operator = (
const internalJSONNode &) json_nothrow json_hot;
91 ~internalJSONNode(
void) json_nothrow json_hot;
93 static internalJSONNode * newInternal(
char mytype = JSON_NULL) json_hot;
94 #ifdef JSON_READ_PRIORITY
95 static internalJSONNode * newInternal(
const json_string & unparsed) json_hot;
96 static internalJSONNode * newInternal(
const json_string & name_t,
const json_string & value_t) json_hot;
98 static internalJSONNode * newInternal(
const internalJSONNode & orig) json_hot;
99 static void deleteInternal(internalJSONNode * ptr) json_nothrow json_hot;
101 json_index_t size(
void) const json_nothrow json_read_priority;
102 bool empty(
void) const json_nothrow;
103 unsigned char type(
void) const json_nothrow json_read_priority;
105 json_string name(
void) const json_nothrow json_read_priority;
106 void setname(const json_string & newname) json_nothrow json_write_priority;
108 void setcomment(
const json_string & comment) json_nothrow;
109 json_string getcomment(
void) const json_nothrow;
112 #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
113 void preparse(
void) json_nothrow;
117 void push_back(JSONNode * node) json_nothrow;
119 void push_back(
const JSONNode & node) json_nothrow;
121 void reserve(json_index_t siz) json_nothrow;
122 void push_front(
const JSONNode & node) json_nothrow;
123 JSONNode * pop_back(json_index_t pos) json_nothrow;
124 JSONNode * pop_back(
const json_string & name_t) json_nothrow;
125 #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
126 JSONNode * pop_back_nocase(
const json_string & name_t) json_nothrow;
129 JSONNode * at(json_index_t pos) json_nothrow;
131 JSONNode ** at(
const json_string & name_t) json_nothrow;
132 #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
133 JSONNode ** at_nocase(
const json_string & name_t) json_nothrow;
136 void Set(
const json_string & val) json_nothrow json_write_priority;
138 void Set(json_number val) json_nothrow json_write_priority;
139 void Set(json_int_t val) json_nothrow json_write_priority;
140 operator json_int_t() const json_nothrow;
141 operator json_number() const json_nothrow;
143 DECL_SET_INTEGER(
char)
144 DECL_SET_INTEGER(
short)
145 DECL_SET_INTEGER(
int)
146 DECL_SET_INTEGER(
long)
147 #ifndef JSON_ISO_STRICT
148 DECL_SET_INTEGER(
long long)
149 void Set(
long double val) json_nothrow json_write_priority;
151 void Set(
float val) json_nothrow json_write_priority;
152 void Set(
double val) json_nothrow json_write_priority;
159 #ifndef JSON_ISO_STRICT
160 DECL_CAST_OP(
long long)
161 operator long double() const json_nothrow;
163 operator float() const json_nothrow;
164 operator
double() const json_nothrow;
166 operator json_string()const json_nothrow;
167 operator
bool() const json_nothrow;
168 void Set(
bool val) json_nothrow;
170 bool IsEqualTo(const json_string & val) const json_nothrow;
171 bool IsEqualTo(
bool val) const json_nothrow;
172 bool IsEqualTo(const internalJSONNode * val) const json_nothrow;
175 bool IsEqualToNum(T val) const json_nothrow;
177 internalJSONNode * incRef(
void) json_nothrow;
178 #ifdef JSON_REF_COUNT
179 void decRef(
void) json_nothrow json_hot;
180 bool hasNoReferences(
void) json_nothrow json_hot;
182 internalJSONNode * makeUnique(
void) json_nothrow json_hot;
184 JSONNode ** begin(
void) const json_nothrow;
185 JSONNode ** end(
void) const json_nothrow;
186 bool Fetched(
void) const json_nothrow json_hot;
187 #ifdef JSON_MUTEX_CALLBACKS
188 void _set_mutex(
void * mutex,
bool unset =
true) json_nothrow json_cold;
189 void _unset_mutex(
void) json_nothrow json_cold;
192 #ifdef JSON_WRITE_PRIORITY
193 void DumpRawString(json_string & output)
const json_nothrow json_write_priority;
194 void WriteName(
bool formatted,
bool arrayChild, json_string & output)
const json_nothrow json_write_priority;
195 #ifdef JSON_ARRAY_SIZE_ON_ONE_LINE
196 void WriteChildrenOneLine(
unsigned int indent, json_string & output)
const json_nothrow json_write_priority;
198 void WriteChildren(
unsigned int indent, json_string & output)
const json_nothrow json_write_priority;
199 void WriteComment(
unsigned int indent, json_string & output)
const json_nothrow json_write_priority;
200 void Write(
unsigned int indent,
bool arrayChild, json_string & output)
const json_nothrow json_write_priority;
204 inline bool isContainer(
void) const json_nothrow {
205 return (_type == JSON_NODE || _type == JSON_ARRAY);
207 inline bool isNotContainer(
void) const json_nothrow {
208 return (_type != JSON_NODE && _type != JSON_ARRAY);
211 #ifdef JSON_LESS_MEMORY
212 inline void makeNotContainer(
void){
214 jsonChildren::deleteChildren(CHILDREN);
217 inline void makeContainer(
void){
218 if (isNotContainer()){
219 CHILDREN = jsonChildren::newChildren();
224 void Nullify(
void) const json_nothrow;
226 #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
227 void SetFetched(
bool val)
const json_nothrow json_hot;
228 void Fetch(
void) const json_nothrow json_hot;
231 #ifdef JSON_READ_PRIORITY
232 void FetchString(
void) const json_nothrow json_read_priority;
233 void FetchNode(
void) const json_nothrow json_read_priority;
234 void FetchArray(
void) const json_nothrow json_read_priority;
236 void FetchNumber(
void) const json_nothrow json_read_priority;
238 #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
239 static bool AreEqualNoCase(
const json_char * ch_one,
const json_char * ch_two) json_nothrow json_read_priority;
242 inline void clearname(
void) json_nothrow {
248 JSONNode Dump(
size_t & totalmemory)
const json_nothrow;
249 JSONNode DumpMutex(
void) const json_nothrow;
254 mutable unsigned char _type BITS(3);
257 mutable bool _name_encoded BITS(1);
259 mutable json_string _string;
260 mutable bool _string_encoded BITS(1);
263 union value_union_t {
266 #ifdef JSON_LESS_MEMORY
267 jsonChildren * Children;
270 mutable value_union_t _value;
272 #ifdef JSON_MUTEX_CALLBACKS
276 #ifdef JSON_REF_COUNT
277 size_t refcount PACKED(20);
280 #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
281 mutable bool fetched BITS(1);
285 json_string _comment;
288 #ifndef JSON_LESS_MEMORY
289 jsonChildren * CHILDREN;
293 inline internalJSONNode::internalJSONNode(
char mytype) json_nothrow : _type(mytype), _name(), _name_encoded(), _string(), _string_encoded(), _value()
295 initializeRefCount(1)
296 initializeFetch(true)
297 initializeComment(json_global(EMPTY_JSON_STRING))
298 initializeChildren((_type == JSON_NODE || _type == JSON_ARRAY) ? jsonChildren::newChildren() : 0){
302 #ifdef JSON_LESS_MEMORY
305 CHILDREN = jsonChildren::newChildren();
310 inline internalJSONNode * internalJSONNode::incRef(
void) json_nothrow {
311 #ifdef JSON_REF_COUNT
319 inline json_index_t internalJSONNode::size(
void) const json_nothrow {
320 if (isNotContainer())
return 0;
322 return CHILDREN -> size();
325 inline bool internalJSONNode::empty(
void) const json_nothrow {
326 if (isNotContainer())
return true;
328 return CHILDREN -> empty();
331 inline unsigned char internalJSONNode::type(
void) const json_nothrow {
335 inline json_string internalJSONNode::name(
void) const json_nothrow {
339 inline void internalJSONNode::setname(
const json_string & newname) json_nothrow {
340 #ifdef JSON_LESS_MEMORY
341 JSON_ASSERT(newname.capacity() == newname.length(), JSON_TEXT(
"name object too large"));
344 _name_encoded =
true;
348 inline void internalJSONNode::setcomment(
const json_string & comment) json_nothrow {
352 inline json_string internalJSONNode::getcomment(
void) const json_nothrow {
357 inline bool internalJSONNode::IsEqualTo(
const json_string & val)
const json_nothrow {
358 if (type() != JSON_STRING)
return false;
360 return _string == val;
363 inline bool internalJSONNode::IsEqualTo(
bool val)
const json_nothrow {
364 if (type() != JSON_BOOL)
return false;
366 return val == _value._bool;
370 inline bool internalJSONNode::IsEqualToNum(T val)
const json_nothrow {
371 if (type() != JSON_NUMBER)
return false;
373 return (json_number)val == _value._number;
376 #ifdef JSON_REF_COUNT
377 inline void internalJSONNode::decRef(
void) json_nothrow {
378 JSON_ASSERT(refcount != 0, JSON_TEXT(
"decRef on a 0 refcount internal"));
382 inline bool internalJSONNode::hasNoReferences(
void) json_nothrow {
383 return refcount == 0;
387 inline internalJSONNode * internalJSONNode::makeUnique(
void) json_nothrow {
388 #ifdef JSON_REF_COUNT
391 return newInternal(*
this);
393 JSON_ASSERT(refcount == 1, JSON_TEXT(
"makeUnique on a 0 refcount internal"));
396 return newInternal(*
this);
400 #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
401 inline void internalJSONNode::SetFetched(
bool val)
const json_nothrow {
406 inline bool internalJSONNode::Fetched(
void) const json_nothrow {
407 #if !defined(JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
414 inline JSONNode ** internalJSONNode::begin(
void) const json_nothrow {
415 JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON_TEXT(
"begin"),
return 0;);
417 return CHILDREN -> begin();
420 inline JSONNode ** internalJSONNode::end(
void) const json_nothrow {
421 JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON_TEXT(
"end"),
return 0;);
423 return CHILDREN -> end();
426 inline JSONNode * internalJSONNode::at(json_index_t pos) json_nothrow {
427 JSON_ASSERT_SAFE(isContainer(), JSON_TEXT(
"calling at on non-container type"),
return 0;);
429 return (*CHILDREN)[pos];
432 #if defined(JSON_LESS_MEMORY) && defined(__GNUC__)
433 inline void internalJSONNode::reserve(json_index_t __attribute__((unused)) siz) json_nothrow
435 inline void internalJSONNode::reserve(json_index_t siz) json_nothrow
438 JSON_ASSERT_SAFE(isContainer(), json_global(ERROR_NON_CONTAINER) + JSON_TEXT(
"reserve"),
return;);
440 jsonChildren::reserve2(CHILDREN, siz);
449 #ifdef JSON_ISO_STRICT
450 #define BASE_CONVERT_TYPE long
452 #define BASE_CONVERT_TYPE long long
455 #define IMP_SMALLER_INT_CAST_OP(_type, type_max, type_min)\
456 inline internalJSONNode::operator _type() const json_nothrow {\
457 JSON_ASSERT(_value._number > type_min, _string + json_global(ERROR_LOWER_RANGE) + JSON_TEXT(#_type));\
458 JSON_ASSERT(_value._number < type_max, _string + json_global(ERROR_UPPER_RANGE) + JSON_TEXT(#_type));\
459 JSON_ASSERT(_value._number == (json_number)((_type)(_value._number)), json_string(JSON_TEXT("(")) + json_string(JSON_TEXT(#_type)) + json_string(JSON_TEXT(") will truncate ")) + _string);\
460 return (_type)static_cast<BASE_CONVERT_TYPE>(*this);\
463 IMP_SMALLER_INT_CAST_OP(
char, CHAR_MAX, CHAR_MIN)
464 IMP_SMALLER_INT_CAST_OP(
unsigned char, UCHAR_MAX, 0)
465 IMP_SMALLER_INT_CAST_OP(
short, SHRT_MAX, SHRT_MIN)
466 IMP_SMALLER_INT_CAST_OP(
unsigned short, USHRT_MAX, 0)
467 IMP_SMALLER_INT_CAST_OP(
int, INT_MAX, INT_MIN)
468 IMP_SMALLER_INT_CAST_OP(
unsigned int, UINT_MAX, 0)
470 #ifndef JSON_ISO_STRICT
471 IMP_SMALLER_INT_CAST_OP(
long, LONG_MAX, LONG_MIN)
472 IMP_SMALLER_INT_CAST_OP(
unsigned long, ULONG_MAX, 0)
476 inline internalJSONNode::operator json_string() const json_nothrow {
483 #ifndef JSON_ISO_STRICT
484 inline internalJSONNode::operator float() const json_nothrow {
485 return static_cast<float>(
static_cast<long double>(*this));
487 inline internalJSONNode::operator double() const json_nothrow {
488 return static_cast<double>(
static_cast<long double>(*this));
491 inline internalJSONNode::operator float() const json_nothrow {
492 return static_cast<float>(
static_cast<double>(*this));
497 #ifdef JSON_LESS_MEMORY
501 #pragma pack(pop, internalJSONNode_pack,)