VR-Vantage API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
document.h
Go to the documentation of this file.
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 
16 // GenericValue
17 
19 
28 #pragma pack (push, 4)
29 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
30 class GenericValue {
31 public:
33  struct Member {
36  };
37 
40  typedef typename Encoding::Ch Ch;
42  typedef const Member* ConstMemberIterator;
45 
47 
48 
51 
53 private:
54  GenericValue(const GenericValue& rhs);
55 
56 public:
57 
59 
64  static const unsigned defaultFlags[7] = {
67  };
69  flags_ = defaultFlags[type];
70  memset(&data_, 0, sizeof(data_));
71  }
72 
75 
78  data_.n.i64 = i;
79  if (i >= 0)
81  }
82 
85  data_.n.u64 = u;
86  if (!(u & 0x80000000))
88  }
89 
92  data_.n.i64 = i64;
93  if (i64 >= 0) {
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 
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 
117 
120  RAPIDJSON_ASSERT(s != NULL);
122  data_.s.str = s;
123  data_.s.length = length;
124  }
125 
128 
130  GenericValue(const Ch* s, SizeType length, Allocator& allocator) { SetStringRaw(s, length, allocator); }
131 
133  GenericValue(const Ch*s, Allocator& allocator) { SetStringRaw(s, internal::StrLen(s), allocator); }
134 
136 
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 
163 
165 
166 
168 
171  RAPIDJSON_ASSERT(this != &rhs);
172  this->~GenericValue();
173  memcpy(this, &rhs, sizeof(GenericValue));
174  rhs.flags_ = kNullFlag;
175  return *this;
176  }
177 
179 
182  template <typename T>
184  this->~GenericValue();
185  new (this) GenericValue(value);
186  return *this;
187  }
189 
191 
192 
193  Type GetType() const { return static_cast<Type>(flags_ & kTypeMask); }
194  bool IsNull() const { return flags_ == kNullFlag; }
195  bool IsFalse() const { return flags_ == kFalseFlag; }
196  bool IsTrue() const { return flags_ == kTrueFlag; }
197  bool IsBool() const { return (flags_ & kBoolFlag) != 0; }
198  bool IsObject() const { return flags_ == kObjectFlag; }
199  bool IsArray() const { return flags_ == kArrayFlag; }
200  bool IsNumber() const { return (flags_ & kNumberFlag) != 0; }
201  bool IsInt() const { return (flags_ & kIntFlag) != 0; }
202  bool IsUint() const { return (flags_ & kUintFlag) != 0; }
203  bool IsInt64() const { return (flags_ & kInt64Flag) != 0; }
204  bool IsUint64() const { return (flags_ & kUint64Flag) != 0; }
205  bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; }
206  bool IsString() const { return (flags_ & kStringFlag) != 0; }
207 
209 
211 
212 
213  GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
214 
216 
218 
219 
220  bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; }
221  GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
222 
224 
226 
227 
229  GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
230 
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 
247 
249  bool HasMember(const Ch* name) const { return FindMember(name) != 0; }
250 
252 
260  RAPIDJSON_ASSERT(name.IsString());
261  Object& o = data_.o;
262  if (o.size >= o.capacity) {
263  if (o.capacity == 0) {
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 
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 
285  GenericValue n(name, internal::StrLen(name));
286  return AddMember(n, value, allocator);
287  }
288 
289  template <typename T>
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 
297 
301  bool RemoveMember(const Ch* name) {
303  if (Member* m = FindMember(name)) {
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 
325 
327 
328 
330  GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
331 
333  SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
334 
337 
339  bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
340 
342 
344  void Clear() {
346  for (SizeType i = 0; i < data_.a.size; ++i)
347  data_.a.elements[i].~GenericValue();
348  data_.a.size = 0;
349  }
350 
352 
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 
372  ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
373  ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
374 
376 
380  GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
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 
390 
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>
406  GenericValue v(value);
407  return PushBack(v, allocator);
408  }
409 
414  data_.a.elements[--data_.a.size].~GenericValue();
415  return *this;
416  }
418 
420 
421 
422  int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; }
423  unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; }
424  int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; }
425  uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; }
426 
427  double GetDouble() const {
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 
436  GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
437  GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
438  GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
439  GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
440  GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
441 
443 
445 
446 
447  const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return data_.s.str; }
448 
450 
453 
455 
460  GenericValue& SetString(const Ch* s, SizeType length) { this->~GenericValue(); SetStringRaw(s, length); return *this; }
461 
463 
466  GenericValue& SetString(const Ch* s) { return SetString(s, internal::StrLen(s)); }
467 
469 
475  GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, length, allocator); return *this; }
476 
478 
482  GenericValue& SetString(const Ch* s, Allocator& allocator) { SetString(s, internal::StrLen(s), allocator); return *this; }
483 
485 
487 
493  template <typename 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.
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;
569  unsigned hashcode;
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 {
602  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
603 
604  struct Array {
608  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
609 
610  union Data {
615  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
616 
619  RAPIDJSON_ASSERT(name);
621 
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  }
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.
635  flags_ = kArrayFlag;
636  data_.a.elements = (GenericValue*)alloctaor.Malloc(count * sizeof(GenericValue));
637  memcpy(data_.a.elements, values, count * sizeof(GenericValue));
639  }
640 
642  void SetObjectRaw(Member* members, SizeType count, Allocator& alloctaor) {
644  data_.o.members = (Member*)alloctaor.Malloc(count * sizeof(Member));
645  memcpy(data_.o.members, members, count * sizeof(Member));
647  }
648 
650  void SetStringRaw(const Ch* s, SizeType length) {
651  RAPIDJSON_ASSERT(s != NULL);
653  data_.s.str = s;
654  data_.s.length = length;
655  }
656 
658  void SetStringRaw(const Ch* s, SizeType length, Allocator& allocator) {
659  RAPIDJSON_ASSERT(s != NULL);
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 
668  void RawAssign(GenericValue& rhs) {
669  memcpy(this, &rhs, sizeof(GenericValue));
670  rhs.flags_ = kNullFlag;
671  }
672 
674  unsigned flags_;
675 };
676 #pragma pack (pop)
677 
680 
682 // GenericDocument
683 
685 
690 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
691 class GenericDocument : public GenericValue<Encoding, Allocator> {
692 public:
693  typedef typename Encoding::Ch Ch;
696 
698 
701  GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {}
702 
704 
708  template <unsigned parseFlags, typename Stream>
710  ValueType::SetNull(); // Remove existing root if exist
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 
727 
731  template <unsigned parseFlags>
734  return ParseStream<parseFlags | kParseInsituFlag>(s);
735  }
736 
738 
741  template <unsigned parseFlags>
742  GenericDocument& Parse(const Ch* str) {
743  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
745  return ParseStream<parseFlags>(s);
746  }
747 
749  bool HasParseError() const { return parseError_ != 0; }
750 
752  const char* GetParseError() const { return parseError_; }
753 
755  size_t GetErrorOffset() const { return errorOffset_; }
756 
758  Allocator& GetAllocator() { return stack_.GetAllocator(); }
759 
761  size_t GetStackCapacity() const { return stack_.GetCapacity(); }
762 
763 private:
764  // Prohibit assignment
766 
767  friend class GenericReader<Encoding, Allocator>; // for Reader to call the following private handler functions
768 
769  // Implementation of Handler
770  void Null() { new (stack_.template Push<ValueType>()) ValueType(); }
771  void Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); }
772  void Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); }
773  void Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); }
774  void Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); }
775  void Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); }
776  void Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); }
777 
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 
785  void StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); }
786 
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 
792  void StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); }
793 
794  void EndArray(SizeType elementCount) {
795  ValueType* elements = stack_.template Pop<ValueType>(elementCount);
796  stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
797  }
798 
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;
809  const char* parseError_;
810  size_t errorOffset_;
811 };
812 
814 
815 } // namespace rapidjson
816 
817 #ifdef _MSC_VER
818 #pragma warning(pop)
819 #endif
820 
821 #endif // RAPIDJSON_DOCUMENT_H_


Copyright © 2005-2013 VT MÄK. All Rights Reserved (www.mak.com)