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