1 #ifndef RAPIDJSON_DOCUMENT_H_
2 #define RAPIDJSON_DOCUMENT_H_
5 #include "internal/strfunc.h"
9 #pragma warning(disable : 4127) // conditional expression is constant
27 #pragma pack (push, 4)
28 template <
typename Encoding,
typename Allocator = MemoryPoolAllocator<> >
39 typedef typename Encoding::Ch
Ch;
63 static const unsigned defaultFlags[7] = {
64 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag,
65 kNumberFlag | kIntFlag | kUintFlag | kInt64Flag | kUint64Flag | kDoubleFlag
67 RAPIDJSON_ASSERT(type <= kNumberType);
68 flags_ = defaultFlags[type];
69 memset(&data_, 0,
sizeof(data_));
79 flags_ |= kUintFlag | kUint64Flag;
85 if (!(u & 0x80000000))
86 flags_ |= kIntFlag | kInt64Flag;
93 flags_ |= kNumberUint64Flag;
94 if (!(i64 & 0xFFFFFFFF00000000LL))
96 if (!(i64 & 0xFFFFFFFF80000000LL))
99 else if (i64 >= -2147483648LL)
106 if (!(u64 & 0x8000000000000000ULL))
107 flags_ |= kInt64Flag;
108 if (!(u64 & 0xFFFFFFFF00000000ULL))
110 if (!(u64 & 0xFFFFFFFF80000000ULL))
119 RAPIDJSON_ASSERT(s != NULL);
120 flags_ = kConstStringFlag;
122 data_.s.length = length;
138 if (Allocator::kNeedFree) {
141 for (
GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
143 Allocator::Free(data_.a.elements);
147 for (
Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) {
148 m->name.~GenericValue();
149 m->value.~GenericValue();
151 Allocator::Free(data_.o.members);
154 case kCopyStringFlag:
155 Allocator::Free(const_cast<Ch*>(data_.s.str));
170 RAPIDJSON_ASSERT(
this != &rhs);
173 rhs.flags_ = kNullFlag;
181 template <
typename T>
192 Type GetType()
const {
return static_cast<Type
>(flags_ & kTypeMask); }
193 bool IsNull()
const {
return flags_ == kNullFlag; }
194 bool IsFalse()
const {
return flags_ == kFalseFlag; }
195 bool IsTrue()
const {
return flags_ == kTrueFlag; }
196 bool IsBool()
const {
return (flags_ & kBoolFlag) != 0; }
197 bool IsObject()
const {
return flags_ == kObjectFlag; }
198 bool IsArray()
const {
return flags_ == kArrayFlag; }
199 bool IsNumber()
const {
return (flags_ & kNumberFlag) != 0; }
200 bool IsInt()
const {
return (flags_ & kIntFlag) != 0; }
201 bool IsUint()
const {
return (flags_ & kUintFlag) != 0; }
202 bool IsInt64()
const {
return (flags_ & kInt64Flag) != 0; }
203 bool IsUint64()
const {
return (flags_ & kUint64Flag) != 0; }
204 bool IsDouble()
const {
return (flags_ & kDoubleFlag) != 0; }
205 bool IsString()
const {
return (flags_ & kStringFlag) != 0; }
219 bool GetBool()
const { RAPIDJSON_ASSERT(IsBool());
return flags_ == kTrueFlag; }
232 if (
Member* member = FindMember(name))
233 return member->value;
243 ConstMemberIterator MemberEnd()
const { RAPIDJSON_ASSERT(IsObject());
return data_.o.members + data_.o.size; }
245 MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject());
return data_.o.members + data_.o.size; }
248 bool HasMember(
const Ch* name)
const {
return FindMember(name) != 0; }
258 RAPIDJSON_ASSERT(IsObject());
259 RAPIDJSON_ASSERT(name.IsString());
261 if (o.size >= o.capacity) {
262 if (o.capacity == 0) {
263 o.capacity = kDefaultObjectCapacity;
264 o.members = (
Member*)allocator.Malloc(o.capacity *
sizeof(
Member));
267 SizeType oldCapacity = o.capacity;
269 o.members = (
Member*)allocator.Realloc(o.members, oldCapacity *
sizeof(
Member), o.capacity *
sizeof(
Member));
272 o.members[o.size].name.RawAssign(name);
273 o.members[o.size].value.RawAssign(value);
279 GenericValue n(name, internal::StrLen(name), nameAllocator);
288 template <
typename T>
301 RAPIDJSON_ASSERT(IsObject());
302 if (
Member* m = FindMember(name)) {
303 RAPIDJSON_ASSERT(data_.o.size > 0);
304 RAPIDJSON_ASSERT(data_.o.members != 0);
306 Member* last = data_.o.members + (data_.o.size - 1);
307 if (data_.o.size > 1 && m != last) {
309 m->name = last->
name;
310 m->value = last->
value;
314 m->name.~GenericValue();
315 m->value.~GenericValue();
332 SizeType
Size()
const { RAPIDJSON_ASSERT(IsArray());
return data_.a.size; }
335 SizeType
Capacity()
const { RAPIDJSON_ASSERT(IsArray());
return data_.a.capacity; }
338 bool Empty()
const { RAPIDJSON_ASSERT(IsArray());
return data_.a.size == 0; }
344 RAPIDJSON_ASSERT(IsArray());
345 for (SizeType i = 0; i < data_.a.size; ++i)
346 data_.a.elements[i].~GenericValue();
362 RAPIDJSON_ASSERT(IsArray());
363 RAPIDJSON_ASSERT(index < data_.a.size);
364 return data_.a.elements[index];
370 ValueIterator End() { RAPIDJSON_ASSERT(IsArray());
return data_.a.elements + data_.a.size; }
380 RAPIDJSON_ASSERT(IsArray());
381 if (newCapacity > data_.a.capacity) {
383 data_.a.capacity = newCapacity;
396 RAPIDJSON_ASSERT(IsArray());
397 if (data_.a.size >= data_.a.capacity)
398 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : data_.a.capacity * 2, allocator);
399 data_.a.elements[data_.a.size++].RawAssign(value);
403 template <
typename T>
411 RAPIDJSON_ASSERT(IsArray());
412 RAPIDJSON_ASSERT(!
Empty());
413 data_.a.elements[--data_.a.size].~GenericValue();
421 int GetInt()
const { RAPIDJSON_ASSERT(flags_ & kIntFlag);
return data_.n.i.i; }
422 unsigned GetUint()
const { RAPIDJSON_ASSERT(flags_ & kUintFlag);
return data_.n.u.u; }
423 int64_t GetInt64()
const { RAPIDJSON_ASSERT(flags_ & kInt64Flag);
return data_.n.i64; }
424 uint64_t GetUint64()
const { RAPIDJSON_ASSERT(flags_ & kUint64Flag);
return data_.n.u64; }
426 double GetDouble()
const {
427 RAPIDJSON_ASSERT(IsNumber());
428 if ((flags_ & kDoubleFlag) != 0)
return data_.n.d;
429 if ((flags_ & kIntFlag) != 0)
return data_.n.i.i;
430 if ((flags_ & kUintFlag) != 0)
return data_.n.u.u;
431 if ((flags_ & kInt64Flag) != 0)
return (
double)data_.n.i64;
432 RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0);
return (
double)data_.n.u64;
446 const Ch* GetString()
const { RAPIDJSON_ASSERT(IsString());
return data_.s.str; }
451 SizeType
GetStringLength()
const { RAPIDJSON_ASSERT(IsString());
return data_.s.length; }
492 template <
typename Handler>
495 case kNullType: handler.Null();
break;
496 case kFalseType: handler.Bool(
false);
break;
497 case kTrueType: handler.Bool(
true);
break;
500 handler.StartObject();
501 for (
Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) {
502 handler.String(m->name.data_.s.str, m->name.data_.s.length,
false);
503 m->value.Accept(handler);
505 handler.EndObject(data_.o.size);
509 handler.StartArray();
510 for (
GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
512 handler.EndArray(data_.a.size);
516 handler.String(data_.s.str, data_.s.length,
false);
520 if (IsInt()) handler.Int(data_.n.i.i);
521 else if (IsUint()) handler.Uint(data_.n.u.u);
522 else if (IsInt64()) handler.Int64(data_.n.i64);
523 else if (IsUint64()) handler.Uint64(data_.n.u64);
524 else handler.Double(data_.n.d);
531 template <
typename,
typename>
540 kUint64Flag = 0x2000,
541 kDoubleFlag = 0x4000,
542 kStringFlag = 0x100000,
543 kCopyFlag = 0x200000,
546 kNullFlag = kNullType,
547 kTrueFlag = kTrueType | kBoolFlag,
548 kFalseFlag = kFalseType | kBoolFlag,
549 kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
550 kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
551 kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
552 kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
553 kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
554 kConstStringFlag = kStringType | kStringFlag,
555 kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
556 kObjectFlag = kObjectType,
557 kArrayFlag = kArrayType,
562 static const SizeType kDefaultArrayCapacity = 16;
563 static const SizeType kDefaultObjectCapacity = 16;
573 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
604 GenericValue<Encoding, Allocator>* elements;
617 Member* FindMember(
const Ch* name) {
618 RAPIDJSON_ASSERT(name);
619 RAPIDJSON_ASSERT(IsObject());
621 SizeType length = internal::StrLen(name);
624 for (Member* member = o.members; member != data_.o.members + data_.o.size; ++member)
625 if (length == member->name.data_.s.length && memcmp(member->name.data_.s.str, name, length *
sizeof(
Ch)) == 0)
630 const Member* FindMember(
const Ch* name)
const {
return const_cast<GenericValue&
>(*this).FindMember(name); }
633 void SetArrayRaw(
GenericValue* values, SizeType count, Allocator& alloctaor) {
636 memcpy(data_.a.elements, values, count *
sizeof(
GenericValue));
637 data_.a.size = data_.a.capacity = count;
641 void SetObjectRaw(Member* members, SizeType count, Allocator& alloctaor) {
642 flags_ = kObjectFlag;
643 data_.o.members = (Member*)alloctaor.Malloc(count *
sizeof(Member));
644 memcpy(data_.o.members, members, count *
sizeof(Member));
645 data_.o.size = data_.o.capacity = count;
649 void SetStringRaw(
const Ch* s, SizeType length) {
650 RAPIDJSON_ASSERT(s != NULL);
651 flags_ = kConstStringFlag;
653 data_.s.length = length;
657 void SetStringRaw(
const Ch* s, SizeType length, Allocator& allocator) {
658 RAPIDJSON_ASSERT(s != NULL);
659 flags_ = kCopyStringFlag;
660 data_.s.str = (
Ch *)allocator.Malloc((length + 1) *
sizeof(
Ch));
661 data_.s.length = length;
662 memcpy(const_cast<Ch*>(data_.s.str), s, length *
sizeof(
Ch));
663 const_cast<Ch*
>(data_.s.str)[length] =
'\0';
669 rhs.flags_ = kNullFlag;
678 typedef GenericValue<UTF8<> > Value;
689 template <
typename Encoding,
typename Allocator = MemoryPoolAllocator<> >
692 typedef typename Encoding::Ch
Ch;
700 GenericDocument(
Allocator* allocator = 0,
size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {}
707 template <
unsigned parseFlags,
typename Stream>
709 ValueType::SetNull();
711 if (reader.template Parse<parseFlags>(stream, *
this)) {
712 RAPIDJSON_ASSERT(stack_.GetSize() ==
sizeof(
ValueType));
713 this->RawAssign(*stack_.template Pop<ValueType>(1));
718 parseError_ = reader.GetParseError();
719 errorOffset_ = reader.GetErrorOffset();
730 template <
unsigned parseFlags>
733 return ParseStream<parseFlags | kParseInsituFlag>(s);
740 template <
unsigned parseFlags>
742 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
744 return ParseStream<parseFlags>(s);
769 void Null() {
new (stack_.template Push<ValueType>())
ValueType(); }
770 void Bool(
bool b) {
new (stack_.template Push<ValueType>())
ValueType(b); }
771 void Int(
int i) {
new (stack_.template Push<ValueType>())
ValueType(i); }
772 void Uint(
unsigned i) {
new (stack_.template Push<ValueType>())
ValueType(i); }
773 void Int64(int64_t i) {
new (stack_.template Push<ValueType>())
ValueType(i); }
774 void Uint64(uint64_t i) {
new (stack_.template Push<ValueType>())
ValueType(i); }
775 void Double(
double d) {
new (stack_.template Push<ValueType>())
ValueType(d); }
777 void String(
const Ch* str, SizeType length,
bool copy) {
781 new (stack_.template Push<ValueType>())
ValueType(str, length);
784 void StartObject() {
new (stack_.template Push<ValueType>())
ValueType(kObjectType); }
786 void EndObject(SizeType memberCount) {
787 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
788 stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount,
GetAllocator());
791 void StartArray() {
new (stack_.template Push<ValueType>())
ValueType(kArrayType); }
793 void EndArray(SizeType elementCount) {
794 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
795 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount,
GetAllocator());
799 if (Allocator::kNeedFree)
800 while (stack_.GetSize() > 0)
801 (stack_.template Pop<ValueType>(1))->~
ValueType();
806 static const size_t kDefaultStackCapacity = 1024;
807 internal::Stack<Allocator> stack_;
808 const char* parseError_;
812 typedef GenericDocument<UTF8<> > Document;
820 #endif // RAPIDJSON_DOCUMENT_H_