RetroArch
schema.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available->
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved->
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License-> You may obtain a copy of the License at
7 //
8 // http://opensource->org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied-> See the License for the
13 // specific language governing permissions and limitations under the License->
14 
15 #ifndef RAPIDJSON_SCHEMA_H_
16 #define RAPIDJSON_SCHEMA_H_
17 
18 #include "document.h"
19 #include "pointer.h"
20 #include <cmath> // abs, floor
21 
22 #if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX)
23 #define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1
24 #else
25 #define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0
26 #endif
27 
28 #if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && !defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800))
29 #define RAPIDJSON_SCHEMA_USE_STDREGEX 1
30 #else
31 #define RAPIDJSON_SCHEMA_USE_STDREGEX 0
32 #endif
33 
34 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX
35 #include "internal/regex.h"
36 #elif RAPIDJSON_SCHEMA_USE_STDREGEX
37 #include <regex>
38 #endif
39 
40 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX
41 #define RAPIDJSON_SCHEMA_HAS_REGEX 1
42 #else
43 #define RAPIDJSON_SCHEMA_HAS_REGEX 0
44 #endif
45 
46 #ifndef RAPIDJSON_SCHEMA_VERBOSE
47 #define RAPIDJSON_SCHEMA_VERBOSE 0
48 #endif
49 
50 #if RAPIDJSON_SCHEMA_VERBOSE
51 #include "stringbuffer.h"
52 #endif
53 
54 RAPIDJSON_DIAG_PUSH
55 
56 #if defined(__GNUC__)
57 RAPIDJSON_DIAG_OFF(effc++)
58 #endif
59 
60 #ifdef __clang__
61 RAPIDJSON_DIAG_OFF(weak-vtables)
62 RAPIDJSON_DIAG_OFF(exit-time-destructors)
63 RAPIDJSON_DIAG_OFF(c++98-compat-pedantic)
64 RAPIDJSON_DIAG_OFF(variadic-macros)
65 #endif
66 
67 #ifdef _MSC_VER
68 RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
69 #endif
70 
72 
74 // Verbose Utilities
75 
76 #if RAPIDJSON_SCHEMA_VERBOSE
77 
78 namespace internal {
79 
80 inline void PrintInvalidKeyword(const char* keyword) {
81  printf("Fail keyword: %s\n", keyword);
82 }
83 
84 inline void PrintInvalidKeyword(const wchar_t* keyword) {
85  wprintf(L"Fail keyword: %ls\n", keyword);
86 }
87 
88 inline void PrintInvalidDocument(const char* document) {
89  printf("Fail document: %s\n\n", document);
90 }
91 
92 inline void PrintInvalidDocument(const wchar_t* document) {
93  wprintf(L"Fail document: %ls\n\n", document);
94 }
95 
96 inline void PrintValidatorPointers(unsigned depth, const char* s, const char* d) {
97  printf("S: %*s%s\nD: %*s%s\n\n", depth * 4, " ", s, depth * 4, " ", d);
98 }
99 
100 inline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar_t* d) {
101  wprintf(L"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L" ", s, depth * 4, L" ", d);
102 }
103 
104 } // namespace internal
105 
106 #endif // RAPIDJSON_SCHEMA_VERBOSE
107 
109 // RAPIDJSON_INVALID_KEYWORD_RETURN
110 
111 #if RAPIDJSON_SCHEMA_VERBOSE
112 #define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword)
113 #else
114 #define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword)
115 #endif
116 
117 #define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\
118 RAPIDJSON_MULTILINEMACRO_BEGIN\
119  context.invalidKeyword = keyword.GetString();\
120  RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\
121  return false;\
122 RAPIDJSON_MULTILINEMACRO_END
123 
125 // Forward declarations
126 
127 template <typename ValueType, typename Allocator>
129 
130 namespace internal {
131 
132 template <typename SchemaDocumentType>
133 class Schema;
134 
136 // ISchemaValidator
137 
139 public:
140  virtual ~ISchemaValidator() {}
141  virtual bool IsValid() const = 0;
142 };
143 
145 // ISchemaStateFactory
146 
147 template <typename SchemaType>
149 public:
150  virtual ~ISchemaStateFactory() {}
151  virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0;
152  virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0;
153  virtual void* CreateHasher() = 0;
154  virtual uint64_t GetHashCode(void* hasher) = 0;
155  virtual void DestroryHasher(void* hasher) = 0;
156  virtual void* MallocState(size_t size) = 0;
157  virtual void FreeState(void* p) = 0;
158 };
159 
161 // Hasher
162 
163 // For comparison of compound value
164 template<typename Encoding, typename Allocator>
165 class Hasher {
166 public:
167  typedef typename Encoding::Ch Ch;
168 
169  Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {}
170 
171  bool Null() { return WriteType(kNullType); }
172  bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); }
173  bool Int(int i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }
174  bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }
175  bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }
176  bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }
177  bool Double(double d) {
178  Number n;
179  if (d < 0) n.u.i = static_cast<int64_t>(d);
180  else n.u.u = static_cast<uint64_t>(d);
181  n.d = d;
182  return WriteNumber(n);
183  }
184 
185  bool RawNumber(const Ch* str, SizeType len, bool) {
186  WriteBuffer(kNumberType, str, len * sizeof(Ch));
187  return true;
188  }
189 
190  bool String(const Ch* str, SizeType len, bool) {
191  WriteBuffer(kStringType, str, len * sizeof(Ch));
192  return true;
193  }
194 
195  bool StartObject() { return true; }
196  bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); }
197  bool EndObject(SizeType memberCount) {
198  uint64_t h = Hash(0, kObjectType);
199  uint64_t* kv = stack_.template Pop<uint64_t>(memberCount * 2);
200  for (SizeType i = 0; i < memberCount; i++)
201  h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive
202  *stack_.template Push<uint64_t>() = h;
203  return true;
204  }
205 
206  bool StartArray() { return true; }
207  bool EndArray(SizeType elementCount) {
208  uint64_t h = Hash(0, kArrayType);
209  uint64_t* e = stack_.template Pop<uint64_t>(elementCount);
210  for (SizeType i = 0; i < elementCount; i++)
211  h = Hash(h, e[i]); // Use hash to achieve element order sensitive
212  *stack_.template Push<uint64_t>() = h;
213  return true;
214  }
215 
216  bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); }
217 
220  return *stack_.template Top<uint64_t>();
221  }
222 
223 private:
224  static const size_t kDefaultSize = 256;
225  struct Number {
226  union U {
229  }u;
230  double d;
231  };
232 
233  bool WriteType(Type type) { return WriteBuffer(type, 0, 0); }
234 
235  bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); }
236 
237  bool WriteBuffer(Type type, const void* data, size_t len) {
238  // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/
239  uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type);
240  const unsigned char* d = static_cast<const unsigned char*>(data);
241  for (size_t i = 0; i < len; i++)
242  h = Hash(h, d[i]);
243  *stack_.template Push<uint64_t>() = h;
244  return true;
245  }
246 
248  static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3);
249  h ^= d;
250  h *= kPrime;
251  return h;
252  }
253 
255 };
256 
258 // SchemaValidationContext
259 
260 template <typename SchemaDocumentType>
265  typedef typename ValueType::Ch Ch;
266 
271  };
272 
274  factory(f),
275  schema(s),
276  valueSchema(),
277  invalidKeyword(),
278  hasher(),
280  validators(),
281  validatorCount(),
287  propertyExist(),
288  inArray(false),
291  {
292  }
293 
295  if (hasher)
297  if (validators) {
298  for (SizeType i = 0; i < validatorCount; i++)
301  }
303  for (SizeType i = 0; i < patternPropertiesValidatorCount; i++)
306  }
309  if (propertyExist)
311  }
312 
317  void* hasher; // Only validator access
318  void* arrayElementHashCodes; // Only validator access this
329  bool inArray;
332 };
333 
335 // Schema
336 
337 template <typename SchemaDocumentType>
338 class Schema {
339 public:
340  typedef typename SchemaDocumentType::ValueType ValueType;
341  typedef typename SchemaDocumentType::AllocatorType AllocatorType;
342  typedef typename SchemaDocumentType::PointerType PointerType;
343  typedef typename ValueType::EncodingType EncodingType;
344  typedef typename EncodingType::Ch Ch;
349 
350  Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) :
351  allocator_(allocator),
352  enum_(),
353  enumCount_(),
354  not_(),
355  type_((1 << kTotalSchemaType) - 1), // typeless
356  validatorCount_(),
357  properties_(),
361  propertyCount_(),
362  minProperties_(),
366  hasRequired_(),
369  itemsList_(),
370  itemsTuple_(),
372  minItems_(),
373  maxItems_(SizeType(~0)),
376  pattern_(),
377  minLength_(0),
378  maxLength_(~SizeType(0)),
381  {
382  typedef typename SchemaDocumentType::ValueType ValueType;
383  typedef typename ValueType::ConstValueIterator ConstValueIterator;
384  typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
385 
386  if (!value.IsObject())
387  return;
388 
389  if (const ValueType* v = GetMember(value, GetTypeString())) {
390  type_ = 0;
391  if (v->IsString())
392  AddType(*v);
393  else if (v->IsArray())
394  for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
395  AddType(*itr);
396  }
397 
398  if (const ValueType* v = GetMember(value, GetEnumString()))
399  if (v->IsArray() && v->Size() > 0) {
400  enum_ = static_cast<uint64_t*>(allocator_->Malloc(sizeof(uint64_t) * v->Size()));
401  for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) {
402  typedef Hasher<EncodingType, MemoryPoolAllocator<> > EnumHasherType;
403  char buffer[256 + 24];
404  MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer));
405  EnumHasherType h(&hasherAllocator, 256);
406  itr->Accept(h);
407  enum_[enumCount_++] = h.GetHashCode();
408  }
409  }
410 
411  if (schemaDocument) {
412  AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document);
413  AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document);
414  AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document);
415  }
416 
417  if (const ValueType* v = GetMember(value, GetNotString())) {
418  schemaDocument->CreateSchema(&not_, p.Append(GetNotString(), allocator_), *v, document);
420  validatorCount_++;
421  }
422 
423  // Object
424 
425  const ValueType* properties = GetMember(value, GetPropertiesString());
426  const ValueType* required = GetMember(value, GetRequiredString());
427  const ValueType* dependencies = GetMember(value, GetDependenciesString());
428  {
429  // Gather properties from properties/required/dependencies
430  SValue allProperties(kArrayType);
431 
432  if (properties && properties->IsObject())
433  for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr)
434  AddUniqueElement(allProperties, itr->name);
435 
436  if (required && required->IsArray())
437  for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
438  if (itr->IsString())
439  AddUniqueElement(allProperties, *itr);
440 
441  if (dependencies && dependencies->IsObject())
442  for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {
443  AddUniqueElement(allProperties, itr->name);
444  if (itr->value.IsArray())
445  for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i)
446  if (i->IsString())
447  AddUniqueElement(allProperties, *i);
448  }
449 
450  if (allProperties.Size() > 0) {
451  propertyCount_ = allProperties.Size();
452  properties_ = static_cast<Property*>(allocator_->Malloc(sizeof(Property) * propertyCount_));
453  for (SizeType i = 0; i < propertyCount_; i++) {
454  new (&properties_[i]) Property();
455  properties_[i].name = allProperties[i];
457  }
458  }
459  }
460 
461  if (properties && properties->IsObject()) {
462  PointerType q = p.Append(GetPropertiesString(), allocator_);
463  for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) {
464  SizeType index;
465  if (FindPropertyIndex(itr->name, &index))
466  schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document);
467  }
468  }
469 
470  if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) {
471  PointerType q = p.Append(GetPatternPropertiesString(), allocator_);
472  patternProperties_ = static_cast<PatternProperty*>(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount()));
474 
475  for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {
478  schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value, document);
480  }
481  }
482 
483  if (required && required->IsArray())
484  for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
485  if (itr->IsString()) {
486  SizeType index;
487  if (FindPropertyIndex(*itr, &index)) {
488  properties_[index].required = true;
489  hasRequired_ = true;
490  }
491  }
492 
493  if (dependencies && dependencies->IsObject()) {
494  PointerType q = p.Append(GetDependenciesString(), allocator_);
495  hasDependencies_ = true;
496  for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {
497  SizeType sourceIndex;
498  if (FindPropertyIndex(itr->name, &sourceIndex)) {
499  if (itr->value.IsArray()) {
500  properties_[sourceIndex].dependencies = static_cast<bool*>(allocator_->Malloc(sizeof(bool) * propertyCount_));
501  std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_);
502  for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) {
503  SizeType targetIndex;
504  if (FindPropertyIndex(*targetItr, &targetIndex))
505  properties_[sourceIndex].dependencies[targetIndex] = true;
506  }
507  }
508  else if (itr->value.IsObject()) {
509  hasSchemaDependencies_ = true;
510  schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document);
512  validatorCount_++;
513  }
514  }
515  }
516  }
517 
518  if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) {
519  if (v->IsBool())
520  additionalProperties_ = v->GetBool();
521  else if (v->IsObject())
522  schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document);
523  }
524 
525  AssignIfExist(minProperties_, value, GetMinPropertiesString());
526  AssignIfExist(maxProperties_, value, GetMaxPropertiesString());
527 
528  // Array
529  if (const ValueType* v = GetMember(value, GetItemsString())) {
530  PointerType q = p.Append(GetItemsString(), allocator_);
531  if (v->IsObject()) // List validation
532  schemaDocument->CreateSchema(&itemsList_, q, *v, document);
533  else if (v->IsArray()) { // Tuple validation
534  itemsTuple_ = static_cast<const Schema**>(allocator_->Malloc(sizeof(const Schema*) * v->Size()));
535  SizeType index = 0;
536  for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++)
537  schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document);
538  }
539  }
540 
541  AssignIfExist(minItems_, value, GetMinItemsString());
542  AssignIfExist(maxItems_, value, GetMaxItemsString());
543 
544  if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) {
545  if (v->IsBool())
546  additionalItems_ = v->GetBool();
547  else if (v->IsObject())
548  schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document);
549  }
550 
551  AssignIfExist(uniqueItems_, value, GetUniqueItemsString());
552 
553  // String
554  AssignIfExist(minLength_, value, GetMinLengthString());
555  AssignIfExist(maxLength_, value, GetMaxLengthString());
556 
557  if (const ValueType* v = GetMember(value, GetPatternString()))
559 
560  // Number
561  if (const ValueType* v = GetMember(value, GetMinimumString()))
562  if (v->IsNumber())
563  minimum_.CopyFrom(*v, *allocator_);
564 
565  if (const ValueType* v = GetMember(value, GetMaximumString()))
566  if (v->IsNumber())
567  maximum_.CopyFrom(*v, *allocator_);
568 
569  AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString());
570  AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString());
571 
572  if (const ValueType* v = GetMember(value, GetMultipleOfString()))
573  if (v->IsNumber() && v->GetDouble() > 0.0)
574  multipleOf_.CopyFrom(*v, *allocator_);
575  }
576 
578  if (allocator_) {
579  allocator_->Free(enum_);
580  }
581  if (properties_) {
582  for (SizeType i = 0; i < propertyCount_; i++)
583  properties_[i].~Property();
584  AllocatorType::Free(properties_);
585  }
586  if (patternProperties_) {
587  for (SizeType i = 0; i < patternPropertyCount_; i++)
589  AllocatorType::Free(patternProperties_);
590  }
591  AllocatorType::Free(itemsTuple_);
592 #if RAPIDJSON_SCHEMA_HAS_REGEX
593  if (pattern_) {
594  pattern_->~RegexType();
595  allocator_->Free(pattern_);
596  }
597 #endif
598  }
599 
600  bool BeginValue(Context& context) const {
601  if (context.inArray) {
602  if (uniqueItems_)
603  context.valueUniqueness = true;
604 
605  if (itemsList_)
606  context.valueSchema = itemsList_;
607  else if (itemsTuple_) {
608  if (context.arrayElementIndex < itemsTupleCount_)
609  context.valueSchema = itemsTuple_[context.arrayElementIndex];
610  else if (additionalItemsSchema_)
612  else if (additionalItems_)
613  context.valueSchema = GetTypeless();
614  else
615  RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString());
616  }
617  else
618  context.valueSchema = GetTypeless();
619 
620  context.arrayElementIndex++;
621  }
622  return true;
623  }
624 
625  RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const {
626  if (context.patternPropertiesValidatorCount > 0) {
627  bool otherValid = false;
630  otherValid = context.patternPropertiesValidators[--count]->IsValid();
631 
632  bool patternValid = true;
633  for (SizeType i = 0; i < count; i++)
634  if (!context.patternPropertiesValidators[i]->IsValid()) {
635  patternValid = false;
636  break;
637  }
638 
640  if (!patternValid)
641  RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
642  }
644  if (!patternValid || !otherValid)
645  RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
646  }
647  else if (!patternValid && !otherValid) // kPatternValidatorWithAdditionalProperty)
648  RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
649  }
650 
651  if (enum_) {
652  const uint64_t h = context.factory.GetHashCode(context.hasher);
653  for (SizeType i = 0; i < enumCount_; i++)
654  if (enum_[i] == h)
655  goto foundEnum;
656  RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString());
657  foundEnum:;
658  }
659 
660  if (allOf_.schemas)
661  for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++)
662  if (!context.validators[i]->IsValid())
663  RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString());
664 
665  if (anyOf_.schemas) {
666  for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)
667  if (context.validators[i]->IsValid())
668  goto foundAny;
669  RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString());
670  foundAny:;
671  }
672 
673  if (oneOf_.schemas) {
674  bool oneValid = false;
675  for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++)
676  if (context.validators[i]->IsValid()) {
677  if (oneValid)
678  RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());
679  else
680  oneValid = true;
681  }
682  if (!oneValid)
683  RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());
684  }
685 
686  if (not_ && context.validators[notValidatorIndex_]->IsValid())
687  RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString());
688 
689  return true;
690  }
691 
692  bool Null(Context& context) const {
693  if (!(type_ & (1 << kNullSchemaType)))
694  RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
695  return CreateParallelValidator(context);
696  }
697 
698  bool Bool(Context& context, bool) const {
699  if (!(type_ & (1 << kBooleanSchemaType)))
700  RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
701  return CreateParallelValidator(context);
702  }
703 
704  bool Int(Context& context, int i) const {
705  if (!CheckInt(context, i))
706  return false;
707  return CreateParallelValidator(context);
708  }
709 
710  bool Uint(Context& context, unsigned u) const {
711  if (!CheckUint(context, u))
712  return false;
713  return CreateParallelValidator(context);
714  }
715 
716  bool Int64(Context& context, int64_t i) const {
717  if (!CheckInt(context, i))
718  return false;
719  return CreateParallelValidator(context);
720  }
721 
722  bool Uint64(Context& context, uint64_t u) const {
723  if (!CheckUint(context, u))
724  return false;
725  return CreateParallelValidator(context);
726  }
727 
728  bool Double(Context& context, double d) const {
729  if (!(type_ & (1 << kNumberSchemaType)))
730  RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
731 
732  if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d))
733  return false;
734 
735  if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d))
736  return false;
737 
738  if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d))
739  return false;
740 
741  return CreateParallelValidator(context);
742  }
743 
744  bool String(Context& context, const Ch* str, SizeType length, bool) const {
745  if (!(type_ & (1 << kStringSchemaType)))
746  RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
747 
748  if (minLength_ != 0 || maxLength_ != SizeType(~0)) {
749  SizeType count;
750  if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {
751  if (count < minLength_)
752  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString());
753  if (count > maxLength_)
754  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString());
755  }
756  }
757 
759  RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString());
760 
761  return CreateParallelValidator(context);
762  }
763 
764  bool StartObject(Context& context) const {
765  if (!(type_ & (1 << kObjectSchemaType)))
766  RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
767 
769  context.propertyExist = static_cast<bool*>(context.factory.MallocState(sizeof(bool) * propertyCount_));
770  std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_);
771  }
772 
773  if (patternProperties_) { // pre-allocate schema array
774  SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType
775  context.patternPropertiesSchemas = static_cast<const SchemaType**>(context.factory.MallocState(sizeof(const SchemaType*) * count));
776  context.patternPropertiesSchemaCount = 0;
777  std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count);
778  }
779 
780  return CreateParallelValidator(context);
781  }
782 
783  bool Key(Context& context, const Ch* str, SizeType len, bool) const {
784  if (patternProperties_) {
785  context.patternPropertiesSchemaCount = 0;
786  for (SizeType i = 0; i < patternPropertyCount_; i++)
789  }
790 
791  SizeType index;
792  if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {
793  if (context.patternPropertiesSchemaCount > 0) {
795  context.valueSchema = GetTypeless();
797  }
798  else
799  context.valueSchema = properties_[index].schema;
800 
801  if (context.propertyExist)
802  context.propertyExist[index] = true;
803 
804  return true;
805  }
806 
810  context.valueSchema = GetTypeless();
812  }
813  else
815  return true;
816  }
817  else if (additionalProperties_) {
818  context.valueSchema = GetTypeless();
819  return true;
820  }
821 
822  if (context.patternPropertiesSchemaCount == 0) // patternProperties are not additional properties
823  RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString());
824 
825  return true;
826  }
827 
828  bool EndObject(Context& context, SizeType memberCount) const {
829  if (hasRequired_)
830  for (SizeType index = 0; index < propertyCount_; index++)
831  if (properties_[index].required)
832  if (!context.propertyExist[index])
833  RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString());
834 
835  if (memberCount < minProperties_)
836  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString());
837 
838  if (memberCount > maxProperties_)
839  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString());
840 
841  if (hasDependencies_) {
842  for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++)
843  if (context.propertyExist[sourceIndex]) {
844  if (properties_[sourceIndex].dependencies) {
845  for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++)
846  if (properties_[sourceIndex].dependencies[targetIndex] && !context.propertyExist[targetIndex])
847  RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString());
848  }
849  else if (properties_[sourceIndex].dependenciesSchema)
850  if (!context.validators[properties_[sourceIndex].dependenciesValidatorIndex]->IsValid())
851  RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString());
852  }
853  }
854 
855  return true;
856  }
857 
858  bool StartArray(Context& context) const {
859  if (!(type_ & (1 << kArraySchemaType)))
860  RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
861 
862  context.arrayElementIndex = 0;
863  context.inArray = true;
864 
865  return CreateParallelValidator(context);
866  }
867 
868  bool EndArray(Context& context, SizeType elementCount) const {
869  context.inArray = false;
870 
871  if (elementCount < minItems_)
872  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString());
873 
874  if (elementCount > maxItems_)
875  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString());
876 
877  return true;
878  }
879 
880  // Generate functions for string literal according to Ch
881 #define RAPIDJSON_STRING_(name, ...) \
882  static const ValueType& Get##name##String() {\
883  static const Ch s[] = { __VA_ARGS__, '\0' };\
884  static const ValueType v(s, sizeof(s) / sizeof(Ch) - 1);\
885  return v;\
886  }
887 
888  RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l')
889  RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n')
890  RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't')
891  RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y')
892  RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g')
893  RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r')
894  RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r')
895  RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e')
896  RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm')
897  RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f')
898  RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f')
899  RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f')
900  RAPIDJSON_STRING_(Not, 'n', 'o', 't')
901  RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
902  RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd')
903  RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's')
904  RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
905  RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
906  RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
907  RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
908  RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's')
909  RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's')
910  RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's')
911  RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's')
912  RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's')
913  RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h')
914  RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h')
915  RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n')
916  RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm')
917  RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm')
918  RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm')
919  RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm')
920  RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f')
921 
922 #undef RAPIDJSON_STRING_
923 
924 private:
934  };
935 
936 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX
938 #elif RAPIDJSON_SCHEMA_USE_STDREGEX
939  typedef std::basic_regex<Ch> RegexType;
940 #else
941  typedef char RegexType;
942 #endif
943 
944  struct SchemaArray {
946  ~SchemaArray() { AllocatorType::Free(schemas); }
948  SizeType begin; // begin index of context.validators
950  };
951 
952  static const SchemaType* GetTypeless() {
953  static SchemaType typeless(0, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), 0);
954  return &typeless;
955  }
956 
957  template <typename V1, typename V2>
958  void AddUniqueElement(V1& a, const V2& v) {
959  for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
960  if (*itr == v)
961  return;
962  V1 c(v, *allocator_);
963  a.PushBack(c, *allocator_);
964  }
965 
966  static const ValueType* GetMember(const ValueType& value, const ValueType& name) {
967  typename ValueType::ConstMemberIterator itr = value.FindMember(name);
968  return itr != value.MemberEnd() ? &(itr->value) : 0;
969  }
970 
971  static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) {
972  if (const ValueType* v = GetMember(value, name))
973  if (v->IsBool())
974  out = v->GetBool();
975  }
976 
977  static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) {
978  if (const ValueType* v = GetMember(value, name))
979  if (v->IsUint64() && v->GetUint64() <= SizeType(~0))
980  out = static_cast<SizeType>(v->GetUint64());
981  }
982 
983  void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) {
984  if (const ValueType* v = GetMember(value, name)) {
985  if (v->IsArray() && v->Size() > 0) {
986  PointerType q = p.Append(name, allocator_);
987  out.count = v->Size();
988  out.schemas = static_cast<const Schema**>(allocator_->Malloc(out.count * sizeof(const Schema*)));
989  memset(out.schemas, 0, sizeof(Schema*)* out.count);
990  for (SizeType i = 0; i < out.count; i++)
991  schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document);
992  out.begin = validatorCount_;
993  validatorCount_ += out.count;
994  }
995  }
996  }
997 
998 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX
999  template <typename ValueType>
1001  if (value.IsString()) {
1002  RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString());
1003  if (!r->IsValid()) {
1004  r->~RegexType();
1005  AllocatorType::Free(r);
1006  r = 0;
1007  }
1008  return r;
1009  }
1010  return 0;
1011  }
1012 
1013  static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) {
1014  return pattern->Search(str);
1015  }
1016 #elif RAPIDJSON_SCHEMA_USE_STDREGEX
1017  template <typename ValueType>
1019  if (value.IsString())
1020  try {
1021  return new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);
1022  }
1023  catch (const std::regex_error&) {
1024  }
1025  return 0;
1026  }
1027 
1028  static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) {
1029  std::match_results<const Ch*> r;
1030  return std::regex_search(str, str + length, r, *pattern);
1031  }
1032 #else
1033  template <typename ValueType>
1034  RegexType* CreatePattern(const ValueType&) { return 0; }
1035 
1036  static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; }
1037 #endif // RAPIDJSON_SCHEMA_USE_STDREGEX
1038 
1039  void AddType(const ValueType& type) {
1040  if (type == GetNullString() ) type_ |= 1 << kNullSchemaType;
1041  else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType;
1042  else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType;
1043  else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType;
1044  else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType;
1045  else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType;
1046  else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
1047  }
1048 
1049  bool CreateParallelValidator(Context& context) const {
1050  if (enum_ || context.arrayUniqueness)
1051  context.hasher = context.factory.CreateHasher();
1052 
1053  if (validatorCount_) {
1054  RAPIDJSON_ASSERT(context.validators == 0);
1055  context.validators = static_cast<ISchemaValidator**>(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_));
1056  context.validatorCount = validatorCount_;
1057 
1058  if (allOf_.schemas)
1059  CreateSchemaValidators(context, allOf_);
1060 
1061  if (anyOf_.schemas)
1062  CreateSchemaValidators(context, anyOf_);
1063 
1064  if (oneOf_.schemas)
1065  CreateSchemaValidators(context, oneOf_);
1066 
1067  if (not_)
1069 
1070  if (hasSchemaDependencies_) {
1071  for (SizeType i = 0; i < propertyCount_; i++)
1072  if (properties_[i].dependenciesSchema)
1073  context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema);
1074  }
1075  }
1076 
1077  return true;
1078  }
1079 
1080  void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const {
1081  for (SizeType i = 0; i < schemas.count; i++)
1082  context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]);
1083  }
1084 
1085  // O(n)
1086  bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const {
1087  SizeType len = name.GetStringLength();
1088  const Ch* str = name.GetString();
1089  for (SizeType index = 0; index < propertyCount_; index++)
1090  if (properties_[index].name.GetStringLength() == len &&
1091  (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0))
1092  {
1093  *outIndex = index;
1094  return true;
1095  }
1096  return false;
1097  }
1098 
1099  bool CheckInt(Context& context, int64_t i) const {
1100  if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))
1101  RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
1102 
1103  if (!minimum_.IsNull()) {
1104  if (minimum_.IsInt64()) {
1105  if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64())
1106  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
1107  }
1108  else if (minimum_.IsUint64()) {
1109  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64()
1110  }
1111  else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1112  return false;
1113  }
1114 
1115  if (!maximum_.IsNull()) {
1116  if (maximum_.IsInt64()) {
1117  if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64())
1118  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
1119  }
1120  else if (maximum_.IsUint64())
1121  /* do nothing */; // i <= max(int64_t) < maximum_.GetUint64()
1122  else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1123  return false;
1124  }
1125 
1126  if (!multipleOf_.IsNull()) {
1127  if (multipleOf_.IsUint64()) {
1128  if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0)
1129  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
1130  }
1131  else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1132  return false;
1133  }
1134 
1135  return true;
1136  }
1137 
1138  bool CheckUint(Context& context, uint64_t i) const {
1139  if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))
1140  RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
1141 
1142  if (!minimum_.IsNull()) {
1143  if (minimum_.IsUint64()) {
1144  if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64())
1145  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
1146  }
1147  else if (minimum_.IsInt64())
1148  /* do nothing */; // i >= 0 > minimum.Getint64()
1149  else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1150  return false;
1151  }
1152 
1153  if (!maximum_.IsNull()) {
1154  if (maximum_.IsUint64()) {
1155  if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64())
1156  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
1157  }
1158  else if (maximum_.IsInt64())
1159  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_
1160  else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1161  return false;
1162  }
1163 
1164  if (!multipleOf_.IsNull()) {
1165  if (multipleOf_.IsUint64()) {
1166  if (i % multipleOf_.GetUint64() != 0)
1167  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
1168  }
1169  else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1170  return false;
1171  }
1172 
1173  return true;
1174  }
1175 
1176  bool CheckDoubleMinimum(Context& context, double d) const {
1177  if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble())
1178  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
1179  return true;
1180  }
1181 
1182  bool CheckDoubleMaximum(Context& context, double d) const {
1183  if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble())
1184  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
1185  return true;
1186  }
1187 
1188  bool CheckDoubleMultipleOf(Context& context, double d) const {
1189  double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());
1190  double q = std::floor(a / b);
1191  double r = a - q * b;
1192  if (r > 0.0)
1193  RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
1194  return true;
1195  }
1196 
1197  struct Property {
1199  ~Property() { AllocatorType::Free(dependencies); }
1205  bool required;
1206  };
1207 
1211  if (pattern) {
1212  pattern->~RegexType();
1213  AllocatorType::Free(pattern);
1214  }
1215  }
1218  };
1219 
1227  unsigned type_; // bitmask of kSchemaType
1230 
1242 
1251 
1255 
1261 };
1262 
1263 template<typename Stack, typename Ch>
1264 struct TokenHelper {
1265  RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) {
1266  *documentStack.template Push<Ch>() = '/';
1267  char buffer[21];
1268  size_t length = static_cast<size_t>((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer);
1269  for (size_t i = 0; i < length; i++)
1270  *documentStack.template Push<Ch>() = buffer[i];
1271  }
1272 };
1273 
1274 // Partial specialized version for char to prevent buffer copying.
1275 template <typename Stack>
1276 struct TokenHelper<Stack, char> {
1277  RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) {
1278  if (sizeof(SizeType) == 4) {
1279  char *buffer = documentStack.template Push<char>(1 + 10); // '/' + uint
1280  *buffer++ = '/';
1281  const char* end = internal::u32toa(index, buffer);
1282  documentStack.template Pop<char>(static_cast<size_t>(10 - (end - buffer)));
1283  }
1284  else {
1285  char *buffer = documentStack.template Push<char>(1 + 20); // '/' + uint64
1286  *buffer++ = '/';
1287  const char* end = internal::u64toa(index, buffer);
1288  documentStack.template Pop<char>(static_cast<size_t>(20 - (end - buffer)));
1289  }
1290  }
1291 };
1292 
1293 } // namespace internal
1294 
1296 // IGenericRemoteSchemaDocumentProvider
1297 
1298 template <typename SchemaDocumentType>
1300 public:
1301  typedef typename SchemaDocumentType::Ch Ch;
1302 
1304  virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0;
1305 };
1306 
1308 // GenericSchemaDocument
1309 
1311 
1319 template <typename ValueT, typename Allocator = CrtAllocator>
1320 class GenericSchemaDocument {
1321 public:
1322  typedef ValueT ValueType;
1324  typedef Allocator AllocatorType;
1325  typedef typename ValueType::EncodingType EncodingType;
1326  typedef typename EncodingType::Ch Ch;
1330  template <typename, typename, typename>
1332 
1334 
1341  explicit GenericSchemaDocument(const ValueType& document, IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) :
1342  remoteProvider_(remoteProvider),
1343  allocator_(allocator),
1344  ownAllocator_(),
1345  root_(),
1346  schemaMap_(allocator, kInitialSchemaMapSize),
1347  schemaRef_(allocator, kInitialSchemaRefSize)
1348  {
1349  if (!allocator_)
1350  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
1351 
1352  // Generate root schema, it will call CreateSchema() to create sub-schemas,
1353  // And call AddRefSchema() if there are $ref.
1354  CreateSchemaRecursive(&root_, PointerType(), document, document);
1355 
1356  // Resolve $ref
1357  while (!schemaRef_.Empty()) {
1358  SchemaRefEntry* refEntry = schemaRef_.template Pop<SchemaRefEntry>(1);
1359  if (const SchemaType* s = GetSchema(refEntry->target)) {
1360  if (refEntry->schema)
1361  *refEntry->schema = s;
1362 
1363  // Create entry in map if not exist
1364  if (!GetSchema(refEntry->source)) {
1365  new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(refEntry->source, const_cast<SchemaType*>(s), false, allocator_);
1366  }
1367  }
1368  refEntry->~SchemaRefEntry();
1369  }
1370 
1371  RAPIDJSON_ASSERT(root_ != 0);
1372 
1373  schemaRef_.ShrinkToFit(); // Deallocate all memory for ref
1374  }
1375 
1376 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1377  GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT :
1379  remoteProvider_(rhs.remoteProvider_),
1380  allocator_(rhs.allocator_),
1381  ownAllocator_(rhs.ownAllocator_),
1382  root_(rhs.root_),
1383  schemaMap_(std::move(rhs.schemaMap_)),
1384  schemaRef_(std::move(rhs.schemaRef_))
1385  {
1386  rhs.remoteProvider_ = 0;
1387  rhs.allocator_ = 0;
1388  rhs.ownAllocator_ = 0;
1389  }
1390 #endif
1391 
1394  while (!schemaMap_.Empty())
1395  schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry();
1396 
1398  }
1399 
1401  const SchemaType& GetRoot() const { return *root_; }
1402 
1403 private:
1408 
1410  SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {}
1414  };
1415 
1416  struct SchemaEntry {
1417  SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {}
1419  if (owned) {
1420  schema->~SchemaType();
1421  Allocator::Free(schema);
1422  }
1423  }
1426  bool owned;
1427  };
1428 
1429  void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {
1430  if (schema)
1431  *schema = SchemaType::GetTypeless();
1432 
1433  if (v.GetType() == kObjectType) {
1434  const SchemaType* s = GetSchema(pointer);
1435  if (!s)
1436  CreateSchema(schema, pointer, v, document);
1437 
1438  for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
1439  CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document);
1440  }
1441  else if (v.GetType() == kArrayType)
1442  for (SizeType i = 0; i < v.Size(); i++)
1443  CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document);
1444  }
1445 
1446  void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {
1447  RAPIDJSON_ASSERT(pointer.IsValid());
1448  if (v.IsObject()) {
1449  if (!HandleRefSchema(pointer, schema, v, document)) {
1450  SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_);
1451  new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(pointer, s, true, allocator_);
1452  if (schema)
1453  *schema = s;
1454  }
1455  }
1456  }
1457 
1458  bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document) {
1459  static const Ch kRefString[] = { '$', 'r', 'e', 'f', '\0' };
1460  static const ValueType kRefValue(kRefString, 4);
1461 
1462  typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue);
1463  if (itr == v.MemberEnd())
1464  return false;
1465 
1466  if (itr->value.IsString()) {
1467  SizeType len = itr->value.GetStringLength();
1468  if (len > 0) {
1469  const Ch* s = itr->value.GetString();
1470  SizeType i = 0;
1471  while (i < len && s[i] != '#') // Find the first #
1472  i++;
1473 
1474  if (i > 0) { // Remote reference, resolve immediately
1475  if (remoteProvider_) {
1476  if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i - 1)) {
1477  PointerType pointer(&s[i], len - i, allocator_);
1478  if (pointer.IsValid()) {
1479  if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) {
1480  if (schema)
1481  *schema = sc;
1482  return true;
1483  }
1484  }
1485  }
1486  }
1487  }
1488  else if (s[i] == '#') { // Local reference, defer resolution
1489  PointerType pointer(&s[i], len - i, allocator_);
1490  if (pointer.IsValid()) {
1491  if (const ValueType* nv = pointer.Get(document))
1492  if (HandleRefSchema(source, schema, *nv, document))
1493  return true;
1494 
1495  new (schemaRef_.template Push<SchemaRefEntry>()) SchemaRefEntry(source, pointer, schema, allocator_);
1496  return true;
1497  }
1498  }
1499  }
1500  }
1501  return false;
1502  }
1503 
1504  const SchemaType* GetSchema(const PointerType& pointer) const {
1505  for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
1506  if (pointer == target->pointer)
1507  return target->schema;
1508  return 0;
1509  }
1510 
1511  PointerType GetPointer(const SchemaType* schema) const {
1512  for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
1513  if (schema == target->schema)
1514  return target->pointer;
1515  return PointerType();
1516  }
1517 
1518  static const size_t kInitialSchemaMapSize = 64;
1519  static const size_t kInitialSchemaRefSize = 64;
1520 
1522  Allocator *allocator_;
1523  Allocator *ownAllocator_;
1525  internal::Stack<Allocator> schemaMap_; // Stores created Pointer -> Schemas
1526  internal::Stack<Allocator> schemaRef_; // Stores Pointer from $ref and schema which holds the $ref
1527 };
1528 
1533 
1535 // GenericSchemaValidator
1536 
1538 
1549 template <
1550  typename SchemaDocumentType,
1552  typename StateAllocator = CrtAllocator>
1553 class GenericSchemaValidator :
1554  public internal::ISchemaStateFactory<typename SchemaDocumentType::SchemaType>,
1556 {
1557 public:
1558  typedef typename SchemaDocumentType::SchemaType SchemaType;
1559  typedef typename SchemaDocumentType::PointerType PointerType;
1560  typedef typename SchemaType::EncodingType EncodingType;
1561  typedef typename EncodingType::Ch Ch;
1562 
1564 
1571  const SchemaDocumentType& schemaDocument,
1572  StateAllocator* allocator = 0,
1573  size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1574  size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1575  :
1576  schemaDocument_(&schemaDocument),
1577  root_(schemaDocument.GetRoot()),
1579  stateAllocator_(allocator),
1580  ownStateAllocator_(0),
1581  schemaStack_(allocator, schemaStackCapacity),
1582  documentStack_(allocator, documentStackCapacity),
1583  valid_(true)
1585  , depth_(0)
1586 #endif
1587  {
1588  }
1589 
1591 
1598  const SchemaDocumentType& schemaDocument,
1599  OutputHandler& outputHandler,
1600  StateAllocator* allocator = 0,
1601  size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1602  size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1603  :
1604  schemaDocument_(&schemaDocument),
1605  root_(schemaDocument.GetRoot()),
1606  outputHandler_(outputHandler),
1607  stateAllocator_(allocator),
1608  ownStateAllocator_(0),
1609  schemaStack_(allocator, schemaStackCapacity),
1610  documentStack_(allocator, documentStackCapacity),
1611  valid_(true)
1613  , depth_(0)
1614 #endif
1615  {
1616  }
1617 
1620  Reset();
1622  }
1623 
1625  void Reset() {
1626  while (!schemaStack_.Empty())
1627  PopSchema();
1629  valid_ = true;
1630  }
1631 
1633  // Implementation of ISchemaValidator
1634  virtual bool IsValid() const { return valid_; }
1635 
1638  return schemaStack_.Empty() ? PointerType() : schemaDocument_->GetPointer(&CurrentSchema());
1639  }
1640 
1642  const Ch* GetInvalidSchemaKeyword() const {
1643  return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword;
1644  }
1645 
1648  return documentStack_.Empty() ? PointerType() : PointerType(documentStack_.template Bottom<Ch>(), documentStack_.GetSize() / sizeof(Ch));
1649  }
1650 
1651 #if RAPIDJSON_SCHEMA_VERBOSE
1652 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \
1653 RAPIDJSON_MULTILINEMACRO_BEGIN\
1654  *documentStack_.template Push<Ch>() = '\0';\
1655  documentStack_.template Pop<Ch>(1);\
1656  internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>());\
1657 RAPIDJSON_MULTILINEMACRO_END
1658 #else
1659 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_()
1660 #endif
1661 
1662 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\
1663  if (!valid_) return false; \
1664  if (!BeginValue() || !CurrentSchema().method arg1) {\
1665  RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\
1666  return valid_ = false;\
1667  }
1668 
1669 #define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\
1670  for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\
1671  if (context->hasher)\
1672  static_cast<HasherType*>(context->hasher)->method arg2;\
1673  if (context->validators)\
1674  for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\
1675  static_cast<GenericSchemaValidator*>(context->validators[i_])->method arg2;\
1676  if (context->patternPropertiesValidators)\
1677  for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\
1678  static_cast<GenericSchemaValidator*>(context->patternPropertiesValidators[i_])->method arg2;\
1679  }
1680 
1681 #define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\
1682  return valid_ = EndValue() && outputHandler_.method arg2
1683 
1684 #define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \
1685  RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\
1686  RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\
1687  RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2)
1688 
1691  bool Int(int i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), i), (i)); }
1692  bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); }
1696  bool RawNumber(const Ch* str, SizeType length, bool copy)
1698  bool String(const Ch* str, SizeType length, bool copy)
1700 
1701  bool StartObject() {
1704  return valid_ = outputHandler_.StartObject();
1705  }
1706 
1707  bool Key(const Ch* str, SizeType len, bool copy) {
1708  if (!valid_) return false;
1709  AppendToken(str, len);
1710  if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false;
1712  return valid_ = outputHandler_.Key(str, len, copy);
1713  }
1714 
1715  bool EndObject(SizeType memberCount) {
1716  if (!valid_) return false;
1718  if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false;
1719  RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount));
1720  }
1721 
1722  bool StartArray() {
1725  return valid_ = outputHandler_.StartArray();
1726  }
1727 
1728  bool EndArray(SizeType elementCount) {
1729  if (!valid_) return false;
1731  if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false;
1732  RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount));
1733  }
1734 
1735 #undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_
1736 #undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_
1737 #undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_
1738 #undef RAPIDJSON_SCHEMA_HANDLE_VALUE_
1739 
1740  // Implementation of ISchemaStateFactory<SchemaType>
1741  virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) {
1744  depth_ + 1,
1745 #endif
1746  &GetStateAllocator());
1747  }
1748 
1749  virtual void DestroySchemaValidator(ISchemaValidator* validator) {
1750  GenericSchemaValidator* v = static_cast<GenericSchemaValidator*>(validator);
1752  StateAllocator::Free(v);
1753  }
1754 
1755  virtual void* CreateHasher() {
1756  return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator());
1757  }
1758 
1759  virtual uint64_t GetHashCode(void* hasher) {
1760  return static_cast<HasherType*>(hasher)->GetHashCode();
1761  }
1762 
1763  virtual void DestroryHasher(void* hasher) {
1764  HasherType* h = static_cast<HasherType*>(hasher);
1765  h->~HasherType();
1766  StateAllocator::Free(h);
1767  }
1768 
1769  virtual void* MallocState(size_t size) {
1770  return GetStateAllocator().Malloc(size);
1771  }
1772 
1773  virtual void FreeState(void* p) {
1774  return StateAllocator::Free(p);
1775  }
1776 
1777 private:
1778  typedef typename SchemaType::Context Context;
1779  typedef GenericValue<UTF8<>, StateAllocator> HashCodeArray;
1781 
1783  const SchemaDocumentType& schemaDocument,
1784  const SchemaType& root,
1786  unsigned depth,
1787 #endif
1788  StateAllocator* allocator = 0,
1789  size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1790  size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1791  :
1792  schemaDocument_(&schemaDocument),
1793  root_(root),
1795  stateAllocator_(allocator),
1796  ownStateAllocator_(0),
1797  schemaStack_(allocator, schemaStackCapacity),
1798  documentStack_(allocator, documentStackCapacity),
1799  valid_(true)
1801  , depth_(depth)
1802 #endif
1803  {
1804  }
1805 
1806  StateAllocator& GetStateAllocator() {
1807  if (!stateAllocator_)
1808  stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator());
1809  return *stateAllocator_;
1810  }
1811 
1812  bool BeginValue() {
1813  if (schemaStack_.Empty())
1814  PushSchema(root_);
1815  else {
1816  if (CurrentContext().inArray)
1817  internal::TokenHelper<internal::Stack<StateAllocator>, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex);
1818 
1819  if (!CurrentSchema().BeginValue(CurrentContext()))
1820  return false;
1821 
1822  SizeType count = CurrentContext().patternPropertiesSchemaCount;
1823  const SchemaType** sa = CurrentContext().patternPropertiesSchemas;
1824  typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
1825  bool valueUniqueness = CurrentContext().valueUniqueness;
1826  if (CurrentContext().valueSchema)
1827  PushSchema(*CurrentContext().valueSchema);
1828 
1829  if (count > 0) {
1830  CurrentContext().objectPatternValidatorType = patternValidatorType;
1831  ISchemaValidator**& va = CurrentContext().patternPropertiesValidators;
1832  SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount;
1833  va = static_cast<ISchemaValidator**>(MallocState(sizeof(ISchemaValidator*) * count));
1834  for (SizeType i = 0; i < count; i++)
1835  va[validatorCount++] = CreateSchemaValidator(*sa[i]);
1836  }
1837 
1838  CurrentContext().arrayUniqueness = valueUniqueness;
1839  }
1840  return true;
1841  }
1842 
1843  bool EndValue() {
1845  return false;
1846 
1847 #if RAPIDJSON_SCHEMA_VERBOSE
1849  schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb);
1850 
1851  *documentStack_.template Push<Ch>() = '\0';
1852  documentStack_.template Pop<Ch>(1);
1853  internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom<Ch>());
1854 #endif
1855 
1856  uint64_t h = CurrentContext().arrayUniqueness ? static_cast<HasherType*>(CurrentContext().hasher)->GetHashCode() : 0;
1857 
1858  PopSchema();
1859 
1860  if (!schemaStack_.Empty()) {
1861  Context& context = CurrentContext();
1862  if (context.valueUniqueness) {
1863  HashCodeArray* a = static_cast<HashCodeArray*>(context.arrayElementHashCodes);
1864  if (!a)
1865  CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType);
1866  for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr)
1867  if (itr->GetUint64() == h)
1868  RAPIDJSON_INVALID_KEYWORD_RETURN(SchemaType::GetUniqueItemsString());
1869  a->PushBack(h, GetStateAllocator());
1870  }
1871  }
1872 
1873  // Remove the last token of document pointer
1874  while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) != '/')
1875  ;
1876 
1877  return true;
1878  }
1879 
1880  void AppendToken(const Ch* str, SizeType len) {
1881  documentStack_.template Reserve<Ch>(1 + len * 2); // worst case all characters are escaped as two characters
1882  *documentStack_.template PushUnsafe<Ch>() = '/';
1883  for (SizeType i = 0; i < len; i++) {
1884  if (str[i] == '~') {
1885  *documentStack_.template PushUnsafe<Ch>() = '~';
1886  *documentStack_.template PushUnsafe<Ch>() = '0';
1887  }
1888  else if (str[i] == '/') {
1889  *documentStack_.template PushUnsafe<Ch>() = '~';
1890  *documentStack_.template PushUnsafe<Ch>() = '1';
1891  }
1892  else
1893  *documentStack_.template PushUnsafe<Ch>() = str[i];
1894  }
1895  }
1896 
1897  RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push<Context>()) Context(*this, &schema); }
1898 
1899  RAPIDJSON_FORCEINLINE void PopSchema() {
1900  Context* c = schemaStack_.template Pop<Context>(1);
1901  if (HashCodeArray* a = static_cast<HashCodeArray*>(c->arrayElementHashCodes)) {
1902  a->~HashCodeArray();
1903  StateAllocator::Free(a);
1904  }
1905  c->~Context();
1906  }
1907 
1908  const SchemaType& CurrentSchema() const { return *schemaStack_.template Top<Context>()->schema; }
1909  Context& CurrentContext() { return *schemaStack_.template Top<Context>(); }
1910  const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); }
1911 
1912  static OutputHandler& GetNullHandler() {
1913  static OutputHandler nullHandler;
1914  return nullHandler;
1915  }
1916 
1917  static const size_t kDefaultSchemaStackCapacity = 1024;
1918  static const size_t kDefaultDocumentStackCapacity = 256;
1919  const SchemaDocumentType* schemaDocument_;
1921  OutputHandler& outputHandler_;
1922  StateAllocator* stateAllocator_;
1923  StateAllocator* ownStateAllocator_;
1926  bool valid_;
1927 #if RAPIDJSON_SCHEMA_VERBOSE
1928  unsigned depth_;
1929 #endif
1930 };
1931 
1933 
1935 // SchemaValidatingReader
1936 
1938 
1947 template <
1948  unsigned parseFlags,
1949  typename InputStream,
1950  typename SourceEncoding,
1951  typename SchemaDocumentType = SchemaDocument,
1952  typename StackAllocator = CrtAllocator>
1954 public:
1955  typedef typename SchemaDocumentType::PointerType PointerType;
1956  typedef typename InputStream::Ch Ch;
1957 
1959 
1963  SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), isValid_(true) {}
1964 
1965  template <typename Handler>
1966  bool operator()(Handler& handler) {
1969  parseResult_ = reader.template Parse<parseFlags>(is_, validator);
1970 
1971  isValid_ = validator.IsValid();
1972  if (isValid_) {
1976  }
1977  else {
1981  }
1982 
1983  return parseResult_;
1984  }
1985 
1986  const ParseResult& GetParseResult() const { return parseResult_; }
1987  bool IsValid() const { return isValid_; }
1991 
1992 private:
1993  InputStream& is_;
1994  const SchemaDocumentType& sd_;
1995 
2000  bool isValid_;
2001 };
2002 
2004 RAPIDJSON_DIAG_POP
2005 
2006 #endif // RAPIDJSON_SCHEMA_H_
Definition: schema.h:133
ValueT ValueType
Definition: schema.h:1322
ISchemaStateFactory< SchemaType > SchemaValidatorFactoryType
Definition: schema.h:263
static void AssignIfExist(SizeType &out, const ValueType &value, const ValueType &name)
Definition: schema.h:977
JSON schema document.
Definition: fwd.h:136
~Schema()
Definition: schema.h:577
Definition: schema.h:932
bool CheckDoubleMultipleOf(Context &context, double d) const
Definition: schema.h:1188
PointerType pointer
Definition: schema.h:1424
StateAllocator * stateAllocator_
Definition: schema.h:1922
union internal::Hasher::Number::U u
bool RawNumber(const Ch *str, SizeType length, bool copy)
Definition: schema.h:1696
GenericSchemaDocument & operator=(const GenericSchemaDocument &)
Prohibit assignment.
GLuint const GLchar * name
Definition: glext.h:6671
Allocator * allocator_
Definition: schema.h:1522
Definition: schema.h:931
bool String(const Ch *str, SizeType len, bool)
Definition: schema.h:190
bool Uint(unsigned u)
Definition: schema.h:174
true
Definition: rapidjson.h:606
A helper class for parsing with validation.
Definition: schema.h:1953
bool valueUniqueness
Definition: schema.h:330
GenericPointer< ValueType, Allocator > PointerType
Definition: schema.h:1328
A type-unsafe stack for storing different types of data.
Definition: stack.h:36
bool additionalItems_
Definition: schema.h:1249
~GenericSchemaDocument()
Destructor.
Definition: schema.h:1393
uint64_t * enum_
Definition: schema.h:1221
bool WriteNumber(const Number &n)
Definition: schema.h:235
PatternProperty * patternProperties_
Definition: schema.h:1233
Definition: schema.h:1197
bool Null(Context &context) const
Definition: schema.h:692
bool EndArray(Context &context, SizeType elementCount) const
Definition: schema.h:868
bool StartArray()
Definition: schema.h:206
StateAllocator * ownStateAllocator_
Definition: schema.h:1923
Definition: schema.h:226
const SchemaType & GetRoot() const
Get the root schema.
Definition: schema.h:1401
SchemaDocumentType::SchemaType SchemaType
Definition: schema.h:1558
const Ch * GetInvalidSchemaKeyword() const
Gets the keyword of invalid schema.
Definition: schema.h:1642
GLuint buffer
Definition: glext.h:6555
bool StartArray()
Definition: schema.h:1722
const PointerType & GetInvalidDocumentPointer() const
Definition: schema.h:1990
array
Definition: rapidjson.h:608
virtual void DestroryHasher(void *hasher)
Definition: schema.h:1763
static const char * reader(lua_State *L, void *ud, size_t *size)
Definition: luac.c:122
Definition: schema.h:148
bool Key(const Ch *str, SizeType len, bool copy)
Definition: schema.h:196
string
Definition: rapidjson.h:609
bool EndObject(SizeType memberCount)
Definition: schema.h:1715
bool Double(double d)
Definition: schema.h:1695
virtual void * MallocState(size_t size)=0
IGenericRemoteSchemaDocumentProvider< SchemaDocument > IRemoteSchemaDocumentProvider
IGenericRemoteSchemaDocumentProvider using SchemaDocument.
Definition: schema.h:1532
const PointerType & GetInvalidSchemaPointer() const
Definition: schema.h:1988
StateAllocator & GetStateAllocator()
Definition: schema.h:1806
def macros
Definition: glgen.py:97
virtual const SchemaDocumentType * GetRemoteDocument(const Ch *uri, SizeType length)=0
virtual ~ISchemaStateFactory()
Definition: schema.h:150
SchemaDocumentType::PointerType PointerType
Definition: schema.h:342
static const size_t kDefaultSchemaStackCapacity
Definition: schema.h:1917
virtual void FreeState(void *p)
Definition: schema.h:1773
bool Bool(bool b)
Definition: schema.h:1690
bool StartObject()
Definition: schema.h:1701
bool Key(Context &context, const Ch *str, SizeType len, bool) const
Definition: schema.h:783
bool Uint64(uint64_t u)
Definition: schema.h:176
OutputHandler & outputHandler_
Definition: schema.h:1921
#define RAPIDJSON_NEW(x)
! customization point for global new
Definition: rapidjson.h:586
Allocator AllocatorType
Definition: schema.h:1324
SchemaValueType
Definition: schema.h:925
ValueType::EncodingType EncodingType
Definition: schema.h:1325
GLdouble GLdouble GLdouble r
Definition: glext.h:6406
SizeType itemsTupleCount_
Definition: schema.h:1246
ValueType::Ch Ch
Definition: schema.h:265
Definition: schema.h:1416
GLdouble GLdouble t
Definition: glext.h:6398
PointerType GetInvalidSchemaPointer() const
Gets the JSON pointer pointed to the invalid schema.
Definition: schema.h:1637
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Constructor without output handler.
Definition: schema.h:1570
Schema(SchemaDocumentType *schemaDocument, const PointerType &p, const ValueType &value, const ValueType &document, AllocatorType *allocator)
Definition: schema.h:350
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
Definition: schema.h:1277
GLenum GLsizei len
Definition: glext.h:7389
bool WriteType(Type type)
Definition: schema.h:233
false
Definition: rapidjson.h:605
static bool IsPatternMatch(const RegexType *pattern, const Ch *str, SizeType)
Definition: schema.h:1013
bool hasSchemaDependencies_
Definition: schema.h:1241
const SchemaType ** schema
Definition: schema.h:1413
Definition: schema.h:1264
#define P(a, b, c, d, k, s, t)
const Context & CurrentContext() const
Definition: schema.h:1910
bool exclusiveMinimum_
Definition: schema.h:1259
virtual ISchemaValidator * CreateSchemaValidator(const SchemaType &root)
Definition: schema.h:1741
static OutputHandler & GetNullHandler()
Definition: schema.h:1912
object
Definition: rapidjson.h:607
size_t GetSize() const
Definition: stack.h:176
GLsizeiptr size
Definition: glext.h:6559
C-runtime library allocator.
Definition: allocators.h:62
PointerType target
Definition: schema.h:1412
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, const SchemaType &root, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Definition: schema.h:1782
GLfloat f
Definition: glext.h:8207
bool isValid_
Definition: schema.h:2000
char * u64toa(uint64_t value, char *buffer)
Definition: itoa.h:123
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp local skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if
Definition: pixman-arm-neon-asm.h:543
Definition: schema.h:944
SchemaArray allOf_
Definition: schema.h:1223
Definition: schema.h:225
double d
Definition: schema.h:230
SchemaValidationContext< SchemaDocumentType > Context
Definition: schema.h:345
int memcmp(const void *s1, const void *s2, unsigned int length)
Definition: compat_ctype.c:51
static const size_t kDefaultSize
Definition: schema.h:224
void * arrayElementHashCodes
Definition: schema.h:318
GLdouble s
Definition: glext.h:6390
Schema< SchemaDocumentType > SchemaType
Definition: schema.h:262
bool CheckInt(Context &context, int64_t i) const
Definition: schema.h:1099
char * u32toa(uint32_t value, char *buffer)
Definition: itoa.h:39
bool EndObject(SizeType memberCount)
Definition: schema.h:197
struct passwd out
Definition: missing_libc_functions.c:51
#define floor(x)
Definition: math.h:25
GLsizei const GLvoid * pointer
Definition: glext.h:6488
SValue maximum_
Definition: schema.h:1257
bool Uint64(uint64_t u)
Definition: schema.h:1694
GenericValue< UTF8<>, StateAllocator > HashCodeArray
Definition: schema.h:1779
RegexType * pattern_
Definition: schema.h:1252
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, OutputHandler &outputHandler, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Constructor with output handler.
Definition: schema.h:1597
ISchemaValidator ** patternPropertiesValidators
Definition: schema.h:321
SchemaValidationContext(SchemaValidatorFactoryType &f, const SchemaType *s)
Definition: schema.h:273
internal::Stack< StateAllocator > documentStack_
stack to store the current path of validating document (Ch)
Definition: schema.h:1925
Definition: ibxm.h:9
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:119
virtual ~IGenericRemoteSchemaDocumentProvider()
Definition: schema.h:1303
Definition: schema.h:1409
ISchemaValidator ** validators
Definition: schema.h:319
static const ValueType * GetMember(const ValueType &value, const ValueType &name)
Definition: schema.h:966
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:6303
const GLubyte * c
Definition: glext.h:9812
virtual ISchemaValidator * CreateSchemaValidator(const SchemaType &)=0
GLboolean GLboolean GLboolean b
Definition: glext.h:6844
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
Definition: schema.h:928
GLuint GLuint GLsizei count
Definition: glext.h:6292
bool CreateParallelValidator(Context &context) const
Definition: schema.h:1049
SizeType patternPropertyCount_
Definition: schema.h:1234
bool Double(Context &context, double d) const
Definition: schema.h:728
Definition: schema.h:1208
SizeType validatorCount_
Definition: schema.h:1228
bool EndObject(Context &context, SizeType memberCount) const
Definition: schema.h:828
bool EndArray(SizeType elementCount)
Definition: schema.h:207
static const SchemaType * GetTypeless()
Definition: schema.h:952
~GenericSchemaValidator()
Destructor.
Definition: schema.h:1619
null
Definition: rapidjson.h:604
internal::Stack< Allocator > schemaMap_
Definition: schema.h:1525
internal::Stack< StateAllocator > schemaStack_
stack to store the current path of schema (BaseSchemaType *)
Definition: schema.h:1924
SizeType notValidatorIndex_
Definition: schema.h:1229
Hasher(Allocator *allocator=0, size_t stackCapacity=kDefaultSize)
Definition: schema.h:169
~PatternProperty()
Definition: schema.h:1210
static uint64_t Hash(uint64_t h, uint64_t d)
Definition: schema.h:247
SizeType maxProperties_
Definition: schema.h:1237
Definition: schema.h:929
void AddType(const ValueType &type)
Definition: schema.h:1039
const ParseResult & GetParseResult() const
Definition: schema.h:1986
void CreateSchemaRecursive(const SchemaType **schema, const PointerType &pointer, const ValueType &v, const ValueType &document)
Definition: schema.h:1429
AllocatorType * allocator_
Definition: schema.h:1220
SizeType arrayElementIndex
Definition: schema.h:327
const SchemaType ** patternPropertiesSchemas
Definition: schema.h:323
Definition: schema.h:927
SchemaDocumentType::PointerType PointerType
Definition: schema.h:1955
Schema< SchemaDocumentType > SchemaType
Definition: schema.h:346
virtual void * MallocState(size_t size)
Definition: schema.h:1769
SizeType maxLength_
Definition: schema.h:1254
#define RAPIDJSON_SCHEMA_VERBOSE
Definition: schema.h:47
GLenum type
Definition: glext.h:6233
const Ch * invalidSchemaKeyword_
Definition: schema.h:1998
bool RawNumber(const Ch *str, SizeType len, bool)
Definition: schema.h:185
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp local skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
Definition: pixman-arm-neon-asm.h:469
bool String(Context &context, const Ch *str, SizeType length, bool) const
Definition: schema.h:744
bool l
Definition: connect_wiiupro.c:37
SchemaArray anyOf_
Definition: schema.h:1224
const SchemaType & CurrentSchema() const
Definition: schema.h:1908
Definition: schema.h:933
SizeType enumCount_
Definition: schema.h:1222
bool valid_
Definition: schema.h:1926
bool Int64(int64_t i)
Definition: schema.h:1693
void * hasher
Definition: schema.h:317
SizeType validatorCount
Definition: schema.h:320
void Clear()
Definition: stack.h:98
virtual void DestroryHasher(void *hasher)=0
virtual uint64_t GetHashCode(void *hasher)=0
const SchemaType * schema
Definition: schema.h:1216
bool StartObject()
Definition: schema.h:195
bool Int(Context &context, int i) const
Definition: schema.h:704
PatternValidatorType objectPatternValidatorType
Definition: schema.h:326
SchemaType::Context Context
Definition: schema.h:1778
bool BeginValue(Context &context) const
Definition: schema.h:600
Definition: schema.h:926
bool Int(int i)
Definition: schema.h:173
SchemaType * schema
Definition: schema.h:1425
GenericSchemaDocument< Value > SchemaDocument
GenericSchemaDocument using Value type.
Definition: schema.h:1530
SValue multipleOf_
Definition: schema.h:1258
bool exclusiveMaximum_
Definition: schema.h:1260
bool WriteBuffer(Type type, const void *data, size_t len)
Definition: schema.h:237
const SchemaType * dependenciesSchema
Definition: schema.h:1202
bool hasDependencies_
Definition: schema.h:1239
number
Definition: rapidjson.h:610
PatternValidatorType valuePatternValidatorType
Definition: schema.h:325
Default implementation of Handler.
Definition: fwd.h:85
const SchemaDocumentType * schemaDocument_
Definition: schema.h:1919
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
Definition: schema.h:1265
const Ch * GetString() const
Definition: stringbuffer.h:73
PatternValidatorType
Definition: schema.h:267
GenericSchemaValidator< SchemaDocument > SchemaValidator
Definition: schema.h:1932
const SchemaType * schema
Definition: schema.h:1201
bool uniqueItems_
Definition: schema.h:1250
PatternProperty()
Definition: schema.h:1209
RAPIDJSON_FORCEINLINE bool EndValue(Context &context) const
Definition: schema.h:625
bool StartObject(Context &context) const
Definition: schema.h:764
void CreateSchema(const SchemaType **schema, const PointerType &pointer, const ValueType &v, const ValueType &document)
Definition: schema.h:1446
const SchemaDocumentType & sd_
Definition: schema.h:1994
bool required
Definition: schema.h:1205
virtual void DestroySchemaValidator(ISchemaValidator *validator)
Definition: schema.h:1749
SizeType patternPropertiesValidatorCount
Definition: schema.h:322
bool EndValue()
Definition: schema.h:1843
bool Key(const Ch *str, SizeType len, bool copy)
Definition: schema.h:1707
GLint GLint GLint GLint GLint GLint y
Definition: glext.h:6295
time_t time(time_t *timer)
bool Null()
Definition: schema.h:1689
Allocator * ownAllocator_
Definition: schema.h:1523
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:402
SValue minimum_
Definition: schema.h:1256
SchemaArray oneOf_
Definition: schema.h:1225
GLint GLint GLint GLint GLint x
Definition: glext.h:6295
static void AssignIfExist(bool &out, const ValueType &value, const ValueType &name)
Definition: schema.h:971
GLdouble GLdouble GLdouble GLdouble q
Definition: glext.h:6414
SizeType count
Definition: schema.h:949
SchemaType::EncodingType EncodingType
Definition: schema.h:1560
SizeType minProperties_
Definition: schema.h:1236
Definition: document.h:391
bool Int64(Context &context, int64_t i) const
Definition: schema.h:716
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glext.h:6293
bool inArray
Definition: schema.h:329
~SchemaValidationContext()
Definition: schema.h:294
SchemaEntry(const PointerType &p, SchemaType *s, bool o, Allocator *allocator)
Definition: schema.h:1417
const SchemaType * not_
Definition: schema.h:1226
bool Empty() const
Definition: stack.h:175
Property()
Definition: schema.h:1198
GLfloat GLfloat p
Definition: glext.h:9809
#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)
Definition: schema.h:1662
ValueType::EncodingType EncodingType
Definition: schema.h:343
bool * dependencies
Definition: schema.h:1204
PointerType GetInvalidDocumentPointer() const
Gets the JSON pointer pointed to the invalid value.
Definition: schema.h:1647
Definition: schema.h:930
virtual ~ISchemaValidator()
Definition: schema.h:140
InputStream::Ch Ch
Definition: schema.h:1956
SizeType minLength_
Definition: schema.h:1253
bool hasRequired_
Definition: schema.h:1240
SizeType begin
Definition: schema.h:948
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:590
bool Bool(Context &context, bool) const
Definition: schema.h:698
bool owned
Definition: schema.h:1426
const SchemaType * additionalPropertiesSchema_
Definition: schema.h:1232
#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)
Definition: schema.h:117
RAPIDJSON_FORCEINLINE void PopSchema()
Definition: schema.h:1899
SizeType propertyCount_
Definition: schema.h:1235
virtual void DestroySchemaValidator(ISchemaValidator *validator)=0
virtual void * CreateHasher()=0
GenericValue< EncodingType, AllocatorType > SValue
Definition: schema.h:347
bool CheckUint(Context &context, uint64_t i) const
Definition: schema.h:1138
GLuint index
Definition: glext.h:6671
#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2)
Definition: schema.h:1684
bool * propertyExist
Definition: schema.h:328
bool BeginValue()
Definition: schema.h:1812
void AddUniqueElement(V1 &a, const V2 &v)
Definition: schema.h:958
PointerType invalidSchemaPointer_
Definition: schema.h:1997
bool CheckDoubleMaximum(Context &context, double d) const
Definition: schema.h:1182
GLsizei GLsizei GLchar * source
Definition: glext.h:6688
Definition: ibxm.h:34
bool Int(int i)
Definition: schema.h:1691
#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)
Definition: schema.h:1681
const GLdouble * v
Definition: glext.h:6391
const SchemaType * additionalItemsSchema_
Definition: schema.h:1243
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:116
bool IsValid() const
Definition: schema.h:1987
Definition: schema.h:138
struct tag_Context Context
Definition: peglib.h:302
bool Bool(bool b)
Definition: schema.h:172
internal::Schema< GenericSchemaDocument > SchemaType
Definition: schema.h:1327
bool String(const Ch *str, SizeType length, bool copy)
Definition: schema.h:1698
internal::GenericRegex< EncodingType > RegexType
Definition: schema.h:937
GLboolean GLboolean g
Definition: glext.h:6844
bool FindPropertyIndex(const ValueType &name, SizeType *outIndex) const
Definition: schema.h:1086
PointerType source
Definition: schema.h:1411
Encoding::Ch Ch
Definition: schema.h:167
GLint j
Definition: nx_glsym.h:307
virtual void FreeState(void *p)=0
bool Double(double d)
Definition: schema.h:177
Stack< Allocator > stack_
Definition: schema.h:254
const SchemaType ** schemas
Definition: schema.h:947
const SchemaType * GetSchema(const PointerType &pointer) const
Definition: schema.h:1504
~Property()
Definition: schema.h:1199
internal::Hasher< EncodingType, StateAllocator > HasherType
Definition: schema.h:1780
RegexType * CreatePattern(const ValueType &value)
Definition: schema.h:1000
const SchemaType ** itemsTuple_
Definition: schema.h:1245
ParseResult parseResult_
Definition: schema.h:1996
void AppendToken(const Ch *str, SizeType len)
Definition: schema.h:1880
SchemaDocumentType::ValueType ValueType
Definition: schema.h:340
InputStream & is_
Definition: schema.h:1993
JSON_Parser_EncodingDetectedHandler handler
Definition: jsonsax_full.h:561
signed __int64 int64_t
Definition: stdint.h:135
SchemaValidatingReader(InputStream &is, const SchemaDocumentType &sd)
Constructor.
Definition: schema.h:1963
EncodingType::Ch Ch
Definition: schema.h:1326
Definition: ffmpeg_fft.c:36
Ιστορικό Εικόνα Πληροφορίες Όλοι Οι Χρήστες Χειρίζονται Το Μενού Αριστερό Αναλογικό Αριστερό Αναλογικό Αριστερό Αναλογικό Y Αριστερό Αναλογικό Δεξί Αναλογικό X Δεξί Αναλογικό Δεξί Αναλογικό Y Δεξί Αναλογικό Σκανδάλη Όπλου Όπλο Aux A Όπλο Aux C Όπλο Select Όπλο D pad Κάτω Όπλο D pad Δεξιά Νεκρή Ζώνη Αναλογικού Σύνδεση Όλων Λήξη Χρόνου Σύνδεσης Hide Unbound Core Input Descriptors Κατάλογος Συσκευών Κατάλογος Ποντικιού Duty Cycle Keyboard Gamepad Mapping Enable Κουμπί D pad κάτω Κουμπί Κουμπί L(πίσω)" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT
RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType &schema)
Definition: schema.h:1897
void CreateSchemaValidators(Context &context, const SchemaArray &schemas) const
Definition: schema.h:1080
bool CheckDoubleMinimum(Context &context, double d) const
Definition: schema.h:1176
Definition: schema.h:261
const SchemaType & root_
Definition: schema.h:1920
#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)
Definition: schema.h:1669
static const size_t kInitialSchemaRefSize
Definition: schema.h:1519
bool EndArray(SizeType elementCount)
Definition: schema.h:1728
bool Uint(unsigned u)
Definition: schema.h:1692
bool Uint(Context &context, unsigned u) const
Definition: schema.h:710
bool Int64(int64_t i)
Definition: schema.h:175
SizeType minItems_
Definition: schema.h:1247
IRemoteSchemaDocumentProviderType * remoteProvider_
Definition: schema.h:1521
PointerType invalidDocumentPointer_
Definition: schema.h:1999
GLsizei const GLfloat * value
Definition: glext.h:6709
SchemaRefEntry(const PointerType &s, const PointerType &t, const SchemaType **outSchema, Allocator *allocator)
Definition: schema.h:1410
unsigned type_
Definition: schema.h:1227
Context & CurrentContext()
Definition: schema.h:1909
const SchemaType * valueSchema
Definition: schema.h:315
bool arrayUniqueness
Definition: schema.h:331
SizeType dependenciesValidatorIndex
Definition: schema.h:1203
const Ch * invalidKeyword
Definition: schema.h:316
EncodingType::Ch Ch
Definition: schema.h:344
virtual uint64_t GetHashCode(void *hasher)
Definition: schema.h:1759
GenericSchemaDocument(const ValueType &document, IRemoteSchemaDocumentProviderType *remoteProvider=0, Allocator *allocator=0)
Constructor.
Definition: schema.h:1341
SchemaArray()
Definition: schema.h:945
const Ch * GetInvalidSchemaKeyword() const
Definition: schema.h:1989
Type
Type of JSON value.
Definition: rapidjson.h:603
EncodingType::Ch Ch
Definition: schema.h:1561
virtual bool IsValid() const
Checks whether the current state is valid.
Definition: schema.h:1634
bool operator()(Handler &handler)
Definition: schema.h:1966
bool additionalProperties_
Definition: schema.h:1238
GLuint GLuint end
Definition: glext.h:6292
PointerType GetPointer(const SchemaType *schema) const
Definition: schema.h:1511
void Reset()
Reset the internal states.
Definition: schema.h:1625
internal::Stack< Allocator > schemaRef_
Definition: schema.h:1526
JSON Schema Validator.
Definition: fwd.h:145
#define false
Definition: ordinals.h:83
bool StartArray(Context &context) const
Definition: schema.h:858
bool Null()
Definition: schema.h:171
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:8390
~SchemaArray()
Definition: schema.h:946
Definition: video4linux2.c:51
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:289
SchemaType::ValueType ValueType
Definition: schema.h:264
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: fwd.h:126
#define true
Definition: ordinals.h:82
bool Uint64(Context &context, uint64_t u) const
Definition: schema.h:722
RegexType * pattern
Definition: schema.h:1217
SchemaDocumentType::AllocatorType AllocatorType
Definition: schema.h:341
SchemaDocumentType::PointerType PointerType
Definition: schema.h:1559
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: fwd.h:88
bool HandleRefSchema(const PointerType &source, const SchemaType **schema, const ValueType &v, const ValueType &document)
Definition: schema.h:1458
const SchemaType * schema
Definition: schema.h:314
void * memset(void *b, int c, size_t len)
Definition: string.c:7
Represents an in-memory output stream.
Definition: fwd.h:59
void AssignIfExist(SchemaArray &out, SchemaDocumentType &schemaDocument, const PointerType &p, const ValueType &value, const ValueType &name, const ValueType &document)
Definition: schema.h:983
unsigned __int64 uint64_t
Definition: stdint.h:136
int64_t i
Definition: schema.h:228
GLenum GLuint GLenum GLsizei length
Definition: glext.h:6233
virtual void * CreateHasher()
Definition: schema.h:1755
Context contains the render state used by various components.
Definition: Context.h:26
GLdouble n
Definition: glext.h:8396
SizeType patternPropertiesSchemaCount
Definition: schema.h:324
~SchemaEntry()
Definition: schema.h:1418
const GLfloat * m
Definition: glext.h:11755
SchemaValidatorFactoryType & factory
Definition: schema.h:313
bool IsValid() const
Definition: schema.h:216
const char *const str
Definition: portlistingparse.c:18
SchemaDocumentType::Ch Ch
Definition: schema.h:1301
#define RAPIDJSON_STRING_(name,...)
Definition: schema.h:881
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6844
Regular expression engine with subset of ECMAscript grammar.
Definition: regex.h:85
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:380
const SchemaType * root_
Root schema.
Definition: schema.h:1524
uint64_t u
Definition: schema.h:227
virtual bool IsValid() const =0
Definition: schema.h:165
SizeType maxItems_
Definition: schema.h:1248
SValue name
Definition: schema.h:1200
IGenericRemoteSchemaDocumentProvider< GenericSchemaDocument > IRemoteSchemaDocumentProviderType
Definition: schema.h:1323
const SchemaType * itemsList_
Definition: schema.h:1244
Property * properties_
Definition: schema.h:1231
uint64_t GetHashCode() const
Definition: schema.h:218
static const size_t kInitialSchemaMapSize
Definition: schema.h:1518
static const size_t kDefaultDocumentStackCapacity
Definition: schema.h:1918