Monero
Loading...
Searching...
No Matches
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 "stringbuffer.h"
21#include <cmath> // abs, floor
22
23#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX)
24#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1
25#else
26#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0
27#endif
28
29#if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800))
30#define RAPIDJSON_SCHEMA_USE_STDREGEX 1
31#else
32#define RAPIDJSON_SCHEMA_USE_STDREGEX 0
33#endif
34
35#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX
36#include "internal/regex.h"
37#elif RAPIDJSON_SCHEMA_USE_STDREGEX
38#include <regex>
39#endif
40
41#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX
42#define RAPIDJSON_SCHEMA_HAS_REGEX 1
43#else
44#define RAPIDJSON_SCHEMA_HAS_REGEX 0
45#endif
46
47#ifndef RAPIDJSON_SCHEMA_VERBOSE
48#define RAPIDJSON_SCHEMA_VERBOSE 0
49#endif
50
51#if RAPIDJSON_SCHEMA_VERBOSE
52#include "stringbuffer.h"
53#endif
54
55RAPIDJSON_DIAG_PUSH
56
57#if defined(__GNUC__)
58RAPIDJSON_DIAG_OFF(effc++)
59#endif
60
61#ifdef __clang__
62RAPIDJSON_DIAG_OFF(weak-vtables)
63RAPIDJSON_DIAG_OFF(exit-time-destructors)
64RAPIDJSON_DIAG_OFF(c++98-compat-pedantic)
65RAPIDJSON_DIAG_OFF(variadic-macros)
66#elif defined(_MSC_VER)
67RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
68#endif
69
71
73// Verbose Utilities
74
75#if RAPIDJSON_SCHEMA_VERBOSE
76
77namespace internal {
78
79inline void PrintInvalidKeyword(const char* keyword) {
80 printf("Fail keyword: %s\n", keyword);
81}
82
83inline void PrintInvalidKeyword(const wchar_t* keyword) {
84 wprintf(L"Fail keyword: %ls\n", keyword);
85}
86
87inline void PrintInvalidDocument(const char* document) {
88 printf("Fail document: %s\n\n", document);
89}
90
91inline void PrintInvalidDocument(const wchar_t* document) {
92 wprintf(L"Fail document: %ls\n\n", document);
93}
94
95inline void PrintValidatorPointers(unsigned depth, const char* s, const char* d) {
96 printf("S: %*s%s\nD: %*s%s\n\n", depth * 4, " ", s, depth * 4, " ", d);
97}
98
99inline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar_t* d) {
100 wprintf(L"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L" ", s, depth * 4, L" ", d);
101}
102
103} // namespace internal
104
105#endif // RAPIDJSON_SCHEMA_VERBOSE
106
108// RAPIDJSON_INVALID_KEYWORD_RETURN
109
110#if RAPIDJSON_SCHEMA_VERBOSE
111#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword)
112#else
113#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword)
114#endif
115
116#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\
117RAPIDJSON_MULTILINEMACRO_BEGIN\
118 context.invalidKeyword = keyword.GetString();\
119 RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\
120 return false;\
121RAPIDJSON_MULTILINEMACRO_END
122
124// Forward declarations
125
126template <typename ValueType, typename Allocator>
128
129namespace internal {
130
131template <typename SchemaDocumentType>
132class Schema;
133
135// ISchemaValidator
136
138public:
139 virtual ~ISchemaValidator() {}
140 virtual bool IsValid() const = 0;
141};
142
144// ISchemaStateFactory
145
146template <typename SchemaType>
148public:
150 virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0;
151 virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0;
152 virtual void* CreateHasher() = 0;
153 virtual uint64_t GetHashCode(void* hasher) = 0;
154 virtual void DestroryHasher(void* hasher) = 0;
155 virtual void* MallocState(size_t size) = 0;
156 virtual void FreeState(void* p) = 0;
157};
158
160// IValidationErrorHandler
161
162template <typename SchemaType>
164public:
165 typedef typename SchemaType::Ch Ch;
166 typedef typename SchemaType::SValue SValue;
167
169
170 virtual void NotMultipleOf(int64_t actual, const SValue& expected) = 0;
171 virtual void NotMultipleOf(uint64_t actual, const SValue& expected) = 0;
172 virtual void NotMultipleOf(double actual, const SValue& expected) = 0;
173 virtual void AboveMaximum(int64_t actual, const SValue& expected, bool exclusive) = 0;
174 virtual void AboveMaximum(uint64_t actual, const SValue& expected, bool exclusive) = 0;
175 virtual void AboveMaximum(double actual, const SValue& expected, bool exclusive) = 0;
176 virtual void BelowMinimum(int64_t actual, const SValue& expected, bool exclusive) = 0;
177 virtual void BelowMinimum(uint64_t actual, const SValue& expected, bool exclusive) = 0;
178 virtual void BelowMinimum(double actual, const SValue& expected, bool exclusive) = 0;
179
180 virtual void TooLong(const Ch* str, SizeType length, SizeType expected) = 0;
181 virtual void TooShort(const Ch* str, SizeType length, SizeType expected) = 0;
182 virtual void DoesNotMatch(const Ch* str, SizeType length) = 0;
183
184 virtual void DisallowedItem(SizeType index) = 0;
185 virtual void TooFewItems(SizeType actualCount, SizeType expectedCount) = 0;
186 virtual void TooManyItems(SizeType actualCount, SizeType expectedCount) = 0;
187 virtual void DuplicateItems(SizeType index1, SizeType index2) = 0;
188
189 virtual void TooManyProperties(SizeType actualCount, SizeType expectedCount) = 0;
190 virtual void TooFewProperties(SizeType actualCount, SizeType expectedCount) = 0;
191 virtual void StartMissingProperties() = 0;
192 virtual void AddMissingProperty(const SValue& name) = 0;
193 virtual bool EndMissingProperties() = 0;
194 virtual void PropertyViolations(ISchemaValidator** subvalidators, SizeType count) = 0;
195 virtual void DisallowedProperty(const Ch* name, SizeType length) = 0;
196
197 virtual void StartDependencyErrors() = 0;
199 virtual void AddMissingDependentProperty(const SValue& targetName) = 0;
200 virtual void EndMissingDependentProperties(const SValue& sourceName) = 0;
201 virtual void AddDependencySchemaError(const SValue& souceName, ISchemaValidator* subvalidator) = 0;
202 virtual bool EndDependencyErrors() = 0;
203
204 virtual void DisallowedValue() = 0;
205 virtual void StartDisallowedType() = 0;
206 virtual void AddExpectedType(const typename SchemaType::ValueType& expectedType) = 0;
207 virtual void EndDisallowedType(const typename SchemaType::ValueType& actualType) = 0;
208 virtual void NotAllOf(ISchemaValidator** subvalidators, SizeType count) = 0;
209 virtual void NoneOf(ISchemaValidator** subvalidators, SizeType count) = 0;
210 virtual void NotOneOf(ISchemaValidator** subvalidators, SizeType count) = 0;
211 virtual void Disallowed() = 0;
212};
213
214
216// Hasher
217
218// For comparison of compound value
219template<typename Encoding, typename Allocator>
220class Hasher {
221public:
222 typedef typename Encoding::Ch Ch;
223
224 Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {}
225
226 bool Null() { return WriteType(kNullType); }
227 bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); }
228 bool Int(int i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }
229 bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }
230 bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }
231 bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }
232 bool Double(double d) {
233 Number n;
234 if (d < 0) n.u.i = static_cast<int64_t>(d);
235 else n.u.u = static_cast<uint64_t>(d);
236 n.d = d;
237 return WriteNumber(n);
238 }
239
240 bool RawNumber(const Ch* str, SizeType len, bool) {
241 WriteBuffer(kNumberType, str, len * sizeof(Ch));
242 return true;
243 }
244
245 bool String(const Ch* str, SizeType len, bool) {
246 WriteBuffer(kStringType, str, len * sizeof(Ch));
247 return true;
248 }
249
250 bool StartObject() { return true; }
251 bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); }
252 bool EndObject(SizeType memberCount) {
254 uint64_t* kv = stack_.template Pop<uint64_t>(memberCount * 2);
255 for (SizeType i = 0; i < memberCount; i++)
256 h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive
257 *stack_.template Push<uint64_t>() = h;
258 return true;
259 }
260
261 bool StartArray() { return true; }
262 bool EndArray(SizeType elementCount) {
264 uint64_t* e = stack_.template Pop<uint64_t>(elementCount);
265 for (SizeType i = 0; i < elementCount; i++)
266 h = Hash(h, e[i]); // Use hash to achieve element order sensitive
267 *stack_.template Push<uint64_t>() = h;
268 return true;
269 }
270
271 bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); }
272
275 return *stack_.template Top<uint64_t>();
276 }
277
278private:
279 static const size_t kDefaultSize = 256;
280 struct Number {
285 double d;
286 };
287
288 bool WriteType(Type type) { return WriteBuffer(type, 0, 0); }
289
290 bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); }
291
292 bool WriteBuffer(Type type, const void* data, size_t len) {
293 // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/
294 uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type);
295 const unsigned char* d = static_cast<const unsigned char*>(data);
296 for (size_t i = 0; i < len; i++)
297 h = Hash(h, d[i]);
298 *stack_.template Push<uint64_t>() = h;
299 return true;
300 }
301
303 static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3);
304 h ^= d;
305 h *= kPrime;
306 return h;
307 }
308
310};
311
313// SchemaValidationContext
314
315template <typename SchemaDocumentType>
321 typedef typename ValueType::Ch Ch;
322
328
350
352 if (hasher)
353 factory.DestroryHasher(hasher);
354 if (validators) {
355 for (SizeType i = 0; i < validatorCount; i++)
356 factory.DestroySchemaValidator(validators[i]);
357 factory.FreeState(validators);
358 }
360 for (SizeType i = 0; i < patternPropertiesValidatorCount; i++)
361 factory.DestroySchemaValidator(patternPropertiesValidators[i]);
363 }
366 if (propertyExist)
367 factory.FreeState(propertyExist);
368 }
369
375 void* hasher; // Only validator access
376 void* arrayElementHashCodes; // Only validator access this
390};
391
393// Schema
394
395template <typename SchemaDocumentType>
396class Schema {
397public:
398 typedef typename SchemaDocumentType::ValueType ValueType;
399 typedef typename SchemaDocumentType::AllocatorType AllocatorType;
400 typedef typename SchemaDocumentType::PointerType PointerType;
401 typedef typename ValueType::EncodingType EncodingType;
402 typedef typename EncodingType::Ch Ch;
408
409 Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) :
410 allocator_(allocator),
411 uri_(schemaDocument->GetURI(), *allocator),
412 pointer_(p),
413 typeless_(schemaDocument->GetTypeless()),
414 enum_(),
415 enumCount_(),
416 not_(),
417 type_((1 << kTotalSchemaType) - 1), // typeless
420 properties_(),
429 hasRequired_(),
432 itemsList_(),
433 itemsTuple_(),
435 minItems_(),
436 maxItems_(SizeType(~0)),
439 pattern_(),
440 minLength_(0),
441 maxLength_(~SizeType(0)),
445 {
446 typedef typename SchemaDocumentType::ValueType ValueType;
447 typedef typename ValueType::ConstValueIterator ConstValueIterator;
448 typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
449
450 if (!value.IsObject())
451 return;
452
453 if (const ValueType* v = GetMember(value, GetTypeString())) {
454 type_ = 0;
455 if (v->IsString())
456 AddType(*v);
457 else if (v->IsArray())
458 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
459 AddType(*itr);
460 }
461
462 if (const ValueType* v = GetMember(value, GetEnumString()))
463 if (v->IsArray() && v->Size() > 0) {
464 enum_ = static_cast<uint64_t*>(allocator_->Malloc(sizeof(uint64_t) * v->Size()));
465 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) {
466 typedef Hasher<EncodingType, MemoryPoolAllocator<> > EnumHasherType;
467 char buffer[256 + 24];
468 MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer));
469 EnumHasherType h(&hasherAllocator, 256);
470 itr->Accept(h);
471 enum_[enumCount_++] = h.GetHashCode();
472 }
473 }
474
475 if (schemaDocument) {
476 AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document);
477 AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document);
478 AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document);
479 }
480
481 if (const ValueType* v = GetMember(value, GetNotString())) {
482 schemaDocument->CreateSchema(&not_, p.Append(GetNotString(), allocator_), *v, document);
485 }
486
487 // Object
488
489 const ValueType* properties = GetMember(value, GetPropertiesString());
490 const ValueType* required = GetMember(value, GetRequiredString());
491 const ValueType* dependencies = GetMember(value, GetDependenciesString());
492 {
493 // Gather properties from properties/required/dependencies
494 SValue allProperties(kArrayType);
495
496 if (properties && properties->IsObject())
497 for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr)
498 AddUniqueElement(allProperties, itr->name);
499
500 if (required && required->IsArray())
501 for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
502 if (itr->IsString())
503 AddUniqueElement(allProperties, *itr);
504
505 if (dependencies && dependencies->IsObject())
506 for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {
507 AddUniqueElement(allProperties, itr->name);
508 if (itr->value.IsArray())
509 for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i)
510 if (i->IsString())
511 AddUniqueElement(allProperties, *i);
512 }
513
514 if (allProperties.Size() > 0) {
515 propertyCount_ = allProperties.Size();
516 properties_ = static_cast<Property*>(allocator_->Malloc(sizeof(Property) * propertyCount_));
517 for (SizeType i = 0; i < propertyCount_; i++) {
518 new (&properties_[i]) Property();
519 properties_[i].name = allProperties[i];
520 properties_[i].schema = typeless_;
521 }
522 }
523 }
524
525 if (properties && properties->IsObject()) {
526 PointerType q = p.Append(GetPropertiesString(), allocator_);
527 for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) {
528 SizeType index;
529 if (FindPropertyIndex(itr->name, &index))
530 schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document);
531 }
532 }
533
534 if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) {
535 PointerType q = p.Append(GetPatternPropertiesString(), allocator_);
536 patternProperties_ = static_cast<PatternProperty*>(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount()));
538
539 for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {
542 schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value, document);
544 }
545 }
546
547 if (required && required->IsArray())
548 for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
549 if (itr->IsString()) {
550 SizeType index;
551 if (FindPropertyIndex(*itr, &index)) {
552 properties_[index].required = true;
553 hasRequired_ = true;
554 }
555 }
556
557 if (dependencies && dependencies->IsObject()) {
558 PointerType q = p.Append(GetDependenciesString(), allocator_);
559 hasDependencies_ = true;
560 for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {
561 SizeType sourceIndex;
562 if (FindPropertyIndex(itr->name, &sourceIndex)) {
563 if (itr->value.IsArray()) {
564 properties_[sourceIndex].dependencies = static_cast<bool*>(allocator_->Malloc(sizeof(bool) * propertyCount_));
565 std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_);
566 for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) {
567 SizeType targetIndex;
568 if (FindPropertyIndex(*targetItr, &targetIndex))
569 properties_[sourceIndex].dependencies[targetIndex] = true;
570 }
571 }
572 else if (itr->value.IsObject()) {
574 schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document);
575 properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_;
577 }
578 }
579 }
580 }
581
582 if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) {
583 if (v->IsBool())
584 additionalProperties_ = v->GetBool();
585 else if (v->IsObject())
586 schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document);
587 }
588
589 AssignIfExist(minProperties_, value, GetMinPropertiesString());
590 AssignIfExist(maxProperties_, value, GetMaxPropertiesString());
591
592 // Array
593 if (const ValueType* v = GetMember(value, GetItemsString())) {
594 PointerType q = p.Append(GetItemsString(), allocator_);
595 if (v->IsObject()) // List validation
596 schemaDocument->CreateSchema(&itemsList_, q, *v, document);
597 else if (v->IsArray()) { // Tuple validation
598 itemsTuple_ = static_cast<const Schema**>(allocator_->Malloc(sizeof(const Schema*) * v->Size()));
599 SizeType index = 0;
600 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++)
601 schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document);
602 }
603 }
604
605 AssignIfExist(minItems_, value, GetMinItemsString());
606 AssignIfExist(maxItems_, value, GetMaxItemsString());
607
608 if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) {
609 if (v->IsBool())
610 additionalItems_ = v->GetBool();
611 else if (v->IsObject())
612 schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document);
613 }
614
615 AssignIfExist(uniqueItems_, value, GetUniqueItemsString());
616
617 // String
618 AssignIfExist(minLength_, value, GetMinLengthString());
619 AssignIfExist(maxLength_, value, GetMaxLengthString());
620
621 if (const ValueType* v = GetMember(value, GetPatternString()))
623
624 // Number
625 if (const ValueType* v = GetMember(value, GetMinimumString()))
626 if (v->IsNumber())
627 minimum_.CopyFrom(*v, *allocator_);
628
629 if (const ValueType* v = GetMember(value, GetMaximumString()))
630 if (v->IsNumber())
631 maximum_.CopyFrom(*v, *allocator_);
632
633 AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString());
634 AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString());
635
636 if (const ValueType* v = GetMember(value, GetMultipleOfString()))
637 if (v->IsNumber() && v->GetDouble() > 0.0)
638 multipleOf_.CopyFrom(*v, *allocator_);
639
640 // Default
641 if (const ValueType* v = GetMember(value, GetDefaultValueString()))
642 if (v->IsString())
643 defaultValueLength_ = v->GetStringLength();
644
645 }
646
648 AllocatorType::Free(enum_);
649 if (properties_) {
650 for (SizeType i = 0; i < propertyCount_; i++)
651 properties_[i].~Property();
652 AllocatorType::Free(properties_);
653 }
654 if (patternProperties_) {
655 for (SizeType i = 0; i < patternPropertyCount_; i++)
656 patternProperties_[i].~PatternProperty();
657 AllocatorType::Free(patternProperties_);
658 }
659 AllocatorType::Free(itemsTuple_);
660#if RAPIDJSON_SCHEMA_HAS_REGEX
661 if (pattern_) {
662 pattern_->~RegexType();
663 AllocatorType::Free(pattern_);
664 }
665#endif
666 }
667
668 const SValue& GetURI() const {
669 return uri_;
670 }
671
672 const PointerType& GetPointer() const {
673 return pointer_;
674 }
675
676 bool BeginValue(Context& context) const {
677 if (context.inArray) {
678 if (uniqueItems_)
679 context.valueUniqueness = true;
680
681 if (itemsList_)
682 context.valueSchema = itemsList_;
683 else if (itemsTuple_) {
684 if (context.arrayElementIndex < itemsTupleCount_)
685 context.valueSchema = itemsTuple_[context.arrayElementIndex];
686 else if (additionalItemsSchema_)
687 context.valueSchema = additionalItemsSchema_;
688 else if (additionalItems_)
689 context.valueSchema = typeless_;
690 else {
691 context.error_handler.DisallowedItem(context.arrayElementIndex);
692 RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString());
693 }
694 }
695 else
696 context.valueSchema = typeless_;
697
698 context.arrayElementIndex++;
699 }
700 return true;
701 }
702
703 RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const {
704 if (context.patternPropertiesValidatorCount > 0) {
705 bool otherValid = false;
706 SizeType count = context.patternPropertiesValidatorCount;
707 if (context.objectPatternValidatorType != Context::kPatternValidatorOnly)
708 otherValid = context.patternPropertiesValidators[--count]->IsValid();
709
710 bool patternValid = true;
711 for (SizeType i = 0; i < count; i++)
712 if (!context.patternPropertiesValidators[i]->IsValid()) {
713 patternValid = false;
714 break;
715 }
716
717 if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) {
718 if (!patternValid) {
719 context.error_handler.PropertyViolations(context.patternPropertiesValidators, count);
720 RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
721 }
722 }
723 else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) {
724 if (!patternValid || !otherValid) {
725 context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1);
726 RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
727 }
728 }
729 else if (!patternValid && !otherValid) { // kPatternValidatorWithAdditionalProperty)
730 context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1);
731 RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
732 }
733 }
734
735 if (enum_) {
736 const uint64_t h = context.factory.GetHashCode(context.hasher);
737 for (SizeType i = 0; i < enumCount_; i++)
738 if (enum_[i] == h)
739 goto foundEnum;
740 context.error_handler.DisallowedValue();
741 RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString());
742 foundEnum:;
743 }
744
745 if (allOf_.schemas)
746 for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++)
747 if (!context.validators[i]->IsValid()) {
748 context.error_handler.NotAllOf(&context.validators[allOf_.begin], allOf_.count);
749 RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString());
750 }
751
752 if (anyOf_.schemas) {
753 for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)
754 if (context.validators[i]->IsValid())
755 goto foundAny;
756 context.error_handler.NoneOf(&context.validators[anyOf_.begin], anyOf_.count);
757 RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString());
758 foundAny:;
759 }
760
761 if (oneOf_.schemas) {
762 bool oneValid = false;
763 for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++)
764 if (context.validators[i]->IsValid()) {
765 if (oneValid) {
766 context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count);
767 RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());
768 } else
769 oneValid = true;
770 }
771 if (!oneValid) {
772 context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count);
773 RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());
774 }
775 }
776
777 if (not_ && context.validators[notValidatorIndex_]->IsValid()) {
778 context.error_handler.Disallowed();
779 RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString());
780 }
781
782 return true;
783 }
784
785 bool Null(Context& context) const {
786 if (!(type_ & (1 << kNullSchemaType))) {
787 DisallowedType(context, GetNullString());
788 RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
789 }
790 return CreateParallelValidator(context);
791 }
792
793 bool Bool(Context& context, bool) const {
794 if (!(type_ & (1 << kBooleanSchemaType))) {
795 DisallowedType(context, GetBooleanString());
796 RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
797 }
798 return CreateParallelValidator(context);
799 }
800
801 bool Int(Context& context, int i) const {
802 if (!CheckInt(context, i))
803 return false;
804 return CreateParallelValidator(context);
805 }
806
807 bool Uint(Context& context, unsigned u) const {
808 if (!CheckUint(context, u))
809 return false;
810 return CreateParallelValidator(context);
811 }
812
813 bool Int64(Context& context, int64_t i) const {
814 if (!CheckInt(context, i))
815 return false;
816 return CreateParallelValidator(context);
817 }
818
819 bool Uint64(Context& context, uint64_t u) const {
820 if (!CheckUint(context, u))
821 return false;
822 return CreateParallelValidator(context);
823 }
824
825 bool Double(Context& context, double d) const {
826 if (!(type_ & (1 << kNumberSchemaType))) {
827 DisallowedType(context, GetNumberString());
828 RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
829 }
830
831 if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d))
832 return false;
833
834 if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d))
835 return false;
836
837 if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d))
838 return false;
839
840 return CreateParallelValidator(context);
841 }
842
843 bool String(Context& context, const Ch* str, SizeType length, bool) const {
844 if (!(type_ & (1 << kStringSchemaType))) {
845 DisallowedType(context, GetStringString());
846 RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
847 }
848
849 if (minLength_ != 0 || maxLength_ != SizeType(~0)) {
850 SizeType count;
852 if (count < minLength_) {
853 context.error_handler.TooShort(str, length, minLength_);
854 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString());
855 }
856 if (count > maxLength_) {
857 context.error_handler.TooLong(str, length, maxLength_);
858 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString());
859 }
860 }
861 }
862
863 if (pattern_ && !IsPatternMatch(pattern_, str, length)) {
864 context.error_handler.DoesNotMatch(str, length);
865 RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString());
866 }
867
868 return CreateParallelValidator(context);
869 }
870
871 bool StartObject(Context& context) const {
872 if (!(type_ & (1 << kObjectSchemaType))) {
873 DisallowedType(context, GetObjectString());
874 RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
875 }
876
878 context.propertyExist = static_cast<bool*>(context.factory.MallocState(sizeof(bool) * propertyCount_));
879 std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_);
880 }
881
882 if (patternProperties_) { // pre-allocate schema array
883 SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType
884 context.patternPropertiesSchemas = static_cast<const SchemaType**>(context.factory.MallocState(sizeof(const SchemaType*) * count));
885 context.patternPropertiesSchemaCount = 0;
886 std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count);
887 }
888
889 return CreateParallelValidator(context);
890 }
891
892 bool Key(Context& context, const Ch* str, SizeType len, bool) const {
893 if (patternProperties_) {
894 context.patternPropertiesSchemaCount = 0;
895 for (SizeType i = 0; i < patternPropertyCount_; i++)
896 if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) {
897 context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema;
898 context.valueSchema = typeless_;
899 }
900 }
901
902 SizeType index;
903 if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {
904 if (context.patternPropertiesSchemaCount > 0) {
905 context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema;
906 context.valueSchema = typeless_;
907 context.valuePatternValidatorType = Context::kPatternValidatorWithProperty;
908 }
909 else
910 context.valueSchema = properties_[index].schema;
911
912 if (context.propertyExist)
913 context.propertyExist[index] = true;
914
915 return true;
916 }
917
919 if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) {
920 context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_;
921 context.valueSchema = typeless_;
922 context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty;
923 }
924 else
925 context.valueSchema = additionalPropertiesSchema_;
926 return true;
927 }
928 else if (additionalProperties_) {
929 context.valueSchema = typeless_;
930 return true;
931 }
932
933 if (context.patternPropertiesSchemaCount == 0) { // patternProperties are not additional properties
934 context.error_handler.DisallowedProperty(str, len);
935 RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString());
936 }
937
938 return true;
939 }
940
941 bool EndObject(Context& context, SizeType memberCount) const {
942 if (hasRequired_) {
943 context.error_handler.StartMissingProperties();
944 for (SizeType index = 0; index < propertyCount_; index++)
945 if (properties_[index].required && !context.propertyExist[index])
946 if (properties_[index].schema->defaultValueLength_ == 0 )
947 context.error_handler.AddMissingProperty(properties_[index].name);
948 if (context.error_handler.EndMissingProperties())
949 RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString());
950 }
951
952 if (memberCount < minProperties_) {
953 context.error_handler.TooFewProperties(memberCount, minProperties_);
954 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString());
955 }
956
957 if (memberCount > maxProperties_) {
958 context.error_handler.TooManyProperties(memberCount, maxProperties_);
959 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString());
960 }
961
962 if (hasDependencies_) {
963 context.error_handler.StartDependencyErrors();
964 for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) {
965 const Property& source = properties_[sourceIndex];
966 if (context.propertyExist[sourceIndex]) {
967 if (source.dependencies) {
968 context.error_handler.StartMissingDependentProperties();
969 for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++)
970 if (source.dependencies[targetIndex] && !context.propertyExist[targetIndex])
971 context.error_handler.AddMissingDependentProperty(properties_[targetIndex].name);
972 context.error_handler.EndMissingDependentProperties(source.name);
973 }
974 else if (source.dependenciesSchema) {
975 ISchemaValidator* dependenciesValidator = context.validators[source.dependenciesValidatorIndex];
976 if (!dependenciesValidator->IsValid())
977 context.error_handler.AddDependencySchemaError(source.name, dependenciesValidator);
978 }
979 }
980 }
981 if (context.error_handler.EndDependencyErrors())
982 RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString());
983 }
984
985 return true;
986 }
987
988 bool StartArray(Context& context) const {
989 if (!(type_ & (1 << kArraySchemaType))) {
990 DisallowedType(context, GetArrayString());
991 RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
992 }
993
994 context.arrayElementIndex = 0;
995 context.inArray = true;
996
997 return CreateParallelValidator(context);
998 }
999
1000 bool EndArray(Context& context, SizeType elementCount) const {
1001 context.inArray = false;
1002
1003 if (elementCount < minItems_) {
1004 context.error_handler.TooFewItems(elementCount, minItems_);
1005 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString());
1006 }
1007
1008 if (elementCount > maxItems_) {
1009 context.error_handler.TooManyItems(elementCount, maxItems_);
1010 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString());
1011 }
1012
1013 return true;
1014 }
1015
1016 // Generate functions for string literal according to Ch
1017#define RAPIDJSON_STRING_(name, ...) \
1018 static const ValueType& Get##name##String() {\
1019 static const Ch s[] = { __VA_ARGS__, '\0' };\
1020 static const ValueType v(s, static_cast<SizeType>(sizeof(s) / sizeof(Ch) - 1));\
1021 return v;\
1022 }
1023
1024 RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l')
1025 RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n')
1026 RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't')
1027 RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y')
1028 RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g')
1029 RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r')
1030 RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r')
1031 RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e')
1032 RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm')
1033 RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f')
1034 RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f')
1035 RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f')
1036 RAPIDJSON_STRING_(Not, 'n', 'o', 't')
1037 RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
1038 RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd')
1039 RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's')
1040 RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
1041 RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
1042 RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
1043 RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
1044 RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's')
1045 RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's')
1046 RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's')
1047 RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's')
1048 RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's')
1049 RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h')
1050 RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h')
1051 RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n')
1052 RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm')
1053 RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm')
1054 RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm')
1055 RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm')
1056 RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f')
1057 RAPIDJSON_STRING_(DefaultValue, 'd', 'e', 'f', 'a', 'u', 'l', 't')
1058
1059#undef RAPIDJSON_STRING_
1060
1061private:
1072
1073#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX
1075#elif RAPIDJSON_SCHEMA_USE_STDREGEX
1076 typedef std::basic_regex<Ch> RegexType;
1077#else
1078 typedef char RegexType;
1079#endif
1080
1083 ~SchemaArray() { AllocatorType::Free(schemas); }
1085 SizeType begin; // begin index of context.validators
1087 };
1088
1089 template <typename V1, typename V2>
1090 void AddUniqueElement(V1& a, const V2& v) {
1091 for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
1092 if (*itr == v)
1093 return;
1094 V1 c(v, *allocator_);
1095 a.PushBack(c, *allocator_);
1096 }
1097
1098 static const ValueType* GetMember(const ValueType& value, const ValueType& name) {
1099 typename ValueType::ConstMemberIterator itr = value.FindMember(name);
1100 return itr != value.MemberEnd() ? &(itr->value) : 0;
1101 }
1102
1103 static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) {
1104 if (const ValueType* v = GetMember(value, name))
1105 if (v->IsBool())
1106 out = v->GetBool();
1107 }
1108
1109 static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) {
1110 if (const ValueType* v = GetMember(value, name))
1111 if (v->IsUint64() && v->GetUint64() <= SizeType(~0))
1112 out = static_cast<SizeType>(v->GetUint64());
1113 }
1114
1115 void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) {
1116 if (const ValueType* v = GetMember(value, name)) {
1117 if (v->IsArray() && v->Size() > 0) {
1118 PointerType q = p.Append(name, allocator_);
1119 out.count = v->Size();
1120 out.schemas = static_cast<const Schema**>(allocator_->Malloc(out.count * sizeof(const Schema*)));
1121 memset(out.schemas, 0, sizeof(Schema*)* out.count);
1122 for (SizeType i = 0; i < out.count; i++)
1123 schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document);
1124 out.begin = validatorCount_;
1125 validatorCount_ += out.count;
1126 }
1127 }
1128 }
1129
1130#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX
1131 template <typename ValueType>
1132 RegexType* CreatePattern(const ValueType& value) {
1133 if (value.IsString()) {
1134 RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), allocator_);
1135 if (!r->IsValid()) {
1136 r->~RegexType();
1137 AllocatorType::Free(r);
1138 r = 0;
1139 }
1140 return r;
1141 }
1142 return 0;
1143 }
1144
1145 static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) {
1146 GenericRegexSearch<RegexType> rs(*pattern);
1147 return rs.Search(str);
1148 }
1149#elif RAPIDJSON_SCHEMA_USE_STDREGEX
1150 template <typename ValueType>
1151 RegexType* CreatePattern(const ValueType& value) {
1152 if (value.IsString())
1153 try {
1154 return new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);
1155 }
1156 catch (const std::regex_error&) {
1157 }
1158 return 0;
1159 }
1160
1161 static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) {
1162 std::match_results<const Ch*> r;
1163 return std::regex_search(str, str + length, r, *pattern);
1164 }
1165#else
1166 template <typename ValueType>
1167 RegexType* CreatePattern(const ValueType&) { return 0; }
1168
1169 static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; }
1170#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
1171
1172 void AddType(const ValueType& type) {
1173 if (type == GetNullString() ) type_ |= 1 << kNullSchemaType;
1174 else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType;
1175 else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType;
1176 else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType;
1177 else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType;
1178 else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType;
1179 else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
1180 }
1181
1182 bool CreateParallelValidator(Context& context) const {
1183 if (enum_ || context.arrayUniqueness)
1184 context.hasher = context.factory.CreateHasher();
1185
1186 if (validatorCount_) {
1187 RAPIDJSON_ASSERT(context.validators == 0);
1188 context.validators = static_cast<ISchemaValidator**>(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_));
1189 context.validatorCount = validatorCount_;
1190
1191 if (allOf_.schemas)
1193
1194 if (anyOf_.schemas)
1196
1197 if (oneOf_.schemas)
1199
1200 if (not_)
1201 context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_);
1202
1204 for (SizeType i = 0; i < propertyCount_; i++)
1205 if (properties_[i].dependenciesSchema)
1206 context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema);
1207 }
1208 }
1209
1210 return true;
1211 }
1212
1213 void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const {
1214 for (SizeType i = 0; i < schemas.count; i++)
1215 context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]);
1216 }
1217
1218 // O(n)
1219 bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const {
1220 SizeType len = name.GetStringLength();
1221 const Ch* str = name.GetString();
1222 for (SizeType index = 0; index < propertyCount_; index++)
1223 if (properties_[index].name.GetStringLength() == len &&
1224 (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0))
1225 {
1226 *outIndex = index;
1227 return true;
1228 }
1229 return false;
1230 }
1231
1232 bool CheckInt(Context& context, int64_t i) const {
1233 if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) {
1234 DisallowedType(context, GetIntegerString());
1235 RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
1236 }
1237
1238 if (!minimum_.IsNull()) {
1239 if (minimum_.IsInt64()) {
1240 if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) {
1241 context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
1242 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
1243 }
1244 }
1245 else if (minimum_.IsUint64()) {
1246 context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
1247 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64()
1248 }
1249 else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1250 return false;
1251 }
1252
1253 if (!maximum_.IsNull()) {
1254 if (maximum_.IsInt64()) {
1255 if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) {
1256 context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
1257 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
1258 }
1259 }
1260 else if (maximum_.IsUint64()) { }
1261 /* do nothing */ // i <= max(int64_t) < maximum_.GetUint64()
1262 else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1263 return false;
1264 }
1265
1266 if (!multipleOf_.IsNull()) {
1267 if (multipleOf_.IsUint64()) {
1268 if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) {
1269 context.error_handler.NotMultipleOf(i, multipleOf_);
1270 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
1271 }
1272 }
1273 else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1274 return false;
1275 }
1276
1277 return true;
1278 }
1279
1280 bool CheckUint(Context& context, uint64_t i) const {
1281 if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) {
1282 DisallowedType(context, GetIntegerString());
1283 RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
1284 }
1285
1286 if (!minimum_.IsNull()) {
1287 if (minimum_.IsUint64()) {
1288 if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) {
1289 context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
1290 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
1291 }
1292 }
1293 else if (minimum_.IsInt64())
1294 /* do nothing */; // i >= 0 > minimum.Getint64()
1295 else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1296 return false;
1297 }
1298
1299 if (!maximum_.IsNull()) {
1300 if (maximum_.IsUint64()) {
1301 if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) {
1302 context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
1303 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
1304 }
1305 }
1306 else if (maximum_.IsInt64()) {
1307 context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
1308 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_
1309 }
1310 else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1311 return false;
1312 }
1313
1314 if (!multipleOf_.IsNull()) {
1315 if (multipleOf_.IsUint64()) {
1316 if (i % multipleOf_.GetUint64() != 0) {
1317 context.error_handler.NotMultipleOf(i, multipleOf_);
1318 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
1319 }
1320 }
1321 else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1322 return false;
1323 }
1324
1325 return true;
1326 }
1327
1328 bool CheckDoubleMinimum(Context& context, double d) const {
1329 if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) {
1330 context.error_handler.BelowMinimum(d, minimum_, exclusiveMinimum_);
1331 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
1332 }
1333 return true;
1334 }
1335
1336 bool CheckDoubleMaximum(Context& context, double d) const {
1337 if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) {
1338 context.error_handler.AboveMaximum(d, maximum_, exclusiveMaximum_);
1339 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
1340 }
1341 return true;
1342 }
1343
1344 bool CheckDoubleMultipleOf(Context& context, double d) const {
1345 double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());
1346 double q = std::floor(a / b);
1347 double r = a - q * b;
1348 if (r > 0.0) {
1349 context.error_handler.NotMultipleOf(d, multipleOf_);
1350 RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
1351 }
1352 return true;
1353 }
1354
1355 void DisallowedType(Context& context, const ValueType& actualType) const {
1356 ErrorHandler& eh = context.error_handler;
1358
1359 if (type_ & (1 << kNullSchemaType)) eh.AddExpectedType(GetNullString());
1360 if (type_ & (1 << kBooleanSchemaType)) eh.AddExpectedType(GetBooleanString());
1361 if (type_ & (1 << kObjectSchemaType)) eh.AddExpectedType(GetObjectString());
1362 if (type_ & (1 << kArraySchemaType)) eh.AddExpectedType(GetArrayString());
1363 if (type_ & (1 << kStringSchemaType)) eh.AddExpectedType(GetStringString());
1364
1365 if (type_ & (1 << kNumberSchemaType)) eh.AddExpectedType(GetNumberString());
1366 else if (type_ & (1 << kIntegerSchemaType)) eh.AddExpectedType(GetIntegerString());
1367
1368 eh.EndDisallowedType(actualType);
1369 }
1370
1381
1385 if (pattern) {
1386 pattern->~RegexType();
1387 AllocatorType::Free(pattern);
1388 }
1389 }
1392 };
1393
1400 SchemaArray allOf_;
1401 SchemaArray anyOf_;
1402 SchemaArray oneOf_;
1404 unsigned type_; // bitmask of kSchemaType
1407
1408 Property* properties_;
1410 PatternProperty* patternProperties_;
1419
1428
1432
1438
1440};
1441
1442template<typename Stack, typename Ch>
1444 RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) {
1445 *documentStack.template Push<Ch>() = '/';
1446 char buffer[21];
1447 size_t length = static_cast<size_t>((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer);
1448 for (size_t i = 0; i < length; i++)
1449 *documentStack.template Push<Ch>() = static_cast<Ch>(buffer[i]);
1450 }
1451};
1452
1453// Partial specialized version for char to prevent buffer copying.
1454template <typename Stack>
1455struct TokenHelper<Stack, char> {
1456 RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) {
1457 if (sizeof(SizeType) == 4) {
1458 char *buffer = documentStack.template Push<char>(1 + 10); // '/' + uint
1459 *buffer++ = '/';
1460 const char* end = internal::u32toa(index, buffer);
1461 documentStack.template Pop<char>(static_cast<size_t>(10 - (end - buffer)));
1462 }
1463 else {
1464 char *buffer = documentStack.template Push<char>(1 + 20); // '/' + uint64
1465 *buffer++ = '/';
1466 const char* end = internal::u64toa(index, buffer);
1467 documentStack.template Pop<char>(static_cast<size_t>(20 - (end - buffer)));
1468 }
1469 }
1470};
1471
1472} // namespace internal
1473
1475// IGenericRemoteSchemaDocumentProvider
1476
1477template <typename SchemaDocumentType>
1479public:
1480 typedef typename SchemaDocumentType::Ch Ch;
1481
1483 virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0;
1484};
1485
1487// GenericSchemaDocument
1488
1490
1498template <typename ValueT, typename Allocator = CrtAllocator>
1500public:
1501 typedef ValueT ValueType;
1505 typedef typename EncodingType::Ch Ch;
1510 template <typename, typename, typename>
1512
1514
1523 explicit GenericSchemaDocument(const ValueType& document, const Ch* uri = 0, SizeType uriLength = 0,
1524 IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) :
1525 remoteProvider_(remoteProvider),
1526 allocator_(allocator),
1527 ownAllocator_(),
1528 root_(),
1529 typeless_(),
1532 {
1533 if (!allocator_)
1535
1536 Ch noUri[1] = {0};
1537 uri_.SetString(uri ? uri : noUri, uriLength, *allocator_);
1538
1539 typeless_ = static_cast<SchemaType*>(allocator_->Malloc(sizeof(SchemaType)));
1541
1542 // Generate root schema, it will call CreateSchema() to create sub-schemas,
1543 // And call AddRefSchema() if there are $ref.
1544 CreateSchemaRecursive(&root_, PointerType(), document, document);
1545
1546 // Resolve $ref
1547 while (!schemaRef_.Empty()) {
1548 SchemaRefEntry* refEntry = schemaRef_.template Pop<SchemaRefEntry>(1);
1549 if (const SchemaType* s = GetSchema(refEntry->target)) {
1550 if (refEntry->schema)
1551 *refEntry->schema = s;
1552
1553 // Create entry in map if not exist
1554 if (!GetSchema(refEntry->source)) {
1555 new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(refEntry->source, const_cast<SchemaType*>(s), false, allocator_);
1556 }
1557 }
1558 else if (refEntry->schema)
1559 *refEntry->schema = typeless_;
1560
1561 refEntry->~SchemaRefEntry();
1562 }
1563
1564 RAPIDJSON_ASSERT(root_ != 0);
1565
1566 schemaRef_.ShrinkToFit(); // Deallocate all memory for ref
1567 }
1568
1569#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1571 GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT :
1572 remoteProvider_(rhs.remoteProvider_),
1573 allocator_(rhs.allocator_),
1574 ownAllocator_(rhs.ownAllocator_),
1575 root_(rhs.root_),
1576 typeless_(rhs.typeless_),
1577 schemaMap_(std::move(rhs.schemaMap_)),
1578 schemaRef_(std::move(rhs.schemaRef_)),
1579 uri_(std::move(rhs.uri_))
1580 {
1581 rhs.remoteProvider_ = 0;
1582 rhs.allocator_ = 0;
1583 rhs.ownAllocator_ = 0;
1584 rhs.typeless_ = 0;
1585 }
1586#endif
1587
1590 while (!schemaMap_.Empty())
1591 schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry();
1592
1593 if (typeless_) {
1594 typeless_->~SchemaType();
1595 Allocator::Free(typeless_);
1596 }
1597
1599 }
1600
1601 const URIType& GetURI() const { return uri_; }
1602
1604 const SchemaType& GetRoot() const { return *root_; }
1605
1606private:
1611
1613 SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {}
1617 };
1618
1620 SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {}
1622 if (owned) {
1623 schema->~SchemaType();
1624 Allocator::Free(schema);
1625 }
1626 }
1629 bool owned;
1630 };
1631
1632 void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {
1633 if (schema)
1634 *schema = typeless_;
1635
1636 if (v.GetType() == kObjectType) {
1637 const SchemaType* s = GetSchema(pointer);
1638 if (!s)
1639 CreateSchema(schema, pointer, v, document);
1640
1641 for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
1642 CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document);
1643 }
1644 else if (v.GetType() == kArrayType)
1645 for (SizeType i = 0; i < v.Size(); i++)
1646 CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document);
1647 }
1648
1649 void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {
1650 RAPIDJSON_ASSERT(pointer.IsValid());
1651 if (v.IsObject()) {
1652 if (!HandleRefSchema(pointer, schema, v, document)) {
1653 SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_);
1654 new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(pointer, s, true, allocator_);
1655 if (schema)
1656 *schema = s;
1657 }
1658 }
1659 }
1660
1661 bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document) {
1662 static const Ch kRefString[] = { '$', 'r', 'e', 'f', '\0' };
1663 static const ValueType kRefValue(kRefString, 4);
1664
1665 typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue);
1666 if (itr == v.MemberEnd())
1667 return false;
1668
1669 if (itr->value.IsString()) {
1670 SizeType len = itr->value.GetStringLength();
1671 if (len > 0) {
1672 const Ch* s = itr->value.GetString();
1673 SizeType i = 0;
1674 while (i < len && s[i] != '#') // Find the first #
1675 i++;
1676
1677 if (i > 0) { // Remote reference, resolve immediately
1678 if (remoteProvider_) {
1679 if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i)) {
1680 PointerType pointer(&s[i], len - i, allocator_);
1681 if (pointer.IsValid()) {
1682 if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) {
1683 if (schema)
1684 *schema = sc;
1685 new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(source, const_cast<SchemaType*>(sc), false, allocator_);
1686 return true;
1687 }
1688 }
1689 }
1690 }
1691 }
1692 else if (s[i] == '#') { // Local reference, defer resolution
1693 PointerType pointer(&s[i], len - i, allocator_);
1694 if (pointer.IsValid()) {
1695 if (const ValueType* nv = pointer.Get(document))
1696 if (HandleRefSchema(source, schema, *nv, document))
1697 return true;
1698
1699 new (schemaRef_.template Push<SchemaRefEntry>()) SchemaRefEntry(source, pointer, schema, allocator_);
1700 return true;
1701 }
1702 }
1703 }
1704 }
1705 return false;
1706 }
1707
1709 for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
1710 if (pointer == target->pointer)
1711 return target->schema;
1712 return 0;
1713 }
1714
1715 PointerType GetPointer(const SchemaType* schema) const {
1716 for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
1717 if (schema == target->schema)
1718 return target->pointer;
1719 return PointerType();
1720 }
1721
1722 const SchemaType* GetTypeless() const { return typeless_; }
1723
1724 static const size_t kInitialSchemaMapSize = 64;
1725 static const size_t kInitialSchemaRefSize = 64;
1726
1732 internal::Stack<Allocator> schemaMap_; // Stores created Pointer -> Schemas
1733 internal::Stack<Allocator> schemaRef_; // Stores Pointer from $ref and schema which holds the $ref
1735};
1736
1741
1743// GenericSchemaValidator
1744
1746
1757template <
1758 typename SchemaDocumentType,
1760 typename StateAllocator = CrtAllocator>
1762 public internal::ISchemaStateFactory<typename SchemaDocumentType::SchemaType>,
1764 public internal::IValidationErrorHandler<typename SchemaDocumentType::SchemaType>
1765{
1766public:
1767 typedef typename SchemaDocumentType::SchemaType SchemaType;
1768 typedef typename SchemaDocumentType::PointerType PointerType;
1770 typedef typename SchemaType::SValue SValue;
1771 typedef typename EncodingType::Ch Ch;
1774
1776
1783 const SchemaDocumentType& schemaDocument,
1784 StateAllocator* allocator = 0,
1785 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1786 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1787 :
1788 schemaDocument_(&schemaDocument),
1789 root_(schemaDocument.GetRoot()),
1790 stateAllocator_(allocator),
1792 schemaStack_(allocator, schemaStackCapacity),
1793 documentStack_(allocator, documentStackCapacity),
1794 outputHandler_(0),
1796 currentError_(),
1798 valid_(true)
1800 , depth_(0)
1801#endif
1802 {
1803 }
1804
1806
1813 const SchemaDocumentType& schemaDocument,
1814 OutputHandler& outputHandler,
1815 StateAllocator* allocator = 0,
1816 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1817 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1818 :
1819 schemaDocument_(&schemaDocument),
1820 root_(schemaDocument.GetRoot()),
1821 stateAllocator_(allocator),
1823 schemaStack_(allocator, schemaStackCapacity),
1824 documentStack_(allocator, documentStackCapacity),
1825 outputHandler_(&outputHandler),
1827 currentError_(),
1829 valid_(true)
1831 , depth_(0)
1832#endif
1833 {
1834 }
1835
1841
1843 void Reset() {
1844 while (!schemaStack_.Empty())
1845 PopSchema();
1846 documentStack_.Clear();
1847 error_.SetObject();
1848 currentError_.SetNull();
1849 missingDependents_.SetNull();
1850 valid_ = true;
1851 }
1852
1854 // Implementation of ISchemaValidator
1855 virtual bool IsValid() const { return valid_; }
1856
1859 const ValueType& GetError() const { return error_; }
1860
1863 return schemaStack_.Empty() ? PointerType() : CurrentSchema().GetPointer();
1864 }
1865
1868 return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword;
1869 }
1870
1873 if (documentStack_.Empty()) {
1874 return PointerType();
1875 }
1876 else {
1877 return PointerType(documentStack_.template Bottom<Ch>(), documentStack_.GetSize() / sizeof(Ch));
1878 }
1879 }
1880
1881 void NotMultipleOf(int64_t actual, const SValue& expected) {
1882 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected);
1883 }
1884 void NotMultipleOf(uint64_t actual, const SValue& expected) {
1885 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected);
1886 }
1887 void NotMultipleOf(double actual, const SValue& expected) {
1888 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected);
1889 }
1890 void AboveMaximum(int64_t actual, const SValue& expected, bool exclusive) {
1891 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected,
1892 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
1893 }
1894 void AboveMaximum(uint64_t actual, const SValue& expected, bool exclusive) {
1895 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected,
1896 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
1897 }
1898 void AboveMaximum(double actual, const SValue& expected, bool exclusive) {
1899 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected,
1900 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
1901 }
1902 void BelowMinimum(int64_t actual, const SValue& expected, bool exclusive) {
1903 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected,
1904 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
1905 }
1906 void BelowMinimum(uint64_t actual, const SValue& expected, bool exclusive) {
1907 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected,
1908 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
1909 }
1910 void BelowMinimum(double actual, const SValue& expected, bool exclusive) {
1911 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected,
1912 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
1913 }
1914
1915 void TooLong(const Ch* str, SizeType length, SizeType expected) {
1916 AddNumberError(SchemaType::GetMaxLengthString(),
1917 ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move());
1918 }
1919 void TooShort(const Ch* str, SizeType length, SizeType expected) {
1920 AddNumberError(SchemaType::GetMinLengthString(),
1921 ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move());
1922 }
1923 void DoesNotMatch(const Ch* str, SizeType length) {
1924 currentError_.SetObject();
1925 currentError_.AddMember(GetActualString(), ValueType(str, length, GetStateAllocator()).Move(), GetStateAllocator());
1926 AddCurrentError(SchemaType::GetPatternString());
1927 }
1928
1930 currentError_.SetObject();
1931 currentError_.AddMember(GetDisallowedString(), ValueType(index).Move(), GetStateAllocator());
1932 AddCurrentError(SchemaType::GetAdditionalItemsString(), true);
1933 }
1934 void TooFewItems(SizeType actualCount, SizeType expectedCount) {
1935 AddNumberError(SchemaType::GetMinItemsString(),
1936 ValueType(actualCount).Move(), SValue(expectedCount).Move());
1937 }
1938 void TooManyItems(SizeType actualCount, SizeType expectedCount) {
1939 AddNumberError(SchemaType::GetMaxItemsString(),
1940 ValueType(actualCount).Move(), SValue(expectedCount).Move());
1941 }
1942 void DuplicateItems(SizeType index1, SizeType index2) {
1943 ValueType duplicates(kArrayType);
1944 duplicates.PushBack(index1, GetStateAllocator());
1945 duplicates.PushBack(index2, GetStateAllocator());
1946 currentError_.SetObject();
1947 currentError_.AddMember(GetDuplicatesString(), duplicates, GetStateAllocator());
1948 AddCurrentError(SchemaType::GetUniqueItemsString(), true);
1949 }
1950
1951 void TooManyProperties(SizeType actualCount, SizeType expectedCount) {
1952 AddNumberError(SchemaType::GetMaxPropertiesString(),
1953 ValueType(actualCount).Move(), SValue(expectedCount).Move());
1954 }
1955 void TooFewProperties(SizeType actualCount, SizeType expectedCount) {
1956 AddNumberError(SchemaType::GetMinPropertiesString(),
1957 ValueType(actualCount).Move(), SValue(expectedCount).Move());
1958 }
1960 currentError_.SetArray();
1961 }
1966 if (currentError_.Empty())
1967 return false;
1968 ValueType error(kObjectType);
1969 error.AddMember(GetMissingString(), currentError_, GetStateAllocator());
1970 currentError_ = error;
1971 AddCurrentError(SchemaType::GetRequiredString());
1972 return true;
1973 }
1974 void PropertyViolations(ISchemaValidator** subvalidators, SizeType count) {
1975 for (SizeType i = 0; i < count; ++i)
1976 MergeError(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError());
1977 }
1978 void DisallowedProperty(const Ch* name, SizeType length) {
1979 currentError_.SetObject();
1980 currentError_.AddMember(GetDisallowedString(), ValueType(name, length, GetStateAllocator()).Move(), GetStateAllocator());
1981 AddCurrentError(SchemaType::GetAdditionalPropertiesString(), true);
1982 }
1983
1985 currentError_.SetObject();
1986 }
1988 missingDependents_.SetArray();
1989 }
1990 void AddMissingDependentProperty(const SValue& targetName) {
1991 missingDependents_.PushBack(ValueType(targetName, GetStateAllocator()).Move(), GetStateAllocator());
1992 }
1993 void EndMissingDependentProperties(const SValue& sourceName) {
1994 if (!missingDependents_.Empty())
1995 currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(),
1997 }
1998 void AddDependencySchemaError(const SValue& sourceName, ISchemaValidator* subvalidator) {
1999 currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(),
2000 static_cast<GenericSchemaValidator*>(subvalidator)->GetError(), GetStateAllocator());
2001 }
2003 if (currentError_.ObjectEmpty())
2004 return false;
2005 ValueType error(kObjectType);
2006 error.AddMember(GetErrorsString(), currentError_, GetStateAllocator());
2007 currentError_ = error;
2008 AddCurrentError(SchemaType::GetDependenciesString());
2009 return true;
2010 }
2011
2013 currentError_.SetObject();
2014 AddCurrentError(SchemaType::GetEnumString());
2015 }
2017 currentError_.SetArray();
2018 }
2019 void AddExpectedType(const typename SchemaType::ValueType& expectedType) {
2020 currentError_.PushBack(ValueType(expectedType, GetStateAllocator()).Move(), GetStateAllocator());
2021 }
2022 void EndDisallowedType(const typename SchemaType::ValueType& actualType) {
2023 ValueType error(kObjectType);
2024 error.AddMember(GetExpectedString(), currentError_, GetStateAllocator());
2025 error.AddMember(GetActualString(), ValueType(actualType, GetStateAllocator()).Move(), GetStateAllocator());
2026 currentError_ = error;
2027 AddCurrentError(SchemaType::GetTypeString());
2028 }
2029 void NotAllOf(ISchemaValidator** subvalidators, SizeType count) {
2030 for (SizeType i = 0; i < count; ++i) {
2031 MergeError(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError());
2032 }
2033 }
2034 void NoneOf(ISchemaValidator** subvalidators, SizeType count) {
2035 AddErrorArray(SchemaType::GetAnyOfString(), subvalidators, count);
2036 }
2037 void NotOneOf(ISchemaValidator** subvalidators, SizeType count) {
2038 AddErrorArray(SchemaType::GetOneOfString(), subvalidators, count);
2039 }
2040 void Disallowed() {
2041 currentError_.SetObject();
2042 AddCurrentError(SchemaType::GetNotString());
2043 }
2044
2045#define RAPIDJSON_STRING_(name, ...) \
2046 static const StringRefType& Get##name##String() {\
2047 static const Ch s[] = { __VA_ARGS__, '\0' };\
2048 static const StringRefType v(s, static_cast<SizeType>(sizeof(s) / sizeof(Ch) - 1)); \
2049 return v;\
2050 }
2051
2052 RAPIDJSON_STRING_(InstanceRef, 'i', 'n', 's', 't', 'a', 'n', 'c', 'e', 'R', 'e', 'f')
2053 RAPIDJSON_STRING_(SchemaRef, 's', 'c', 'h', 'e', 'm', 'a', 'R', 'e', 'f')
2054 RAPIDJSON_STRING_(Expected, 'e', 'x', 'p', 'e', 'c', 't', 'e', 'd')
2055 RAPIDJSON_STRING_(Actual, 'a', 'c', 't', 'u', 'a', 'l')
2056 RAPIDJSON_STRING_(Disallowed, 'd', 'i', 's', 'a', 'l', 'l', 'o', 'w', 'e', 'd')
2057 RAPIDJSON_STRING_(Missing, 'm', 'i', 's', 's', 'i', 'n', 'g')
2058 RAPIDJSON_STRING_(Errors, 'e', 'r', 'r', 'o', 'r', 's')
2059 RAPIDJSON_STRING_(Duplicates, 'd', 'u', 'p', 'l', 'i', 'c', 'a', 't', 'e', 's')
2060
2061#undef RAPIDJSON_STRING_
2062
2063#if RAPIDJSON_SCHEMA_VERBOSE
2064#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \
2065RAPIDJSON_MULTILINEMACRO_BEGIN\
2066 *documentStack_.template Push<Ch>() = '\0';\
2067 documentStack_.template Pop<Ch>(1);\
2068 internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>());\
2069RAPIDJSON_MULTILINEMACRO_END
2070#else
2071#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_()
2072#endif
2073
2074#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\
2075 if (!valid_) return false; \
2076 if (!BeginValue() || !CurrentSchema().method arg1) {\
2077 RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\
2078 return valid_ = false;\
2079 }
2080
2081#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\
2082 for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\
2083 if (context->hasher)\
2084 static_cast<HasherType*>(context->hasher)->method arg2;\
2085 if (context->validators)\
2086 for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\
2087 static_cast<GenericSchemaValidator*>(context->validators[i_])->method arg2;\
2088 if (context->patternPropertiesValidators)\
2089 for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\
2090 static_cast<GenericSchemaValidator*>(context->patternPropertiesValidators[i_])->method arg2;\
2091 }
2092
2093#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\
2094 return valid_ = EndValue() && (!outputHandler_ || outputHandler_->method arg2)
2095
2096#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \
2097 RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\
2098 RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\
2099 RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2)
2100
2104 bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); }
2108 bool RawNumber(const Ch* str, SizeType length, bool copy)
2109 { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }
2110 bool String(const Ch* str, SizeType length, bool copy)
2111 { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }
2112
2118
2119 bool Key(const Ch* str, SizeType len, bool copy) {
2120 if (!valid_) return false;
2121 AppendToken(str, len);
2122 if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false;
2124 return valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy);
2125 }
2126
2127 bool EndObject(SizeType memberCount) {
2128 if (!valid_) return false;
2130 if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false;
2132 }
2133
2139
2140 bool EndArray(SizeType elementCount) {
2141 if (!valid_) return false;
2143 if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false;
2144 RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount));
2145 }
2146
2147#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_
2148#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_
2149#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_
2150#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_
2151
2152 // Implementation of ISchemaStateFactory<SchemaType>
2153 virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) {
2154 return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root, documentStack_.template Bottom<char>(), documentStack_.GetSize(),
2156 depth_ + 1,
2157#endif
2159 }
2160
2161 virtual void DestroySchemaValidator(ISchemaValidator* validator) {
2162 GenericSchemaValidator* v = static_cast<GenericSchemaValidator*>(validator);
2164 StateAllocator::Free(v);
2165 }
2166
2167 virtual void* CreateHasher() {
2168 return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator());
2169 }
2170
2171 virtual uint64_t GetHashCode(void* hasher) {
2172 return static_cast<HasherType*>(hasher)->GetHashCode();
2173 }
2174
2175 virtual void DestroryHasher(void* hasher) {
2176 HasherType* h = static_cast<HasherType*>(hasher);
2177 h->~HasherType();
2178 StateAllocator::Free(h);
2179 }
2180
2181 virtual void* MallocState(size_t size) {
2182 return GetStateAllocator().Malloc(size);
2183 }
2184
2185 virtual void FreeState(void* p) {
2186 StateAllocator::Free(p);
2187 }
2188
2189private:
2191 typedef GenericValue<UTF8<>, StateAllocator> HashCodeArray;
2193
2195 const SchemaDocumentType& schemaDocument,
2196 const SchemaType& root,
2197 const char* basePath, size_t basePathSize,
2199 unsigned depth,
2200#endif
2201 StateAllocator* allocator = 0,
2202 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
2203 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
2204 :
2205 schemaDocument_(&schemaDocument),
2206 root_(root),
2207 stateAllocator_(allocator),
2209 schemaStack_(allocator, schemaStackCapacity),
2210 documentStack_(allocator, documentStackCapacity),
2211 outputHandler_(0),
2213 currentError_(),
2215 valid_(true)
2217 , depth_(depth)
2218#endif
2219 {
2220 if (basePath && basePathSize)
2221 memcpy(documentStack_.template Push<char>(basePathSize), basePath, basePathSize);
2222 }
2223
2224 StateAllocator& GetStateAllocator() {
2225 if (!stateAllocator_)
2226 stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator)();
2227 return *stateAllocator_;
2228 }
2229
2230 bool BeginValue() {
2231 if (schemaStack_.Empty())
2233 else {
2234 if (CurrentContext().inArray)
2236
2238 return false;
2239
2240 SizeType count = CurrentContext().patternPropertiesSchemaCount;
2241 const SchemaType** sa = CurrentContext().patternPropertiesSchemas;
2242 typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
2243 bool valueUniqueness = CurrentContext().valueUniqueness;
2244 RAPIDJSON_ASSERT(CurrentContext().valueSchema);
2245 PushSchema(*CurrentContext().valueSchema);
2246
2247 if (count > 0) {
2248 CurrentContext().objectPatternValidatorType = patternValidatorType;
2249 ISchemaValidator**& va = CurrentContext().patternPropertiesValidators;
2250 SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount;
2251 va = static_cast<ISchemaValidator**>(MallocState(sizeof(ISchemaValidator*) * count));
2252 for (SizeType i = 0; i < count; i++)
2253 va[validatorCount++] = CreateSchemaValidator(*sa[i]);
2254 }
2255
2256 CurrentContext().arrayUniqueness = valueUniqueness;
2257 }
2258 return true;
2259 }
2260
2261 bool EndValue() {
2263 return false;
2264
2265#if RAPIDJSON_SCHEMA_VERBOSE
2267 schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb);
2268
2269 *documentStack_.template Push<Ch>() = '\0';
2270 documentStack_.template Pop<Ch>(1);
2271 internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom<Ch>());
2272#endif
2273
2274 uint64_t h = CurrentContext().arrayUniqueness ? static_cast<HasherType*>(CurrentContext().hasher)->GetHashCode() : 0;
2275
2276 PopSchema();
2277
2278 if (!schemaStack_.Empty()) {
2279 Context& context = CurrentContext();
2280 if (context.valueUniqueness) {
2281 HashCodeArray* a = static_cast<HashCodeArray*>(context.arrayElementHashCodes);
2282 if (!a)
2283 CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType);
2284 for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr)
2285 if (itr->GetUint64() == h) {
2286 DuplicateItems(static_cast<SizeType>(itr - a->Begin()), a->Size());
2287 RAPIDJSON_INVALID_KEYWORD_RETURN(SchemaType::GetUniqueItemsString());
2288 }
2289 a->PushBack(h, GetStateAllocator());
2290 }
2291 }
2292
2293 // Remove the last token of document pointer
2294 while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) != '/')
2295 ;
2296
2297 return true;
2298 }
2299
2300 void AppendToken(const Ch* str, SizeType len) {
2301 documentStack_.template Reserve<Ch>(1 + len * 2); // worst case all characters are escaped as two characters
2302 *documentStack_.template PushUnsafe<Ch>() = '/';
2303 for (SizeType i = 0; i < len; i++) {
2304 if (str[i] == '~') {
2305 *documentStack_.template PushUnsafe<Ch>() = '~';
2306 *documentStack_.template PushUnsafe<Ch>() = '0';
2307 }
2308 else if (str[i] == '/') {
2309 *documentStack_.template PushUnsafe<Ch>() = '~';
2310 *documentStack_.template PushUnsafe<Ch>() = '1';
2311 }
2312 else
2313 *documentStack_.template PushUnsafe<Ch>() = str[i];
2314 }
2315 }
2316
2317 RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push<Context>()) Context(*this, *this, &schema); }
2318
2319 RAPIDJSON_FORCEINLINE void PopSchema() {
2320 Context* c = schemaStack_.template Pop<Context>(1);
2321 if (HashCodeArray* a = static_cast<HashCodeArray*>(c->arrayElementHashCodes)) {
2322 a->~HashCodeArray();
2323 StateAllocator::Free(a);
2324 }
2325 c->~Context();
2326 }
2327
2328 void AddErrorLocation(ValueType& result, bool parent) {
2330 PointerType instancePointer = GetInvalidDocumentPointer();
2331 ((parent && instancePointer.GetTokenCount() > 0)
2332 ? PointerType(instancePointer.GetTokens(), instancePointer.GetTokenCount() - 1)
2333 : instancePointer).StringifyUriFragment(sb);
2334 ValueType instanceRef(sb.GetString(), static_cast<SizeType>(sb.GetSize() / sizeof(Ch)),
2336 result.AddMember(GetInstanceRefString(), instanceRef, GetStateAllocator());
2337 sb.Clear();
2338 memcpy(sb.Push(CurrentSchema().GetURI().GetStringLength()),
2339 CurrentSchema().GetURI().GetString(),
2340 CurrentSchema().GetURI().GetStringLength() * sizeof(Ch));
2341 GetInvalidSchemaPointer().StringifyUriFragment(sb);
2342 ValueType schemaRef(sb.GetString(), static_cast<SizeType>(sb.GetSize() / sizeof(Ch)),
2344 result.AddMember(GetSchemaRefString(), schemaRef, GetStateAllocator());
2345 }
2346
2347 void AddError(ValueType& keyword, ValueType& error) {
2348 typename ValueType::MemberIterator member = error_.FindMember(keyword);
2349 if (member == error_.MemberEnd())
2350 error_.AddMember(keyword, error, GetStateAllocator());
2351 else {
2352 if (member->value.IsObject()) {
2353 ValueType errors(kArrayType);
2354 errors.PushBack(member->value, GetStateAllocator());
2355 member->value = errors;
2356 }
2357 member->value.PushBack(error, GetStateAllocator());
2358 }
2359 }
2360
2361 void AddCurrentError(const typename SchemaType::ValueType& keyword, bool parent = false) {
2363 AddError(ValueType(keyword, GetStateAllocator(), false).Move(), currentError_);
2364 }
2365
2366 void MergeError(ValueType& other) {
2367 for (typename ValueType::MemberIterator it = other.MemberBegin(), end = other.MemberEnd(); it != end; ++it) {
2368 AddError(it->name, it->value);
2369 }
2370 }
2371
2372 void AddNumberError(const typename SchemaType::ValueType& keyword, ValueType& actual, const SValue& expected,
2373 const typename SchemaType::ValueType& (*exclusive)() = 0) {
2374 currentError_.SetObject();
2375 currentError_.AddMember(GetActualString(), actual, GetStateAllocator());
2376 currentError_.AddMember(GetExpectedString(), ValueType(expected, GetStateAllocator()).Move(), GetStateAllocator());
2377 if (exclusive)
2378 currentError_.AddMember(ValueType(exclusive(), GetStateAllocator()).Move(), true, GetStateAllocator());
2379 AddCurrentError(keyword);
2380 }
2381
2382 void AddErrorArray(const typename SchemaType::ValueType& keyword,
2383 ISchemaValidator** subvalidators, SizeType count) {
2384 ValueType errors(kArrayType);
2385 for (SizeType i = 0; i < count; ++i)
2386 errors.PushBack(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError(), GetStateAllocator());
2387 currentError_.SetObject();
2388 currentError_.AddMember(GetErrorsString(), errors, GetStateAllocator());
2389 AddCurrentError(keyword);
2390 }
2391
2392 const SchemaType& CurrentSchema() const { return *schemaStack_.template Top<Context>()->schema; }
2393 Context& CurrentContext() { return *schemaStack_.template Top<Context>(); }
2394 const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); }
2395
2396 static const size_t kDefaultSchemaStackCapacity = 1024;
2397 static const size_t kDefaultDocumentStackCapacity = 256;
2398 const SchemaDocumentType* schemaDocument_;
2400 StateAllocator* stateAllocator_;
2401 StateAllocator* ownStateAllocator_;
2404 OutputHandler* outputHandler_;
2409#if RAPIDJSON_SCHEMA_VERBOSE
2410 unsigned depth_;
2411#endif
2412};
2413
2415
2417// SchemaValidatingReader
2418
2420
2429template <
2430 unsigned parseFlags,
2431 typename InputStream,
2432 typename SourceEncoding,
2433 typename SchemaDocumentType = SchemaDocument,
2434 typename StackAllocator = CrtAllocator>
2436public:
2437 typedef typename SchemaDocumentType::PointerType PointerType;
2438 typedef typename InputStream::Ch Ch;
2440
2442
2446 SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), error_(kObjectType), isValid_(true) {}
2447
2448 template <typename Handler>
2449 bool operator()(Handler& handler) {
2452 parseResult_ = reader.template Parse<parseFlags>(is_, validator);
2453
2454 isValid_ = validator.IsValid();
2455 if (isValid_) {
2459 error_.SetObject();
2460 }
2461 else {
2465 error_.CopyFrom(validator.GetError(), allocator_);
2466 }
2467
2468 return parseResult_;
2469 }
2470
2471 const ParseResult& GetParseResult() const { return parseResult_; }
2472 bool IsValid() const { return isValid_; }
2476 const ValueType& GetError() const { return error_; }
2477
2478private:
2479 InputStream& is_;
2480 const SchemaDocumentType& sd_;
2481
2486 StackAllocator allocator_;
2489};
2490
2492RAPIDJSON_DIAG_POP
2493
2494#endif // RAPIDJSON_SCHEMA_H_
#define s(x, c)
Definition aesb.c:47
cryptonote::block b
Definition block.cpp:40
static uint64_t h
Definition blockchain_stats.cpp:55
C-runtime library allocator.
Definition allocators.h:75
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition pointer.h:79
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition reader.h:537
JSON schema document.
Definition schema.h:1499
const URIType & GetURI() const
Definition schema.h:1601
internal::Stack< CrtAllocator > schemaRef_
Definition schema.h:1733
const SchemaType * GetTypeless() const
Definition schema.h:1722
bool HandleRefSchema(const PointerType &source, const SchemaType **schema, const ValueType &v, const ValueType &document)
Definition schema.h:1661
const SchemaType * GetSchema(const PointerType &pointer) const
Definition schema.h:1708
void CreateSchemaRecursive(const SchemaType **schema, const PointerType &pointer, const ValueType &v, const ValueType &document)
Definition schema.h:1632
static const size_t kInitialSchemaMapSize
Definition schema.h:1724
const SchemaType * root_
Definition schema.h:1730
static const size_t kInitialSchemaRefSize
Definition schema.h:1725
const SchemaType & GetRoot() const
Get the root schema.
Definition schema.h:1604
~GenericSchemaDocument()
Destructor.
Definition schema.h:1589
URIType uri_
Definition schema.h:1734
SchemaType * typeless_
Definition schema.h:1731
internal::Stack< CrtAllocator > schemaMap_
Definition schema.h:1732
CrtAllocator * allocator_
Definition schema.h:1728
CrtAllocator * ownAllocator_
Definition schema.h:1729
GenericSchemaDocument & operator=(const GenericSchemaDocument &)
Prohibit assignment.
IGenericRemoteSchemaDocumentProvider< GenericSchemaDocument > IRemoteSchemaDocumentProviderType
Definition schema.h:1502
void CreateSchema(const SchemaType **schema, const PointerType &pointer, const ValueType &v, const ValueType &document)
Definition schema.h:1649
EncodingType::Ch Ch
Definition schema.h:1505
CrtAllocator AllocatorType
Definition schema.h:1503
GenericValue< EncodingType, CrtAllocator > URIType
Definition schema.h:1508
internal::Schema< GenericSchemaDocument > SchemaType
Definition schema.h:1506
ValueType::EncodingType EncodingType
Definition schema.h:1504
PointerType GetPointer(const SchemaType *schema) const
Definition schema.h:1715
Value ValueType
Definition schema.h:1501
GenericSchemaDocument(const GenericSchemaDocument &)
Prohibit copying.
IRemoteSchemaDocumentProviderType * remoteProvider_
Definition schema.h:1727
GenericSchemaDocument(const ValueType &document, const Ch *uri=0, SizeType uriLength=0, IRemoteSchemaDocumentProviderType *remoteProvider=0, Allocator *allocator=0)
Constructor.
Definition schema.h:1523
GenericPointer< ValueType, CrtAllocator > PointerType
Definition schema.h:1507
friend class GenericSchemaValidator
Definition schema.h:1511
JSON Schema Validator.
Definition schema.h:1765
virtual void DestroryHasher(void *hasher)
Definition schema.h:2175
Context & CurrentContext()
Definition schema.h:2393
void AddError(ValueType &keyword, ValueType &error)
Definition schema.h:2347
void BelowMinimum(int64_t actual, const SValue &expected, bool exclusive)
Definition schema.h:1902
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Constructor without output handler.
Definition schema.h:1782
void DisallowedValue()
Definition schema.h:2012
ValueType & GetError()
Gets the error object.
Definition schema.h:1858
void AddCurrentError(const typename SchemaType::ValueType &keyword, bool parent=false)
Definition schema.h:2361
void TooLong(const Ch *str, SizeType length, SizeType expected)
Definition schema.h:1915
void AddDependencySchemaError(const SValue &sourceName, ISchemaValidator *subvalidator)
Definition schema.h:1998
void PropertyViolations(ISchemaValidator **subvalidators, SizeType count)
Definition schema.h:1974
void DisallowedItem(SizeType index)
Definition schema.h:1929
bool String(const Ch *str, SizeType length, bool copy)
Definition schema.h:2110
bool BeginValue()
Definition schema.h:2230
~GenericSchemaValidator()
Destructor.
Definition schema.h:1837
void StartMissingProperties()
Definition schema.h:1959
void NotAllOf(ISchemaValidator **subvalidators, SizeType count)
Definition schema.h:2029
GenericValue< EncodingType, CrtAllocator > ValueType
Definition schema.h:1773
void DisallowedProperty(const Ch *name, SizeType length)
Definition schema.h:1978
virtual void * CreateHasher()
Definition schema.h:2167
void Reset()
Reset the internal states.
Definition schema.h:1843
void AboveMaximum(int64_t actual, const SValue &expected, bool exclusive)
Definition schema.h:1890
virtual void FreeState(void *p)
Definition schema.h:2185
bool EndMissingProperties()
Definition schema.h:1965
void MergeError(ValueType &other)
Definition schema.h:2366
bool StartObject()
Definition schema.h:2113
PointerType GetInvalidSchemaPointer() const
Gets the JSON pointer pointed to the invalid schema.
Definition schema.h:1862
void NotMultipleOf(uint64_t actual, const SValue &expected)
Definition schema.h:1884
bool EndArray(SizeType elementCount)
Definition schema.h:2140
void AddExpectedType(const typename SchemaType::ValueType &expectedType)
Definition schema.h:2019
virtual ISchemaValidator * CreateSchemaValidator(const SchemaType &root)
Definition schema.h:2153
RAPIDJSON_FORCEINLINE void PopSchema()
Definition schema.h:2319
bool Key(const Ch *str, SizeType len, bool copy)
Definition schema.h:2119
bool Null()
Definition schema.h:2101
const SchemaType & CurrentSchema() const
Definition schema.h:2392
void StartDependencyErrors()
Definition schema.h:1984
void TooShort(const Ch *str, SizeType length, SizeType expected)
Definition schema.h:1919
void TooManyItems(SizeType actualCount, SizeType expectedCount)
Definition schema.h:1938
void DuplicateItems(SizeType index1, SizeType index2)
Definition schema.h:1942
void AddMissingDependentProperty(const SValue &targetName)
Definition schema.h:1990
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, const SchemaType &root, const char *basePath, size_t basePathSize, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Definition schema.h:2194
void AddMissingProperty(const SValue &name)
Definition schema.h:1962
virtual bool IsValid() const
Checks whether the current state is valid.
Definition schema.h:1855
void AboveMaximum(uint64_t actual, const SValue &expected, bool exclusive)
Definition schema.h:1894
StateAllocator & GetStateAllocator()
Definition schema.h:2224
void StartDisallowedType()
Definition schema.h:2016
virtual void * MallocState(size_t size)
Definition schema.h:2181
bool Bool(bool b)
Definition schema.h:2102
bool Uint(unsigned u)
Definition schema.h:2104
bool EndObject(SizeType memberCount)
Definition schema.h:2127
void AddNumberError(const typename SchemaType::ValueType &keyword, ValueType &actual, const SValue &expected, const typename SchemaType::ValueType &(*exclusive)()=0)
Definition schema.h:2372
void NoneOf(ISchemaValidator **subvalidators, SizeType count)
Definition schema.h:2034
void TooFewProperties(SizeType actualCount, SizeType expectedCount)
Definition schema.h:1955
void NotMultipleOf(int64_t actual, const SValue &expected)
Definition schema.h:1881
const Ch * GetInvalidSchemaKeyword() const
Gets the keyword of invalid schema.
Definition schema.h:1867
bool EndDependencyErrors()
Definition schema.h:2002
internal::Hasher< EncodingType, CrtAllocator > HasherType
Definition schema.h:2192
bool StartArray()
Definition schema.h:2134
void AboveMaximum(double actual, const SValue &expected, bool exclusive)
Definition schema.h:1898
bool Uint64(uint64_t u)
Definition schema.h:2106
virtual uint64_t GetHashCode(void *hasher)
Definition schema.h:2171
BaseReaderHandler< UTF8< char >, void > * outputHandler_
Definition schema.h:2404
PointerType GetInvalidDocumentPointer() const
Gets the JSON pointer pointed to the invalid value.
Definition schema.h:1872
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, OutputHandler &outputHandler, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Constructor with output handler.
Definition schema.h:1812
void StartMissingDependentProperties()
Definition schema.h:1987
bool Int64(int64_t i)
Definition schema.h:2105
const Context & CurrentContext() const
Definition schema.h:2394
void Disallowed()
Definition schema.h:2040
void AppendToken(const Ch *str, SizeType len)
Definition schema.h:2300
void BelowMinimum(uint64_t actual, const SValue &expected, bool exclusive)
Definition schema.h:1906
void NotOneOf(ISchemaValidator **subvalidators, SizeType count)
Definition schema.h:2037
const ValueType & GetError() const
Definition schema.h:1859
void TooManyProperties(SizeType actualCount, SizeType expectedCount)
Definition schema.h:1951
bool Int(int i)
Definition schema.h:2103
void EndDisallowedType(const typename SchemaType::ValueType &actualType)
Definition schema.h:2022
GenericValue< UTF8<>, CrtAllocator > HashCodeArray
Definition schema.h:2191
virtual void DestroySchemaValidator(ISchemaValidator *validator)
Definition schema.h:2161
bool RawNumber(const Ch *str, SizeType length, bool copy)
Definition schema.h:2108
void NotMultipleOf(double actual, const SValue &expected)
Definition schema.h:1887
RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType &schema)
Definition schema.h:2317
bool EndValue()
Definition schema.h:2261
bool Double(double d)
Definition schema.h:2107
void DoesNotMatch(const Ch *str, SizeType length)
Definition schema.h:1923
void TooFewItems(SizeType actualCount, SizeType expectedCount)
Definition schema.h:1934
void AddErrorArray(const typename SchemaType::ValueType &keyword, ISchemaValidator **subvalidators, SizeType count)
Definition schema.h:2382
void AddErrorLocation(ValueType &result, bool parent)
Definition schema.h:2328
void EndMissingDependentProperties(const SValue &sourceName)
Definition schema.h:1993
void BelowMinimum(double actual, const SValue &expected, bool exclusive)
Definition schema.h:1910
Represents an in-memory output stream.
Definition stringbuffer.h:41
const Ch * GetString() const
Definition stringbuffer.h:73
void Clear()
Definition stringbuffer.h:60
size_t GetSize() const
Get the size of string in bytes in the string buffer.
Definition stringbuffer.h:82
Ch * Push(size_t count)
Definition stringbuffer.h:69
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition document.h:575
UTF8<> EncodingType
Definition document.h:579
GenericMemberIterator< false, EncodingType, CrtAllocator >::Iterator MemberIterator
Definition document.h:583
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition document.h:586
GenericMemberIterator< true, UTF8<>, MemoryPoolAllocator<> >::Iterator ConstMemberIterator
Definition document.h:584
Definition schema.h:1478
virtual ~IGenericRemoteSchemaDocumentProvider()
Definition schema.h:1482
SchemaDocument::Ch Ch
Definition schema.h:1480
virtual const SchemaDocumentType * GetRemoteDocument(const Ch *uri, SizeType length)=0
ValueType error_
Definition schema.h:2487
const PointerType & GetInvalidDocumentPointer() const
Definition schema.h:2475
PointerType invalidSchemaPointer_
Definition schema.h:2483
SchemaDocumentType::PointerType PointerType
Definition schema.h:2437
const Ch * invalidSchemaKeyword_
Definition schema.h:2484
bool IsValid() const
Definition schema.h:2472
bool isValid_
Definition schema.h:2488
const PointerType & GetInvalidSchemaPointer() const
Definition schema.h:2473
InputStream::Ch Ch
Definition schema.h:2438
bool operator()(Handler &handler)
Definition schema.h:2449
StackAllocator allocator_
Definition schema.h:2486
ParseResult parseResult_
Definition schema.h:2482
const SchemaDocumentType & sd_
Definition schema.h:2480
const Ch * GetInvalidSchemaKeyword() const
Definition schema.h:2474
const ParseResult & GetParseResult() const
Definition schema.h:2471
PointerType invalidDocumentPointer_
Definition schema.h:2485
SchemaValidatingReader(InputStream &is, const SchemaDocumentType &sd)
Constructor.
Definition schema.h:2446
const ValueType & GetError() const
Definition schema.h:2476
GenericValue< SourceEncoding, StackAllocator > ValueType
Definition schema.h:2439
InputStream & is_
Definition schema.h:2479
Definition gtest-string.h:58
Definition regex.h:599
Regular expression engine with subset of ECMAscript grammar.
Definition regex.h:114
Definition schema.h:220
bool WriteBuffer(Type type, const void *data, size_t len)
Definition schema.h:292
static const size_t kDefaultSize
Definition schema.h:279
bool Bool(bool b)
Definition schema.h:227
bool Uint64(uint64_t u)
Definition schema.h:231
bool StartObject()
Definition schema.h:250
bool Key(const Ch *str, SizeType len, bool copy)
Definition schema.h:251
bool StartArray()
Definition schema.h:261
Encoding::Ch Ch
Definition schema.h:222
bool Uint(unsigned u)
Definition schema.h:229
bool Null()
Definition schema.h:226
bool EndObject(SizeType memberCount)
Definition schema.h:252
Hasher(Allocator *allocator=0, size_t stackCapacity=kDefaultSize)
Definition schema.h:224
bool Double(double d)
Definition schema.h:232
bool String(const Ch *str, SizeType len, bool)
Definition schema.h:245
bool Int(int i)
Definition schema.h:228
bool WriteNumber(const Number &n)
Definition schema.h:290
uint64_t GetHashCode() const
Definition schema.h:273
static uint64_t Hash(uint64_t h, uint64_t d)
Definition schema.h:302
bool EndArray(SizeType elementCount)
Definition schema.h:262
bool Int64(int64_t i)
Definition schema.h:230
bool IsValid() const
Definition schema.h:271
bool RawNumber(const Ch *str, SizeType len, bool)
Definition schema.h:240
Stack< StateAllocator > stack_
Definition schema.h:309
bool WriteType(Type type)
Definition schema.h:288
Definition schema.h:147
virtual void DestroySchemaValidator(ISchemaValidator *validator)=0
virtual void FreeState(void *p)=0
virtual ISchemaValidator * CreateSchemaValidator(const SchemaType &)=0
virtual void DestroryHasher(void *hasher)=0
virtual void * CreateHasher()=0
virtual void * MallocState(size_t size)=0
virtual uint64_t GetHashCode(void *hasher)=0
virtual ~ISchemaStateFactory()
Definition schema.h:149
Definition schema.h:137
virtual bool IsValid() const =0
virtual ~ISchemaValidator()
Definition schema.h:139
Definition schema.h:163
virtual void EndMissingDependentProperties(const SValue &sourceName)=0
virtual void DisallowedItem(SizeType index)=0
virtual void NotMultipleOf(int64_t actual, const SValue &expected)=0
SchemaType::Ch Ch
Definition schema.h:165
SchemaType::SValue SValue
Definition schema.h:166
virtual void AddMissingDependentProperty(const SValue &targetName)=0
virtual void TooManyProperties(SizeType actualCount, SizeType expectedCount)=0
virtual bool EndMissingProperties()=0
virtual void DuplicateItems(SizeType index1, SizeType index2)=0
virtual void AddMissingProperty(const SValue &name)=0
virtual void NotAllOf(ISchemaValidator **subvalidators, SizeType count)=0
virtual void AddDependencySchemaError(const SValue &souceName, ISchemaValidator *subvalidator)=0
virtual void TooShort(const Ch *str, SizeType length, SizeType expected)=0
virtual void BelowMinimum(int64_t actual, const SValue &expected, bool exclusive)=0
virtual void AboveMaximum(double actual, const SValue &expected, bool exclusive)=0
virtual void AddExpectedType(const typename SchemaType::ValueType &expectedType)=0
virtual void DisallowedProperty(const Ch *name, SizeType length)=0
virtual void NoneOf(ISchemaValidator **subvalidators, SizeType count)=0
virtual void NotOneOf(ISchemaValidator **subvalidators, SizeType count)=0
virtual void AboveMaximum(uint64_t actual, const SValue &expected, bool exclusive)=0
virtual ~IValidationErrorHandler()
Definition schema.h:168
virtual void AboveMaximum(int64_t actual, const SValue &expected, bool exclusive)=0
virtual bool EndDependencyErrors()=0
virtual void BelowMinimum(double actual, const SValue &expected, bool exclusive)=0
virtual void TooManyItems(SizeType actualCount, SizeType expectedCount)=0
virtual void DoesNotMatch(const Ch *str, SizeType length)=0
virtual void StartDisallowedType()=0
virtual void BelowMinimum(uint64_t actual, const SValue &expected, bool exclusive)=0
virtual void StartDependencyErrors()=0
virtual void PropertyViolations(ISchemaValidator **subvalidators, SizeType count)=0
virtual void StartMissingProperties()=0
virtual void EndDisallowedType(const typename SchemaType::ValueType &actualType)=0
virtual void NotMultipleOf(uint64_t actual, const SValue &expected)=0
virtual void NotMultipleOf(double actual, const SValue &expected)=0
virtual void TooFewProperties(SizeType actualCount, SizeType expectedCount)=0
virtual void TooLong(const Ch *str, SizeType length, SizeType expected)=0
virtual void StartMissingDependentProperties()=0
virtual void TooFewItems(SizeType actualCount, SizeType expectedCount)=0
Definition schema.h:396
bool Int64(Context &context, int64_t i) const
Definition schema.h:813
void CreateSchemaValidators(Context &context, const SchemaArray &schemas) const
Definition schema.h:1213
bool exclusiveMaximum_
Definition schema.h:1437
SizeType notValidatorIndex_
Definition schema.h:1406
bool StartArray(Context &context) const
Definition schema.h:988
bool CheckUint(Context &context, uint64_t i) const
Definition schema.h:1280
RegexType * CreatePattern(const ValueType &)
Definition schema.h:1167
bool StartObject(Context &context) const
Definition schema.h:871
SchemaDocumentType::PointerType PointerType
Definition schema.h:400
bool additionalProperties_
Definition schema.h:1415
bool exclusiveMinimum_
Definition schema.h:1436
bool Int(Context &context, int i) const
Definition schema.h:801
bool Uint64(Context &context, uint64_t u) const
Definition schema.h:819
bool uniqueItems_
Definition schema.h:1427
SizeType maxLength_
Definition schema.h:1431
bool FindPropertyIndex(const ValueType &name, SizeType *outIndex) const
Definition schema.h:1219
AllocatorType * allocator_
Definition schema.h:1394
static void AssignIfExist(SizeType &out, const ValueType &value, const ValueType &name)
Definition schema.h:1109
IValidationErrorHandler< Schema > ErrorHandler
Definition schema.h:406
Schema(SchemaDocumentType *schemaDocument, const PointerType &p, const ValueType &value, const ValueType &document, AllocatorType *allocator)
Definition schema.h:409
SizeType validatorCount_
Definition schema.h:1405
SValue maximum_
Definition schema.h:1434
bool CheckDoubleMultipleOf(Context &context, double d) const
Definition schema.h:1344
SchemaArray oneOf_
Definition schema.h:1402
SizeType minItems_
Definition schema.h:1424
~Schema()
Definition schema.h:647
static void AssignIfExist(bool &out, const ValueType &value, const ValueType &name)
Definition schema.h:1103
char RegexType
Definition schema.h:1078
void AddType(const ValueType &type)
Definition schema.h:1172
bool additionalItems_
Definition schema.h:1426
bool CheckDoubleMinimum(Context &context, double d) const
Definition schema.h:1328
bool EndObject(Context &context, SizeType memberCount) const
Definition schema.h:941
SizeType maxProperties_
Definition schema.h:1414
Property * properties_
Definition schema.h:1408
void DisallowedType(Context &context, const ValueType &actualType) const
Definition schema.h:1355
bool CheckInt(Context &context, int64_t i) const
Definition schema.h:1232
const SchemaType * typeless_
Definition schema.h:1397
SchemaDocumentType::AllocatorType AllocatorType
Definition schema.h:399
bool EndArray(Context &context, SizeType elementCount) const
Definition schema.h:1000
const SchemaType * additionalPropertiesSchema_
Definition schema.h:1409
SizeType defaultValueLength_
Definition schema.h:1439
bool Double(Context &context, double d) const
Definition schema.h:825
bool CreateParallelValidator(Context &context) const
Definition schema.h:1182
SchemaDocumentType::ValueType ValueType
Definition schema.h:398
const SchemaType * additionalItemsSchema_
Definition schema.h:1420
unsigned type_
Definition schema.h:1404
const PointerType & GetPointer() const
Definition schema.h:672
bool String(Context &context, const Ch *str, SizeType length, bool) const
Definition schema.h:843
static bool IsPatternMatch(const RegexType *, const Ch *, SizeType)
Definition schema.h:1169
bool CheckDoubleMaximum(Context &context, double d) const
Definition schema.h:1336
void AddUniqueElement(V1 &a, const V2 &v)
Definition schema.h:1090
SizeType enumCount_
Definition schema.h:1399
EncodingType::Ch Ch
Definition schema.h:402
SValue minimum_
Definition schema.h:1433
PatternProperty * patternProperties_
Definition schema.h:1410
ValueType::EncodingType EncodingType
Definition schema.h:401
static const ValueType * GetMember(const ValueType &value, const ValueType &name)
Definition schema.h:1098
SchemaArray allOf_
Definition schema.h:1400
SizeType minProperties_
Definition schema.h:1413
bool hasSchemaDependencies_
Definition schema.h:1418
GenericValue< EncodingType, AllocatorType > SValue
Definition schema.h:405
bool Bool(Context &context, bool) const
Definition schema.h:793
const SchemaType ** itemsTuple_
Definition schema.h:1422
const SchemaType * not_
Definition schema.h:1403
SizeType minLength_
Definition schema.h:1430
bool Uint(Context &context, unsigned u) const
Definition schema.h:807
bool Key(Context &context, const Ch *str, SizeType len, bool) const
Definition schema.h:892
PointerType pointer_
Definition schema.h:1396
SizeType maxItems_
Definition schema.h:1425
Schema< SchemaDocumentType > SchemaType
Definition schema.h:404
SchemaValidationContext< SchemaDocumentType > Context
Definition schema.h:403
SValue uri_
Definition schema.h:1395
bool Null(Context &context) const
Definition schema.h:785
const SValue & GetURI() const
Definition schema.h:668
SizeType itemsTupleCount_
Definition schema.h:1423
SizeType patternPropertyCount_
Definition schema.h:1411
bool hasRequired_
Definition schema.h:1417
SizeType propertyCount_
Definition schema.h:1412
RegexType * pattern_
Definition schema.h:1429
bool hasDependencies_
Definition schema.h:1416
bool BeginValue(Context &context) const
Definition schema.h:676
uint64_t * enum_
Definition schema.h:1398
void AssignIfExist(SchemaArray &out, SchemaDocumentType &schemaDocument, const PointerType &p, const ValueType &value, const ValueType &name, const ValueType &document)
Definition schema.h:1115
SValue multipleOf_
Definition schema.h:1435
SchemaValueType
Definition schema.h:1062
@ kArraySchemaType
Definition schema.h:1066
@ kNumberSchemaType
Definition schema.h:1068
@ kStringSchemaType
Definition schema.h:1067
@ kNullSchemaType
Definition schema.h:1063
@ kObjectSchemaType
Definition schema.h:1065
@ kIntegerSchemaType
Definition schema.h:1069
@ kBooleanSchemaType
Definition schema.h:1064
@ kTotalSchemaType
Definition schema.h:1070
const SchemaType * itemsList_
Definition schema.h:1421
RAPIDJSON_FORCEINLINE bool EndValue(Context &context) const
Definition schema.h:703
SchemaArray anyOf_
Definition schema.h:1401
A type-unsafe stack for storing different types of data.
Definition stack.h:36
Concept for allocating, resizing and freeing memory block.
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
GenericSchemaDocument< Value, CrtAllocator > SchemaDocument
Definition fwd.h:138
GenericSchemaValidator< SchemaDocument, BaseReaderHandler< UTF8< char >, void >, CrtAllocator > SchemaValidator
Definition fwd.h:147
IGenericRemoteSchemaDocumentProvider< SchemaDocument > IRemoteSchemaDocumentProvider
Definition fwd.h:139
void * memcpy(void *a, const void *b, size_t c)
Definition glibc_compat.cpp:16
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:411
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition rapidjson.h:121
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition rapidjson.h:124
#define true
#define false
#define L(m0, m1, m2, m3, m4, m5, m6, m7)
Definition jh.c:116
int q
Definition base.py:2
Definition d.py:1
Definition document.h:406
char * u64toa(uint64_t value, char *buffer)
Definition itoa.h:126
bool CountStringCodePoint(const typename Encoding::Ch *s, SizeType length, SizeType *outCount)
Returns number of code points in a encoded string.
Definition strfunc.h:50
char * u32toa(uint32_t value, char *buffer)
Definition itoa.h:39
int i
Definition pymoduletest.py:23
p
Definition pymoduletest.py:75
r
Definition testupnpigd.py:61
Definition uri.py:1
const char * name
Definition options.c:30
const GenericPointer< typename T::ValueType > T2 value
Definition pointer.h:1225
const GenericPointer< typename T::ValueType > & pointer
Definition pointer.h:1124
const CharType(& source)[N]
Definition pointer.h:1147
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1124
const char *const str
Definition portlistingparse.c:23
Type
Type of JSON value.
Definition rapidjson.h:623
@ kFalseType
false
Definition rapidjson.h:625
@ kObjectType
object
Definition rapidjson.h:627
@ kTrueType
true
Definition rapidjson.h:626
@ kStringType
string
Definition rapidjson.h:629
@ kNullType
null
Definition rapidjson.h:624
@ kArrayType
array
Definition rapidjson.h:628
@ kNumberType
number
Definition rapidjson.h:630
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:610
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.).
Definition rapidjson.h:389
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition rapidjson.h:294
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:606
#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)
Definition schema.h:2074
#define RAPIDJSON_SCHEMA_VERBOSE
Definition schema.h:48
#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2)
Definition schema.h:2096
#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)
Definition schema.h:2093
#define RAPIDJSON_STRING_(name,...)
Definition schema.h:1017
#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)
Definition schema.h:116
#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)
Definition schema.h:2081
#define Ch(x, y, z)
Definition sha512-blocks.c:34
tools::wallet2::message_signature_result_t result
Definition signature.cpp:62
if(!cryptonote::get_account_address_from_str_or_url(info, cryptonote::TESTNET, "9uVsvEryzpN8WH2t1WWhFFCG5tS8cBNdmJYNRuckLENFimfauV5pZKeS1P2CbxGkSDTUPHXWwiYE5ZGSXDAGbaZgDxobqDN"))
Definition signature.cpp:53
static __thread int depth
Definition threadpool.cpp:34
signed __int64 int64_t
Definition stdint.h:135
unsigned __int64 uint64_t
Definition stdint.h:136
Default implementation of Handler.
Definition reader.h:196
bool owned
Definition schema.h:1629
~SchemaEntry()
Definition schema.h:1621
PointerType pointer
Definition schema.h:1627
SchemaType * schema
Definition schema.h:1628
SchemaEntry(const PointerType &p, SchemaType *s, bool o, Allocator *allocator)
Definition schema.h:1620
SchemaRefEntry(const PointerType &s, const PointerType &t, const SchemaType **outSchema, Allocator *allocator)
Definition schema.h:1613
PointerType target
Definition schema.h:1615
const SchemaType ** schema
Definition schema.h:1616
PointerType source
Definition schema.h:1614
Reference to a constant string (not taking a copy).
Definition document.h:253
Result of parsing (wraps ParseErrorCode).
Definition error.h:106
CharType Ch
Definition encodings.h:97
Definition schema.h:280
union internal::Hasher::Number::U u
Definition schema.h:316
bool arrayUniqueness
Definition schema.h:389
SizeType validatorCount
Definition schema.h:378
const SchemaType ** patternPropertiesSchemas
Definition schema.h:381
ISchemaValidator ** validators
Definition schema.h:377
SizeType arrayElementIndex
Definition schema.h:385
bool valueUniqueness
Definition schema.h:388
SizeType patternPropertiesValidatorCount
Definition schema.h:380
ISchemaStateFactory< SchemaType > SchemaValidatorFactoryType
Definition schema.h:318
const SchemaType * valueSchema
Definition schema.h:373
bool * propertyExist
Definition schema.h:386
void * hasher
Definition schema.h:375
IValidationErrorHandler< SchemaType > ErrorHandlerType
Definition schema.h:319
PatternValidatorType
Definition schema.h:323
@ kPatternValidatorWithProperty
Definition schema.h:325
@ kPatternValidatorWithAdditionalProperty
Definition schema.h:326
@ kPatternValidatorOnly
Definition schema.h:324
void * arrayElementHashCodes
Definition schema.h:376
ISchemaValidator ** patternPropertiesValidators
Definition schema.h:379
SizeType patternPropertiesSchemaCount
Definition schema.h:382
Schema< SchemaDocumentType > SchemaType
Definition schema.h:317
const Ch * invalidKeyword
Definition schema.h:374
~SchemaValidationContext()
Definition schema.h:351
ValueType::Ch Ch
Definition schema.h:321
SchemaType::ValueType ValueType
Definition schema.h:320
PatternValidatorType valuePatternValidatorType
Definition schema.h:383
SchemaValidationContext(SchemaValidatorFactoryType &f, ErrorHandlerType &eh, const SchemaType *s)
Definition schema.h:329
ErrorHandlerType & error_handler
Definition schema.h:371
PatternValidatorType objectPatternValidatorType
Definition schema.h:384
SchemaValidatorFactoryType & factory
Definition schema.h:370
bool inArray
Definition schema.h:387
const SchemaType * schema
Definition schema.h:372
Definition schema.h:1382
~PatternProperty()
Definition schema.h:1384
RegexType * pattern
Definition schema.h:1391
const SchemaType * schema
Definition schema.h:1390
PatternProperty()
Definition schema.h:1383
Definition schema.h:1371
const SchemaType * dependenciesSchema
Definition schema.h:1376
bool required
Definition schema.h:1379
~Property()
Definition schema.h:1373
const SchemaType * schema
Definition schema.h:1375
SizeType dependenciesValidatorIndex
Definition schema.h:1377
bool * dependencies
Definition schema.h:1378
SValue name
Definition schema.h:1374
Property()
Definition schema.h:1372
SchemaArray()
Definition schema.h:1082
const SchemaType ** schemas
Definition schema.h:1084
~SchemaArray()
Definition schema.h:1083
SizeType count
Definition schema.h:1086
SizeType begin
Definition schema.h:1085
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
Definition schema.h:1456
Definition schema.h:1443
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
Definition schema.h:1444
std::string data
Definition base58.cpp:37
Definition schema.h:281
int64_t i
Definition schema.h:283
uint64_t u
Definition schema.h:282