| 7a956470 |
sago007 |
2016-02-14 17:09 |
1 |
#ifndef RAPIDJSON_DOCUMENT_H_ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
2 |
#define RAPIDJSON_DOCUMENT_H_ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
3 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
4 |
#include "reader.h" |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
5 |
#include "internal/strfunc.h" |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
6 |
#include <new> // placement new |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
7 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
8 |
#ifdef _MSC_VER |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
9 |
#pragma warning(push) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
10 |
#pragma warning(disable : 4127) // conditional expression is constant |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
11 |
#endif |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
12 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
13 |
namespace rapidjson { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
14 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
15 |
/////////////////////////////////////////////////////////////////////////////// |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
16 |
// GenericValue |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
17 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
18 |
//! Represents a JSON value. Use Value for UTF8 encoding and default allocator. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
19 |
/*! |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
20 |
A JSON value can be one of 7 types. This class is a variant type supporting |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
21 |
these types. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
22 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
23 |
Use the Value if UTF8 and default allocator |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
24 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
25 |
\tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
26 |
\tparam Allocator Allocator type for allocating memory of object, array and string. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
27 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
28 |
#pragma pack (push, 4) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
29 |
template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
30 |
class GenericValue { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
31 |
public: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
32 |
//! Name-value pair in an object. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
33 |
struct Member { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
34 |
GenericValue<Encoding, Allocator> name; //!< name of member (must be a string) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
35 |
GenericValue<Encoding, Allocator> value; //!< value of member. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
36 |
}; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
37 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
38 |
typedef Encoding EncodingType; //!< Encoding type from template parameter. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
39 |
typedef Allocator AllocatorType; //!< Allocator type from template parameter. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
40 |
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
41 |
typedef Member* MemberIterator; //!< Member iterator for iterating in object. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
42 |
typedef const Member* ConstMemberIterator; //!< Constant member iterator for iterating in object. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
43 |
typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
44 |
typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
45 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
46 |
//!@name Constructors and destructor. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
47 |
//@{ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
48 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
49 |
//! Default constructor creates a null value. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
50 |
GenericValue() : flags_(kNull_Flag) {} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
51 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
52 |
//! Copy constructor is not permitted. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
53 |
private: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
54 |
GenericValue(const GenericValue& rhs); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
55 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
56 |
public: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
57 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
58 |
//! Constructor with JSON value type. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
59 |
/*! This creates a Value of specified type with default content. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
60 |
\param type Type of the value. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
61 |
\note Default content for number is zero. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
62 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
63 |
GenericValue(Type type) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
64 |
static const unsigned defaultFlags[7] = { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
65 |
kNull_Flag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
66 |
kNumberFlag | kIntFlag | kUintFlag | kInt64Flag | kUint64Flag | kDoubleFlag |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
67 |
}; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
68 |
RAPIDJSON_ASSERT(type <= kNumberType); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
69 |
flags_ = defaultFlags[type]; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
70 |
memset(&data_, 0, sizeof(data_)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
71 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
72 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
73 |
//! Constructor for boolean value. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
74 |
GenericValue(bool b) : flags_(b ? kTrueFlag : kFalseFlag) {} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
75 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
76 |
//! Constructor for int value. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
77 |
GenericValue(int i) : flags_(kNumberIntFlag) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
78 |
data_.n.i64 = i; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
79 |
if (i >= 0) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
80 |
flags_ |= kUintFlag | kUint64Flag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
81 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
82 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
83 |
//! Constructor for unsigned value. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
84 |
GenericValue(unsigned u) : flags_(kNumberUintFlag) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
85 |
data_.n.u64 = u; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
86 |
if (!(u & 0x80000000)) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
87 |
flags_ |= kIntFlag | kInt64Flag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
88 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
89 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
90 |
//! Constructor for int64_t value. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
91 |
GenericValue(int64_t i64) : flags_(kNumberInt64Flag) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
92 |
data_.n.i64 = i64; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
93 |
if (i64 >= 0) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
94 |
flags_ |= kNumberUint64Flag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
95 |
if (!(i64 & 0xFFFFFFFF00000000LL)) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
96 |
flags_ |= kUintFlag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
97 |
if (!(i64 & 0xFFFFFFFF80000000LL)) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
98 |
flags_ |= kIntFlag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
99 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
100 |
else if (i64 >= -2147483648LL) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
101 |
flags_ |= kIntFlag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
102 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
103 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
104 |
//! Constructor for uint64_t value. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
105 |
GenericValue(uint64_t u64) : flags_(kNumberUint64Flag) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
106 |
data_.n.u64 = u64; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
107 |
if (!(u64 & 0x8000000000000000ULL)) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
108 |
flags_ |= kInt64Flag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
109 |
if (!(u64 & 0xFFFFFFFF00000000ULL)) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
110 |
flags_ |= kUintFlag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
111 |
if (!(u64 & 0xFFFFFFFF80000000ULL)) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
112 |
flags_ |= kIntFlag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
113 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
114 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
115 |
//! Constructor for double value. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
116 |
GenericValue(double d) : flags_(kNumberDoubleFlag) { data_.n.d = d; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
117 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
118 |
//! Constructor for constant string (i.e. do not make a copy of string) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
119 |
GenericValue(const Ch* s, SizeType length) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
120 |
RAPIDJSON_ASSERT(s != NULL); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
121 |
flags_ = kConstStringFlag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
122 |
data_.s.str = s; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
123 |
data_.s.length = length; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
124 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
125 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
126 |
//! Constructor for constant string (i.e. do not make a copy of string) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
127 |
GenericValue(const Ch* s) { SetStringRaw(s, internal::StrLen(s)); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
128 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
129 |
//! Constructor for copy-string (i.e. do make a copy of string) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
130 |
GenericValue(const Ch* s, SizeType length, Allocator& allocator) { SetStringRaw(s, length, allocator); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
131 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
132 |
//! Constructor for copy-string (i.e. do make a copy of string) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
133 |
GenericValue(const Ch*s, Allocator& allocator) { SetStringRaw(s, internal::StrLen(s), allocator); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
134 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
135 |
//! Destructor. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
136 |
/*! Need to destruct elements of array, members of object, or copy-string. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
137 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
138 |
~GenericValue() { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
139 |
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
140 |
switch(flags_) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
141 |
case kArrayFlag: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
142 |
for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
143 |
v->~GenericValue(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
144 |
Allocator::Free(data_.a.elements); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
145 |
break; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
146 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
147 |
case kObjectFlag: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
148 |
for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
149 |
m->name.~GenericValue(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
150 |
m->value.~GenericValue(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
151 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
152 |
Allocator::Free(data_.o.members); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
153 |
break; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
154 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
155 |
case kCopyStringFlag: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
156 |
Allocator::Free(const_cast<Ch*>(data_.s.str)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
157 |
break; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
158 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
159 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
160 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
161 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
162 |
//@} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
163 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
164 |
//!@name Assignment operators |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
165 |
//@{ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
166 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
167 |
//! Assignment with move semantics. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
168 |
/*! \param rhs Source of the assignment. It will become a null value after assignment. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
169 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
170 |
GenericValue& operator=(GenericValue& rhs) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
171 |
RAPIDJSON_ASSERT(this != &rhs); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
172 |
this->~GenericValue(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
173 |
memcpy(this, &rhs, sizeof(GenericValue)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
174 |
rhs.flags_ = kNull_Flag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
175 |
return *this; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
176 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
177 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
178 |
//! Assignment with primitive types. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
179 |
/*! \tparam T Either Type, int, unsigned, int64_t, uint64_t, const Ch* |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
180 |
\param value The value to be assigned. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
181 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
182 |
template <typename T> |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
183 |
GenericValue& operator=(T value) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
184 |
this->~GenericValue(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
185 |
new (this) GenericValue(value); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
186 |
return *this; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
187 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
188 |
//@} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
189 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
190 |
//!@name Type |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
191 |
//@{ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
192 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
193 |
Type GetType() const { return static_cast<Type>(flags_ & kTypeMask); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
194 |
bool IsNull_() const { return flags_ == kNull_Flag; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
195 |
bool IsFalse() const { return flags_ == kFalseFlag; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
196 |
bool IsTrue() const { return flags_ == kTrueFlag; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
197 |
bool IsBool_() const { return (flags_ & kBool_Flag) != 0; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
198 |
bool IsObject() const { return flags_ == kObjectFlag; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
199 |
bool IsArray() const { return flags_ == kArrayFlag; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
200 |
bool IsNumber() const { return (flags_ & kNumberFlag) != 0; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
201 |
bool IsInt() const { return (flags_ & kIntFlag) != 0; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
202 |
bool IsUint() const { return (flags_ & kUintFlag) != 0; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
203 |
bool IsInt64() const { return (flags_ & kInt64Flag) != 0; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
204 |
bool IsUint64() const { return (flags_ & kUint64Flag) != 0; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
205 |
bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
206 |
bool IsString() const { return (flags_ & kStringFlag) != 0; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
207 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
208 |
//@} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
209 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
210 |
//!@name Null_ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
211 |
//@{ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
212 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
213 |
GenericValue& SetNull_() { this->~GenericValue(); new (this) GenericValue(); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
214 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
215 |
//@} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
216 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
217 |
//!@name Bool_ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
218 |
//@{ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
219 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
220 |
bool GetBool_() const { RAPIDJSON_ASSERT(IsBool_()); return flags_ == kTrueFlag; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
221 |
GenericValue& SetBool_(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
222 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
223 |
//@} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
224 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
225 |
//!@name Object |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
226 |
//@{ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
227 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
228 |
//! Set this value as an empty object. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
229 |
GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
230 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
231 |
//! Get the value associated with the object's name. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
232 |
GenericValue& operator[](const Ch* name) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
233 |
if (Member* member = FindMember(name)) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
234 |
return member->value; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
235 |
else { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
236 |
static GenericValue Null_Value; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
237 |
return Null_Value; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
238 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
239 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
240 |
const GenericValue& operator[](const Ch* name) const { return const_cast<GenericValue&>(*this)[name]; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
241 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
242 |
//! Member iterators. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
243 |
ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
244 |
ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
245 |
MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
246 |
MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
247 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
248 |
//! Check whether a member exists in the object. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
249 |
bool HasMember(const Ch* name) const { return FindMember(name) != 0; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
250 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
251 |
//! Add a member (name-value pair) to the object. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
252 |
/*! \param name A string value as name of member. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
253 |
\param value Value of any type. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
254 |
\param allocator Allocator for reallocating memory. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
255 |
\return The value itself for fluent API. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
256 |
\note The ownership of name and value will be transfered to this object if success. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
257 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
258 |
GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
259 |
RAPIDJSON_ASSERT(IsObject()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
260 |
RAPIDJSON_ASSERT(name.IsString()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
261 |
Object& o = data_.o; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
262 |
if (o.size >= o.capacity) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
263 |
if (o.capacity == 0) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
264 |
o.capacity = kDefaultObjectCapacity; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
265 |
o.members = (Member*)allocator.Malloc(o.capacity * sizeof(Member)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
266 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
267 |
else { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
268 |
SizeType oldCapacity = o.capacity; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
269 |
o.capacity *= 2; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
270 |
o.members = (Member*)allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
271 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
272 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
273 |
o.members[o.size].name.RawAssign(name); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
274 |
o.members[o.size].value.RawAssign(value); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
275 |
o.size++; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
276 |
return *this; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
277 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
278 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
279 |
GenericValue& AddMember(const Ch* name, Allocator& nameAllocator, GenericValue& value, Allocator& allocator) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
280 |
GenericValue n(name, internal::StrLen(name), nameAllocator); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
281 |
return AddMember(n, value, allocator); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
282 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
283 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
284 |
GenericValue& AddMember(const Ch* name, GenericValue& value, Allocator& allocator) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
285 |
GenericValue n(name, internal::StrLen(name)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
286 |
return AddMember(n, value, allocator); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
287 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
288 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
289 |
template <typename T> |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
290 |
GenericValue& AddMember(const Ch* name, T value, Allocator& allocator) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
291 |
GenericValue n(name, internal::StrLen(name)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
292 |
GenericValue v(value); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
293 |
return AddMember(n, v, allocator); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
294 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
295 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
296 |
//! Remove a member in object by its name. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
297 |
/*! \param name Name of member to be removed. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
298 |
\return Whether the member existed. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
299 |
\note Removing member is implemented by moving the last member. So the ordering of members is changed. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
300 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
301 |
bool RemoveMember(const Ch* name) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
302 |
RAPIDJSON_ASSERT(IsObject()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
303 |
if (Member* m = FindMember(name)) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
304 |
RAPIDJSON_ASSERT(data_.o.size > 0); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
305 |
RAPIDJSON_ASSERT(data_.o.members != 0); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
306 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
307 |
Member* last = data_.o.members + (data_.o.size - 1); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
308 |
if (data_.o.size > 1 && m != last) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
309 |
// Move the last one to this place |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
310 |
m->name = last->name; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
311 |
m->value = last->value; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
312 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
313 |
else { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
314 |
// Only one left, just destroy |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
315 |
m->name.~GenericValue(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
316 |
m->value.~GenericValue(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
317 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
318 |
--data_.o.size; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
319 |
return true; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
320 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
321 |
return false; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
322 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
323 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
324 |
//@} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
325 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
326 |
//!@name Array |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
327 |
//@{ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
328 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
329 |
//! Set this value as an empty array. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
330 |
GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
331 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
332 |
//! Get the number of elements in array. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
333 |
SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
334 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
335 |
//! Get the capacity of array. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
336 |
SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
337 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
338 |
//! Check whether the array is empty. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
339 |
bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
340 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
341 |
//! Remove all elements in the array. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
342 |
/*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
343 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
344 |
void Clear() { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
345 |
RAPIDJSON_ASSERT(IsArray()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
346 |
for (SizeType i = 0; i < data_.a.size; ++i) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
347 |
data_.a.elements[i].~GenericValue(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
348 |
data_.a.size = 0; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
349 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
350 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
351 |
//! Get an element from array by index. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
352 |
/*! \param index Zero-based index of element. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
353 |
\note |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
354 |
\code |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
355 |
Value a(kArrayType); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
356 |
a.PushBack(123); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
357 |
int x = a[0].GetInt(); // Error: operator[ is ambiguous, as 0 also mean a null pointer of const char* type. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
358 |
int y = a[SizeType(0)].GetInt(); // Cast to SizeType will work. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
359 |
int z = a[0u].GetInt(); // This works too. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
360 |
\endcode |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
361 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
362 |
GenericValue& operator[](SizeType index) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
363 |
RAPIDJSON_ASSERT(IsArray()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
364 |
RAPIDJSON_ASSERT(index < data_.a.size); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
365 |
return data_.a.elements[index]; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
366 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
367 |
const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
368 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
369 |
//! Element iterator |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
370 |
ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
371 |
ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
372 |
ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
373 |
ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
374 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
375 |
//! Request the array to have enough capacity to store elements. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
376 |
/*! \param newCapacity The capacity that the array at least need to have. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
377 |
\param allocator The allocator for allocating memory. It must be the same one use previously. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
378 |
\return The value itself for fluent API. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
379 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
380 |
GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
381 |
RAPIDJSON_ASSERT(IsArray()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
382 |
if (newCapacity > data_.a.capacity) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
383 |
data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
384 |
data_.a.capacity = newCapacity; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
385 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
386 |
return *this; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
387 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
388 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
389 |
//! Append a value at the end of the array. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
390 |
/*! \param value The value to be appended. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
391 |
\param allocator The allocator for allocating memory. It must be the same one use previously. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
392 |
\return The value itself for fluent API. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
393 |
\note The ownership of the value will be transfered to this object if success. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
394 |
\note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
395 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
396 |
GenericValue& PushBack(GenericValue& value, Allocator& allocator) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
397 |
RAPIDJSON_ASSERT(IsArray()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
398 |
if (data_.a.size >= data_.a.capacity) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
399 |
Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : data_.a.capacity * 2, allocator); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
400 |
data_.a.elements[data_.a.size++].RawAssign(value); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
401 |
return *this; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
402 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
403 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
404 |
template <typename T> |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
405 |
GenericValue& PushBack(T value, Allocator& allocator) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
406 |
GenericValue v(value); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
407 |
return PushBack(v, allocator); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
408 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
409 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
410 |
//! Remove the last element in the array. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
411 |
GenericValue& PopBack() { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
412 |
RAPIDJSON_ASSERT(IsArray()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
413 |
RAPIDJSON_ASSERT(!Empty()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
414 |
data_.a.elements[--data_.a.size].~GenericValue(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
415 |
return *this; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
416 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
417 |
//@} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
418 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
419 |
//!@name Number |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
420 |
//@{ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
421 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
422 |
int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
423 |
unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
424 |
int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
425 |
uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
426 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
427 |
double GetDouble() const { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
428 |
RAPIDJSON_ASSERT(IsNumber()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
429 |
if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
430 |
if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
431 |
if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
432 |
if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
433 |
RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
434 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
435 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
436 |
GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
437 |
GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
438 |
GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
439 |
GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
440 |
GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
441 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
442 |
//@} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
443 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
444 |
//!@name String |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
445 |
//@{ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
446 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
447 |
const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return data_.s.str; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
448 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
449 |
//! Get the length of string. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
450 |
/*! Since rapidjson permits "\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
451 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
452 |
SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return data_.s.length; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
453 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
454 |
//! Set this value as a string without copying source string. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
455 |
/*! This version has better performance with supplied length, and also support string containing null character. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
456 |
\param s source string pointer. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
457 |
\param length The length of source string, excluding the trailing null terminator. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
458 |
\return The value itself for fluent API. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
459 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
460 |
GenericValue& SetString(const Ch* s, SizeType length) { this->~GenericValue(); SetStringRaw(s, length); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
461 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
462 |
//! Set this value as a string without copying source string. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
463 |
/*! \param s source string pointer. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
464 |
\return The value itself for fluent API. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
465 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
466 |
GenericValue& SetString(const Ch* s) { return SetString(s, internal::StrLen(s)); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
467 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
468 |
//! Set this value as a string by copying from source string. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
469 |
/*! This version has better performance with supplied length, and also support string containing null character. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
470 |
\param s source string. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
471 |
\param length The length of source string, excluding the trailing null terminator. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
472 |
\param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator(). |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
473 |
\return The value itself for fluent API. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
474 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
475 |
GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, length, allocator); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
476 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
477 |
//! Set this value as a string by copying from source string. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
478 |
/*! \param s source string. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
479 |
\param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator(). |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
480 |
\return The value itself for fluent API. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
481 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
482 |
GenericValue& SetString(const Ch* s, Allocator& allocator) { SetString(s, internal::StrLen(s), allocator); return *this; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
483 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
484 |
//@} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
485 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
486 |
//! Generate events of this value to a Handler. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
487 |
/*! This function adopts the GoF visitor pattern. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
488 |
Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
489 |
It can also be used to deep clone this value via GenericDocument, which is also a Handler. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
490 |
\tparam Handler type of handler. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
491 |
\param handler An object implementing concept Handler. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
492 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
493 |
template <typename Handler> |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
494 |
const GenericValue& Accept(Handler& handler) const { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
495 |
switch(GetType()) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
496 |
case kNull_Type: handler.Null_(); break; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
497 |
case kFalseType: handler.Bool_(false); break; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
498 |
case kTrueType: handler.Bool_(true); break; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
499 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
500 |
case kObjectType: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
501 |
handler.StartObject(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
502 |
for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
503 |
handler.String(m->name.data_.s.str, m->name.data_.s.length, false); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
504 |
m->value.Accept(handler); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
505 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
506 |
handler.EndObject(data_.o.size); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
507 |
break; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
508 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
509 |
case kArrayType: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
510 |
handler.StartArray(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
511 |
for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
512 |
v->Accept(handler); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
513 |
handler.EndArray(data_.a.size); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
514 |
break; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
515 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
516 |
case kStringType: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
517 |
handler.String(data_.s.str, data_.s.length, false); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
518 |
break; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
519 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
520 |
case kNumberType: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
521 |
if (IsInt()) handler.Int(data_.n.i.i); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
522 |
else if (IsUint()) handler.Uint(data_.n.u.u); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
523 |
else if (IsInt64()) handler.Int64(data_.n.i64); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
524 |
else if (IsUint64()) handler.Uint64(data_.n.u64); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
525 |
else handler.Double(data_.n.d); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
526 |
break; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
527 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
528 |
return *this; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
529 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
530 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
531 |
private: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
532 |
template <typename, typename> |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
533 |
friend class GenericDocument; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
534 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
535 |
enum { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
536 |
kBool_Flag = 0x100, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
537 |
kNumberFlag = 0x200, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
538 |
kIntFlag = 0x400, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
539 |
kUintFlag = 0x800, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
540 |
kInt64Flag = 0x1000, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
541 |
kUint64Flag = 0x2000, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
542 |
kDoubleFlag = 0x4000, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
543 |
kStringFlag = 0x100000, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
544 |
kCopyFlag = 0x200000, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
545 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
546 |
// Initial flags of different types. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
547 |
kNull_Flag = kNull_Type, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
548 |
kTrueFlag = kTrueType | kBool_Flag, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
549 |
kFalseFlag = kFalseType | kBool_Flag, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
550 |
kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
551 |
kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
552 |
kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
553 |
kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
554 |
kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
555 |
kConstStringFlag = kStringType | kStringFlag, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
556 |
kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
557 |
kObjectFlag = kObjectType, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
558 |
kArrayFlag = kArrayType, |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
559 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
560 |
kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
561 |
}; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
562 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
563 |
static const SizeType kDefaultArrayCapacity = 16; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
564 |
static const SizeType kDefaultObjectCapacity = 16; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
565 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
566 |
struct String { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
567 |
const Ch* str; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
568 |
SizeType length; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
569 |
unsigned hashcode; //!< reserved |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
570 |
}; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
571 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
572 |
// By using proper binary layout, retrieval of different integer types do not need conversions. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
573 |
union Number { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
574 |
#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
575 |
struct I { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
576 |
int i; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
577 |
char padding[4]; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
578 |
}i; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
579 |
struct U { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
580 |
unsigned u; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
581 |
char padding2[4]; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
582 |
}u; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
583 |
#else |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
584 |
struct I { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
585 |
char padding[4]; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
586 |
int i; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
587 |
}i; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
588 |
struct U { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
589 |
char padding2[4]; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
590 |
unsigned u; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
591 |
}u; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
592 |
#endif |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
593 |
int64_t i64; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
594 |
uint64_t u64; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
595 |
double d; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
596 |
}; // 8 bytes |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
597 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
598 |
struct Object { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
599 |
Member* members; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
600 |
SizeType size; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
601 |
SizeType capacity; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
602 |
}; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
603 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
604 |
struct Array { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
605 |
GenericValue<Encoding, Allocator>* elements; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
606 |
SizeType size; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
607 |
SizeType capacity; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
608 |
}; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
609 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
610 |
union Data { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
611 |
String s; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
612 |
Number n; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
613 |
Object o; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
614 |
Array a; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
615 |
}; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
616 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
617 |
//! Find member by name. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
618 |
Member* FindMember(const Ch* name) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
619 |
RAPIDJSON_ASSERT(name); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
620 |
RAPIDJSON_ASSERT(IsObject()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
621 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
622 |
SizeType length = internal::StrLen(name); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
623 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
624 |
Object& o = data_.o; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
625 |
for (Member* member = o.members; member != data_.o.members + data_.o.size; ++member) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
626 |
if (length == member->name.data_.s.length && memcmp(member->name.data_.s.str, name, length * sizeof(Ch)) == 0) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
627 |
return member; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
628 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
629 |
return 0; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
630 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
631 |
const Member* FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
632 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
633 |
// Initialize this value as array with initial data, without calling destructor. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
634 |
void SetArrayRaw(GenericValue* values, SizeType count, Allocator& alloctaor) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
635 |
flags_ = kArrayFlag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
636 |
data_.a.elements = (GenericValue*)alloctaor.Malloc(count * sizeof(GenericValue)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
637 |
memcpy(data_.a.elements, values, count * sizeof(GenericValue)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
638 |
data_.a.size = data_.a.capacity = count; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
639 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
640 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
641 |
//! Initialize this value as object with initial data, without calling destructor. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
642 |
void SetObjectRaw(Member* members, SizeType count, Allocator& alloctaor) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
643 |
flags_ = kObjectFlag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
644 |
data_.o.members = (Member*)alloctaor.Malloc(count * sizeof(Member)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
645 |
memcpy(data_.o.members, members, count * sizeof(Member)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
646 |
data_.o.size = data_.o.capacity = count; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
647 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
648 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
649 |
//! Initialize this value as constant string, without calling destructor. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
650 |
void SetStringRaw(const Ch* s, SizeType length) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
651 |
RAPIDJSON_ASSERT(s != NULL); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
652 |
flags_ = kConstStringFlag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
653 |
data_.s.str = s; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
654 |
data_.s.length = length; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
655 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
656 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
657 |
//! Initialize this value as copy string with initial data, without calling destructor. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
658 |
void SetStringRaw(const Ch* s, SizeType length, Allocator& allocator) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
659 |
RAPIDJSON_ASSERT(s != NULL); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
660 |
flags_ = kCopyStringFlag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
661 |
data_.s.str = (Ch *)allocator.Malloc((length + 1) * sizeof(Ch)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
662 |
data_.s.length = length; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
663 |
memcpy(const_cast<Ch*>(data_.s.str), s, length * sizeof(Ch)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
664 |
const_cast<Ch*>(data_.s.str)[length] = '\0'; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
665 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
666 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
667 |
//! Assignment without calling destructor |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
668 |
void RawAssign(GenericValue& rhs) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
669 |
memcpy(this, &rhs, sizeof(GenericValue)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
670 |
rhs.flags_ = kNull_Flag; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
671 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
672 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
673 |
Data data_; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
674 |
unsigned flags_; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
675 |
}; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
676 |
#pragma pack (pop) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
677 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
678 |
//! Value with UTF8 encoding. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
679 |
typedef GenericValue<UTF8<> > Value; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
680 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
681 |
/////////////////////////////////////////////////////////////////////////////// |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
682 |
// GenericDocument |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
683 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
684 |
//! A document for parsing JSON text as DOM. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
685 |
/*! |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
686 |
\implements Handler |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
687 |
\tparam Encoding encoding for both parsing and string storage. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
688 |
\tparam Alloactor allocator for allocating memory for the DOM, and the stack during parsing. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
689 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
690 |
template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
691 |
class GenericDocument : public GenericValue<Encoding, Allocator> { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
692 |
public: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
693 |
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
694 |
typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
695 |
typedef Allocator AllocatorType; //!< Allocator type from template parameter. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
696 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
697 |
//! Constructor |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
698 |
/*! \param allocator Optional allocator for allocating stack memory. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
699 |
\param stackCapacity Initial capacity of stack in bytes. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
700 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
701 |
GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
702 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
703 |
//! Parse JSON text from an input stream. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
704 |
/*! \tparam parseFlags Combination of ParseFlag. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
705 |
\param stream Input stream to be parsed. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
706 |
\return The document itself for fluent API. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
707 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
708 |
template <unsigned parseFlags, typename Stream> |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
709 |
GenericDocument& ParseStream(Stream& stream) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
710 |
ValueType::SetNull_(); // Remove existing root if exist |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
711 |
GenericReader<Encoding, Allocator> reader; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
712 |
if (reader.template Parse<parseFlags>(stream, *this)) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
713 |
RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
714 |
this->RawAssign(*stack_.template Pop<ValueType>(1)); // Add this-> to prevent issue 13. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
715 |
parseError_ = 0; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
716 |
errorOffset_ = 0; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
717 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
718 |
else { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
719 |
parseError_ = reader.GetParseError(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
720 |
errorOffset_ = reader.GetErrorOffset(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
721 |
ClearStack(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
722 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
723 |
return *this; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
724 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
725 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
726 |
//! Parse JSON text from a mutable string. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
727 |
/*! \tparam parseFlags Combination of ParseFlag. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
728 |
\param str Mutable zero-terminated string to be parsed. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
729 |
\return The document itself for fluent API. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
730 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
731 |
template <unsigned parseFlags> |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
732 |
GenericDocument& ParseInsitu(Ch* str) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
733 |
GenericInsituStringStream<Encoding> s(str); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
734 |
return ParseStream<parseFlags | kParseInsituFlag>(s); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
735 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
736 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
737 |
//! Parse JSON text from a read-only string. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
738 |
/*! \tparam parseFlags Combination of ParseFlag (must not contain kParseInsituFlag). |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
739 |
\param str Read-only zero-terminated string to be parsed. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
740 |
*/ |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
741 |
template <unsigned parseFlags> |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
742 |
GenericDocument& Parse(const Ch* str) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
743 |
RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
744 |
GenericStringStream<Encoding> s(str); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
745 |
return ParseStream<parseFlags>(s); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
746 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
747 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
748 |
//! Whether a parse error was occured in the last parsing. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
749 |
bool HasParseError() const { return parseError_ != 0; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
750 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
751 |
//! Get the message of parsing error. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
752 |
const char* GetParseError() const { return parseError_; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
753 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
754 |
//! Get the offset in character of the parsing error. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
755 |
size_t GetErrorOffset() const { return errorOffset_; } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
756 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
757 |
//! Get the allocator of this document. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
758 |
Allocator& GetAllocator() { return stack_.GetAllocator(); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
759 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
760 |
//! Get the capacity of stack in bytes. |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
761 |
size_t GetStackCapacity() const { return stack_.GetCapacity(); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
762 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
763 |
private: |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
764 |
// Prohibit assignment |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
765 |
GenericDocument& operator=(const GenericDocument&); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
766 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
767 |
friend class GenericReader<Encoding, Allocator>; // for Reader to call the following private handler functions |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
768 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
769 |
// Implementation of Handler |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
770 |
void Null_() { new (stack_.template Push<ValueType>()) ValueType(); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
771 |
void Bool_(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
772 |
void Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
773 |
void Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
774 |
void Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
775 |
void Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
776 |
void Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
777 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
778 |
void String(const Ch* str, SizeType length, bool copy) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
779 |
if (copy) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
780 |
new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
781 |
else |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
782 |
new (stack_.template Push<ValueType>()) ValueType(str, length); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
783 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
784 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
785 |
void StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
786 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
787 |
void EndObject(SizeType memberCount) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
788 |
typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
789 |
stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
790 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
791 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
792 |
void StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); } |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
793 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
794 |
void EndArray(SizeType elementCount) { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
795 |
ValueType* elements = stack_.template Pop<ValueType>(elementCount); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
796 |
stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator()); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
797 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
798 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
799 |
void ClearStack() { |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
800 |
if (Allocator::kNeedFree) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
801 |
while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
802 |
(stack_.template Pop<ValueType>(1))->~ValueType(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
803 |
else |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
804 |
stack_.Clear(); |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
805 |
} |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
806 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
807 |
static const size_t kDefaultStackCapacity = 1024; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
808 |
internal::Stack<Allocator> stack_; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
809 |
const char* parseError_; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
810 |
size_t errorOffset_; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
811 |
}; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
812 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
813 |
typedef GenericDocument<UTF8<> > Document; |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
814 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
815 |
} // namespace rapidjson |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
816 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
817 |
#ifdef _MSC_VER |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
818 |
#pragma warning(pop) |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
819 |
#endif |
| 7a956470 |
sago007 |
2016-02-14 17:09 |
820 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
821 |
#endif // RAPIDJSON_DOCUMENT_H_ |
|
|
1970-01-01 00:00 |
822 |
|