15 #ifndef RAPIDJSON_SCHEMA_H_ 16 #define RAPIDJSON_SCHEMA_H_ 23 #if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX) 24 #define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1 26 #define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0 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 32 #define RAPIDJSON_SCHEMA_USE_STDREGEX 0 35 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 37 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 41 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX 42 #define RAPIDJSON_SCHEMA_HAS_REGEX 1 44 #define RAPIDJSON_SCHEMA_HAS_REGEX 0 47 #ifndef RAPIDJSON_SCHEMA_VERBOSE 48 #define RAPIDJSON_SCHEMA_VERBOSE 0 51 #if RAPIDJSON_SCHEMA_VERBOSE 58 RAPIDJSON_DIAG_OFF(effc++)
62 RAPIDJSON_DIAG_OFF(weak-vtables)
63 RAPIDJSON_DIAG_OFF(exit-time-destructors)
64 RAPIDJSON_DIAG_OFF(c++98-compat-pedantic)
65 RAPIDJSON_DIAG_OFF(variadic-macros)
66 #elif defined(_MSC_VER) 67 RAPIDJSON_DIAG_OFF(4512)
75 #if RAPIDJSON_SCHEMA_VERBOSE 79 inline void PrintInvalidKeyword(
const char* keyword) {
80 printf(
"Fail keyword: %s\n", keyword);
83 inline void PrintInvalidKeyword(
const wchar_t* keyword) {
84 wprintf(L
"Fail keyword: %ls\n", keyword);
87 inline void PrintInvalidDocument(
const char* document) {
88 printf(
"Fail document: %s\n\n", document);
91 inline void PrintInvalidDocument(
const wchar_t* document) {
92 wprintf(L
"Fail document: %ls\n\n", document);
95 inline 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);
99 inline 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);
105 #endif // RAPIDJSON_SCHEMA_VERBOSE 110 #if RAPIDJSON_SCHEMA_VERBOSE 111 #define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword) 113 #define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) 116 #define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\ 117 RAPIDJSON_MULTILINEMACRO_BEGIN\ 118 context.invalidKeyword = keyword.GetString();\ 119 RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\ 121 RAPIDJSON_MULTILINEMACRO_END 126 template <
typename ValueType,
typename Allocator>
131 template <
typename SchemaDocumentType>
140 virtual bool IsValid()
const = 0;
146 template <
typename SchemaType>
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;
162 template <
typename SchemaType>
165 typedef typename SchemaType::Ch
Ch;
166 typedef typename SchemaType::SValue
SValue;
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;
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;
184 virtual void DisallowedItem(
SizeType index) = 0;
186 virtual void TooManyItems(
SizeType actualCount,
SizeType expectedCount) = 0;
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;
195 virtual void DisallowedProperty(
const Ch* name,
SizeType length) = 0;
197 virtual void StartDependencyErrors() = 0;
198 virtual void StartMissingDependentProperties() = 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;
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;
211 virtual void Disallowed() = 0;
219 template<
typename Encoding,
typename Allocator>
222 typedef typename Encoding::Ch
Ch;
224 Hasher(Allocator* allocator = 0,
size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {}
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); }
234 if (d < 0) n.
u.
i =
static_cast<int64_t>(d);
237 return WriteNumber(n);
251 bool Key(
const Ch* str,
SizeType len,
bool copy) {
return String(str, len, copy); }
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]);
257 *stack_.template Push<uint64_t>() = h;
264 uint64_t* e = stack_.template Pop<uint64_t>(elementCount);
265 for (
SizeType i = 0; i < elementCount; i++)
267 *stack_.template Push<uint64_t>() = h;
275 return *stack_.template Top<uint64_t>();
279 static const size_t kDefaultSize = 256;
295 const unsigned char* d =
static_cast<const unsigned char*
>(data);
296 for (
size_t i = 0; i < len; i++)
298 *stack_.template Push<uint64_t>() = h;
315 template <
typename SchemaDocumentType>
321 typedef typename ValueType::Ch
Ch;
326 kPatternValidatorWithAdditionalProperty
336 arrayElementHashCodes(),
339 patternPropertiesValidators(),
340 patternPropertiesValidatorCount(),
341 patternPropertiesSchemas(),
342 patternPropertiesSchemaCount(),
343 valuePatternValidatorType(kPatternValidatorOnly),
346 valueUniqueness(false),
347 arrayUniqueness(false)
353 factory.DestroryHasher(hasher);
355 for (
SizeType i = 0; i < validatorCount; i++)
356 factory.DestroySchemaValidator(validators[i]);
357 factory.FreeState(validators);
359 if (patternPropertiesValidators) {
360 for (
SizeType i = 0; i < patternPropertiesValidatorCount; i++)
361 factory.DestroySchemaValidator(patternPropertiesValidators[i]);
362 factory.FreeState(patternPropertiesValidators);
364 if (patternPropertiesSchemas)
365 factory.FreeState(patternPropertiesSchemas);
367 factory.FreeState(propertyExist);
395 template <
typename SchemaDocumentType>
398 typedef typename SchemaDocumentType::ValueType
ValueType;
402 typedef typename EncodingType::Ch
Ch;
409 Schema(SchemaDocumentType* schemaDocument,
const PointerType& p,
const ValueType&
value,
const ValueType& document, AllocatorType* allocator) :
412 pointer_(p, allocator),
417 type_((1 << kTotalSchemaType) - 1),
419 notValidatorIndex_(),
421 additionalPropertiesSchema_(),
422 patternProperties_(),
423 patternPropertyCount_(),
427 additionalProperties_(true),
430 hasSchemaDependencies_(),
431 additionalItemsSchema_(),
437 additionalItems_(true),
442 exclusiveMinimum_(false),
443 exclusiveMaximum_(false),
444 defaultValueLength_(0)
446 typedef typename SchemaDocumentType::ValueType
ValueType;
447 typedef typename ValueType::ConstValueIterator ConstValueIterator;
448 typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
450 if (!value.IsObject())
453 if (
const ValueType* v = GetMember(value, GetTypeString())) {
457 else if (v->IsArray())
458 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
462 if (
const ValueType* v = GetMember(value, GetEnumString()))
463 if (v->IsArray() && v->Size() > 0) {
465 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) {
467 char buffer[256u + 24];
469 EnumHasherType h(&hasherAllocator, 256);
471 enum_[enumCount_++] = h.GetHashCode();
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);
481 if (
const ValueType* v = GetMember(value, GetNotString())) {
482 schemaDocument->CreateSchema(¬_, p.Append(GetNotString(),
allocator_), *v, document);
483 notValidatorIndex_ = validatorCount_;
489 const ValueType* properties = GetMember(value, GetPropertiesString());
490 const ValueType* required = GetMember(value, GetRequiredString());
491 const ValueType* dependencies = GetMember(value, GetDependenciesString());
496 if (properties && properties->IsObject())
497 for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr)
498 AddUniqueElement(allProperties, itr->name);
500 if (required && required->IsArray())
501 for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
503 AddUniqueElement(allProperties, *itr);
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)
511 AddUniqueElement(allProperties, *i);
514 if (allProperties.Size() > 0) {
515 propertyCount_ = allProperties.Size();
517 for (
SizeType i = 0; i < propertyCount_; i++) {
519 properties_[i].
name = allProperties[i];
525 if (properties && properties->IsObject()) {
526 PointerType q = p.Append(GetPropertiesString(),
allocator_);
527 for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) {
529 if (FindPropertyIndex(itr->name, &index))
530 schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name,
allocator_), itr->value, document);
534 if (
const ValueType* v = GetMember(value, GetPatternPropertiesString())) {
535 PointerType q = p.Append(GetPatternPropertiesString(),
allocator_);
537 patternPropertyCount_ = 0;
539 for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {
541 patternProperties_[patternPropertyCount_].
pattern = CreatePattern(itr->name);
542 schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name,
allocator_), itr->value, document);
543 patternPropertyCount_++;
547 if (required && required->IsArray())
548 for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
549 if (itr->IsString()) {
551 if (FindPropertyIndex(*itr, &index)) {
552 properties_[index].required =
true;
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) {
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) {
568 if (FindPropertyIndex(*targetItr, &targetIndex))
569 properties_[sourceIndex].dependencies[targetIndex] =
true;
572 else if (itr->value.IsObject()) {
573 hasSchemaDependencies_ =
true;
574 schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name,
allocator_), itr->value, document);
575 properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_;
582 if (
const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) {
584 additionalProperties_ = v->GetBool();
585 else if (v->IsObject())
586 schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(),
allocator_), *v, document);
589 AssignIfExist(minProperties_, value, GetMinPropertiesString());
590 AssignIfExist(maxProperties_, value, GetMaxPropertiesString());
593 if (
const ValueType* v = GetMember(value, GetItemsString())) {
594 PointerType q = p.Append(GetItemsString(),
allocator_);
596 schemaDocument->CreateSchema(&itemsList_, q, *v, document);
597 else if (v->IsArray()) {
600 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++)
601 schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index,
allocator_), *itr, document);
605 AssignIfExist(minItems_, value, GetMinItemsString());
606 AssignIfExist(maxItems_, value, GetMaxItemsString());
608 if (
const ValueType* v = GetMember(value, GetAdditionalItemsString())) {
610 additionalItems_ = v->GetBool();
611 else if (v->IsObject())
612 schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(),
allocator_), *v, document);
615 AssignIfExist(uniqueItems_, value, GetUniqueItemsString());
618 AssignIfExist(minLength_, value, GetMinLengthString());
619 AssignIfExist(maxLength_, value, GetMaxLengthString());
621 if (
const ValueType* v = GetMember(value, GetPatternString()))
622 pattern_ = CreatePattern(*v);
625 if (
const ValueType* v = GetMember(value, GetMinimumString()))
629 if (
const ValueType* v = GetMember(value, GetMaximumString()))
633 AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString());
634 AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString());
636 if (
const ValueType* v = GetMember(value, GetMultipleOfString()))
637 if (v->IsNumber() && v->GetDouble() > 0.0)
641 if (
const ValueType* v = GetMember(value, GetDefaultValueString()))
643 defaultValueLength_ = v->GetStringLength();
648 AllocatorType::Free(enum_);
650 for (
SizeType i = 0; i < propertyCount_; i++)
652 AllocatorType::Free(properties_);
654 if (patternProperties_) {
655 for (
SizeType i = 0; i < patternPropertyCount_; i++)
657 AllocatorType::Free(patternProperties_);
659 AllocatorType::Free(itemsTuple_);
660 #if RAPIDJSON_SCHEMA_HAS_REGEX 662 pattern_->~RegexType();
663 AllocatorType::Free(pattern_);
683 else if (itemsTuple_) {
686 else if (additionalItemsSchema_)
688 else if (additionalItems_)
703 RAPIDJSON_FORCEINLINE
bool EndValue(Context& context)
const {
705 bool otherValid =
false;
710 bool patternValid =
true;
711 for (
SizeType i = 0; i < count; i++)
713 patternValid =
false;
724 if (!patternValid || !otherValid) {
729 else if (!patternValid && !otherValid) {
737 for (
SizeType i = 0; i < enumCount_; i++)
746 for (
SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++)
752 if (anyOf_.schemas) {
753 for (
SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)
761 if (oneOf_.schemas) {
762 bool oneValid =
false;
763 for (
SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++)
785 bool Null(Context& context)
const {
786 if (!(type_ & (1 << kNullSchemaType))) {
787 DisallowedType(context, GetNullString());
790 return CreateParallelValidator(context);
793 bool Bool(Context& context,
bool)
const {
794 if (!(type_ & (1 << kBooleanSchemaType))) {
795 DisallowedType(context, GetBooleanString());
798 return CreateParallelValidator(context);
801 bool Int(Context& context,
int i)
const {
802 if (!CheckInt(context, i))
804 return CreateParallelValidator(context);
807 bool Uint(Context& context,
unsigned u)
const {
808 if (!CheckUint(context, u))
810 return CreateParallelValidator(context);
814 if (!CheckInt(context, i))
816 return CreateParallelValidator(context);
820 if (!CheckUint(context, u))
822 return CreateParallelValidator(context);
825 bool Double(Context& context,
double d)
const {
826 if (!(type_ & (1 << kNumberSchemaType))) {
827 DisallowedType(context, GetNumberString());
831 if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d))
834 if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d))
837 if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d))
840 return CreateParallelValidator(context);
844 if (!(type_ & (1 << kStringSchemaType))) {
845 DisallowedType(context, GetStringString());
849 if (minLength_ != 0 || maxLength_ !=
SizeType(~0)) {
851 if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {
852 if (count < minLength_) {
856 if (count > maxLength_) {
863 if (pattern_ && !IsPatternMatch(pattern_, str, length)) {
868 return CreateParallelValidator(context);
872 if (!(type_ & (1 << kObjectSchemaType))) {
873 DisallowedType(context, GetObjectString());
877 if (hasDependencies_ || hasRequired_) {
879 std::memset(context.
propertyExist, 0,
sizeof(
bool) * propertyCount_);
882 if (patternProperties_) {
883 SizeType count = patternPropertyCount_ + 1;
889 return CreateParallelValidator(context);
892 bool Key(Context& context,
const Ch* str,
SizeType len,
bool)
const {
893 if (patternProperties_) {
895 for (
SizeType i = 0; i < patternPropertyCount_; i++)
896 if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) {
903 if (FindPropertyIndex(
ValueType(str, len).Move(), &index)) {
918 if (additionalPropertiesSchema_) {
928 else if (additionalProperties_) {
944 for (
SizeType index = 0; index < propertyCount_; index++)
945 if (properties_[index].required && !context.
propertyExist[index])
946 if (properties_[index].schema->defaultValueLength_ == 0 )
952 if (memberCount < minProperties_) {
957 if (memberCount > maxProperties_) {
962 if (hasDependencies_) {
964 for (
SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) {
969 for (
SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++)
976 if (!dependenciesValidator->
IsValid())
989 if (!(type_ & (1 << kArraySchemaType))) {
990 DisallowedType(context, GetArrayString());
997 return CreateParallelValidator(context);
1003 if (elementCount < minItems_) {
1008 if (elementCount > maxItems_) {
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));\ 1037 RAPIDJSON_STRING_(Properties,
'p',
'r',
'o',
'p',
'e',
'r',
't',
'i',
'e',
's')
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')
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')
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')
1059 #undef RAPIDJSON_STRING_ 1073 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1075 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 1076 typedef std::basic_regex<Ch> RegexType;
1078 typedef char RegexType;
1089 template <
typename V1,
typename V2>
1091 for (
typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
1094 V1 c(v, *allocator_);
1095 a.PushBack(c, *allocator_);
1099 typename ValueType::ConstMemberIterator itr = value.FindMember(name);
1100 return itr != value.MemberEnd() ? &(itr->value) : 0;
1104 if (
const ValueType* v = GetMember(value, name))
1110 if (
const ValueType* v = GetMember(value, name))
1111 if (v->IsUint64() && v->GetUint64() <=
SizeType(~0))
1112 out = static_cast<SizeType>(v->GetUint64());
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();
1123 schemaDocument.CreateSchema(&out.
schemas[i], q.Append(i, allocator_), (*v)[i], document);
1124 out.
begin = validatorCount_;
1125 validatorCount_ += out.
count;
1130 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1131 template <
typename ValueType>
1133 if (value.IsString()) {
1134 RegexType* r =
new (allocator_->Malloc(
sizeof(RegexType))) RegexType(value.GetString(), allocator_);
1137 AllocatorType::Free(r);
1149 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 1150 template <
typename ValueType>
1151 RegexType* CreatePattern(
const ValueType&
value) {
1152 if (value.IsString())
1153 RegexType *r = static_cast<RegexType*>(allocator_->Malloc(
sizeof(RegexType)));
1155 return new (r) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);
1157 catch (
const std::regex_error&) {
1158 AllocatorType::Free(r);
1163 static bool IsPatternMatch(
const RegexType* pattern,
const Ch *str,
SizeType length) {
1164 std::match_results<const Ch*> r;
1165 return std::regex_search(str, str + length, r, *pattern);
1168 template <
typename ValueType>
1169 RegexType* CreatePattern(
const ValueType&) {
return 0; }
1171 static bool IsPatternMatch(
const RegexType*,
const Ch *,
SizeType) {
return true; }
1172 #endif // RAPIDJSON_SCHEMA_USE_STDREGEX 1175 if (type == GetNullString() ) type_ |= 1 << kNullSchemaType;
1176 else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType;
1177 else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType;
1178 else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType;
1179 else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType;
1180 else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType;
1181 else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
1188 if (validatorCount_) {
1194 CreateSchemaValidators(context, allOf_);
1197 CreateSchemaValidators(context, anyOf_);
1200 CreateSchemaValidators(context, oneOf_);
1205 if (hasSchemaDependencies_) {
1206 for (
SizeType i = 0; i < propertyCount_; i++)
1207 if (properties_[i].dependenciesSchema)
1222 SizeType len = name.GetStringLength();
1223 const Ch* str = name.GetString();
1224 for (
SizeType index = 0; index < propertyCount_; index++)
1225 if (properties_[index].name.GetStringLength() == len &&
1226 (std::memcmp(properties_[index].name.GetString(), str,
sizeof(Ch) * len) == 0))
1235 if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) {
1236 DisallowedType(context, GetIntegerString());
1240 if (!minimum_.IsNull()) {
1241 if (minimum_.IsInt64()) {
1242 if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) {
1247 else if (minimum_.IsUint64()) {
1251 else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1255 if (!maximum_.IsNull()) {
1256 if (maximum_.IsInt64()) {
1257 if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) {
1262 else if (maximum_.IsUint64()) { }
1264 else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1268 if (!multipleOf_.IsNull()) {
1269 if (multipleOf_.IsUint64()) {
1270 if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) {
1275 else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1283 if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) {
1284 DisallowedType(context, GetIntegerString());
1288 if (!minimum_.IsNull()) {
1289 if (minimum_.IsUint64()) {
1290 if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) {
1295 else if (minimum_.IsInt64())
1297 else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1301 if (!maximum_.IsNull()) {
1302 if (maximum_.IsUint64()) {
1303 if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) {
1308 else if (maximum_.IsInt64()) {
1312 else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1316 if (!multipleOf_.IsNull()) {
1317 if (multipleOf_.IsUint64()) {
1318 if (i % multipleOf_.GetUint64() != 0) {
1323 else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1331 if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) {
1339 if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) {
1347 double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());
1348 double q = std::floor(a / b);
1349 double r = a - q * b;
1361 if (type_ & (1 << kNullSchemaType)) eh.
AddExpectedType(GetNullString());
1362 if (type_ & (1 << kBooleanSchemaType)) eh.
AddExpectedType(GetBooleanString());
1363 if (type_ & (1 << kObjectSchemaType)) eh.
AddExpectedType(GetObjectString());
1364 if (type_ & (1 << kArraySchemaType)) eh.
AddExpectedType(GetArrayString());
1365 if (type_ & (1 << kStringSchemaType)) eh.
AddExpectedType(GetStringString());
1367 if (type_ & (1 << kNumberSchemaType)) eh.
AddExpectedType(GetNumberString());
1368 else if (type_ & (1 << kIntegerSchemaType)) eh.
AddExpectedType(GetIntegerString());
1374 Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {}
1388 pattern->~RegexType();
1389 AllocatorType::Free(pattern);
1444 template<
typename Stack,
typename Ch>
1447 *documentStack.template Push<Ch>() =
'/';
1449 size_t length =
static_cast<size_t>((
sizeof(
SizeType) == 4 ?
u32toa(index, buffer) :
u64toa(index, buffer)) - buffer);
1450 for (
size_t i = 0; i < length; i++)
1451 *documentStack.template Push<Ch>() =
static_cast<Ch
>(buffer[i]);
1456 template <
typename Stack>
1460 char *buffer = documentStack.template Push<char>(1 + 10);
1463 documentStack.template Pop<char>(
static_cast<size_t>(10 - (end - buffer)));
1466 char *buffer = documentStack.template Push<char>(1 + 20);
1469 documentStack.template Pop<char>(
static_cast<size_t>(20 - (end - buffer)));
1479 template <
typename SchemaDocumentType>
1482 typedef typename SchemaDocumentType::Ch
Ch;
1485 virtual const SchemaDocumentType* GetRemoteDocument(
const Ch* uri,
SizeType length) = 0;
1500 template <
typename ValueT,
typename Allocator = CrtAllocator>
1507 typedef typename EncodingType::Ch
Ch;
1512 template <
typename,
typename,
typename>
1526 IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) :
1527 remoteProvider_(remoteProvider),
1528 allocator_(allocator),
1532 schemaMap_(allocator, kInitialSchemaMapSize),
1533 schemaRef_(allocator, kInitialSchemaRefSize)
1539 uri_.SetString(uri ? uri : noUri, uriLength, *allocator_);
1541 typeless_ =
static_cast<SchemaType*
>(allocator_->Malloc(
sizeof(SchemaType)));
1549 while (!schemaRef_.Empty()) {
1550 SchemaRefEntry* refEntry = schemaRef_.template Pop<SchemaRefEntry>(1);
1551 if (
const SchemaType* s = GetSchema(refEntry->
target)) {
1556 if (!GetSchema(refEntry->
source)) {
1557 new (schemaMap_.template Push<SchemaEntry>())
SchemaEntry(refEntry->
source, const_cast<SchemaType*>(s),
false, allocator_);
1560 else if (refEntry->
schema)
1561 *refEntry->
schema = typeless_;
1563 refEntry->~SchemaRefEntry();
1568 schemaRef_.ShrinkToFit();
1571 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 1574 remoteProvider_(rhs.remoteProvider_),
1575 allocator_(rhs.allocator_),
1576 ownAllocator_(rhs.ownAllocator_),
1578 typeless_(rhs.typeless_),
1579 schemaMap_(std::move(rhs.schemaMap_)),
1580 schemaRef_(std::move(rhs.schemaRef_)),
1581 uri_(std::move(rhs.uri_))
1583 rhs.remoteProvider_ = 0;
1585 rhs.ownAllocator_ = 0;
1592 while (!schemaMap_.Empty())
1593 schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry();
1596 typeless_->~SchemaType();
1597 Allocator::Free(typeless_);
1603 const URIType&
GetURI()
const {
return uri_; }
1615 SchemaRefEntry(
const PointerType& s,
const PointerType& t,
const SchemaType** outSchema, Allocator *allocator) :
source(s, allocator), target(t, allocator), schema(outSchema) {}
1622 SchemaEntry(
const PointerType& p, SchemaType* s,
bool o, Allocator* allocator) :
pointer(p, allocator), schema(s), owned(o) {}
1625 schema->~SchemaType();
1626 Allocator::Free(schema);
1636 *schema = typeless_;
1639 const SchemaType* s = GetSchema(pointer);
1641 CreateSchema(schema, pointer, v, document);
1643 for (
typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
1644 CreateSchemaRecursive(0, pointer.
Append(itr->name, allocator_), itr->value, document);
1647 for (
SizeType i = 0; i < v.Size(); i++)
1648 CreateSchemaRecursive(0, pointer.
Append(i, allocator_), v[i], document);
1651 void CreateSchema(
const SchemaType** schema,
const PointerType&
pointer,
const ValueType& v,
const ValueType& document) {
1654 if (!HandleRefSchema(pointer, schema, v, document)) {
1655 SchemaType* s =
new (allocator_->Malloc(
sizeof(SchemaType))) SchemaType(
this, pointer, v, document, allocator_);
1656 new (schemaMap_.template Push<SchemaEntry>())
SchemaEntry(pointer, s,
true, allocator_);
1663 bool HandleRefSchema(
const PointerType&
source,
const SchemaType** schema,
const ValueType& v,
const ValueType& document) {
1664 static const Ch kRefString[] = {
'$',
'r',
'e',
'f',
'\0' };
1665 static const ValueType kRefValue(kRefString, 4);
1667 typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue);
1668 if (itr == v.MemberEnd())
1671 if (itr->value.IsString()) {
1672 SizeType len = itr->value.GetStringLength();
1674 const Ch* s = itr->value.GetString();
1676 while (i < len && s[i] !=
'#')
1680 if (remoteProvider_) {
1682 PointerType
pointer(&s[i], len - i, allocator_);
1683 if (pointer.IsValid()) {
1684 if (
const SchemaType* sc = remoteDocument->GetSchema(pointer)) {
1687 new (schemaMap_.template Push<SchemaEntry>())
SchemaEntry(source, const_cast<SchemaType*>(sc),
false, allocator_);
1694 else if (s[i] ==
'#') {
1695 PointerType
pointer(&s[i], len - i, allocator_);
1696 if (pointer.IsValid()) {
1697 if (
const ValueType* nv = pointer.Get(document))
1698 if (HandleRefSchema(source, schema, *nv, document))
1701 new (schemaRef_.template Push<SchemaRefEntry>())
SchemaRefEntry(source, pointer, schema, allocator_);
1711 for (
const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
1712 if (pointer == target->pointer)
1713 return target->schema;
1718 for (
const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
1719 if (schema == target->schema)
1720 return target->pointer;
1721 return PointerType();
1726 static const size_t kInitialSchemaMapSize = 64;
1727 static const size_t kInitialSchemaRefSize = 64;
1760 typename SchemaDocumentType,
1773 typedef typename EncodingType::Ch
Ch;
1785 const SchemaDocumentType& schemaDocument,
1786 StateAllocator* allocator = 0,
1787 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1788 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1790 schemaDocument_(&schemaDocument),
1791 root_(schemaDocument.GetRoot()),
1792 stateAllocator_(allocator),
1793 ownStateAllocator_(0),
1794 schemaStack_(allocator, schemaStackCapacity),
1795 documentStack_(allocator, documentStackCapacity),
1799 missingDependents_(),
1815 const SchemaDocumentType& schemaDocument,
1816 OutputHandler& outputHandler,
1817 StateAllocator* allocator = 0,
1818 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1819 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1821 schemaDocument_(&schemaDocument),
1822 root_(schemaDocument.GetRoot()),
1823 stateAllocator_(allocator),
1824 ownStateAllocator_(0),
1825 schemaStack_(allocator, schemaStackCapacity),
1826 documentStack_(allocator, documentStackCapacity),
1827 outputHandler_(&outputHandler),
1830 missingDependents_(),
1846 while (!schemaStack_.Empty())
1848 documentStack_.Clear();
1850 currentError_.SetNull();
1851 missingDependents_.SetNull();
1865 return schemaStack_.Empty() ? PointerType() : CurrentSchema().GetPointer();
1870 return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword;
1875 if (documentStack_.Empty()) {
1876 return PointerType();
1879 return PointerType(documentStack_.template Bottom<Ch>(), documentStack_.GetSize() /
sizeof(Ch));
1884 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected);
1887 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected);
1890 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected);
1893 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected,
1894 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
1897 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected,
1898 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
1901 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected,
1902 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
1905 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected,
1906 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
1909 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected,
1910 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
1913 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected,
1914 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
1918 AddNumberError(SchemaType::GetMaxLengthString(),
1919 ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move());
1922 AddNumberError(SchemaType::GetMinLengthString(),
1923 ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move());
1926 currentError_.SetObject();
1927 currentError_.AddMember(GetActualString(), ValueType(str, length, GetStateAllocator()).Move(), GetStateAllocator());
1928 AddCurrentError(SchemaType::GetPatternString());
1932 currentError_.SetObject();
1933 currentError_.AddMember(GetDisallowedString(), ValueType(index).Move(), GetStateAllocator());
1934 AddCurrentError(SchemaType::GetAdditionalItemsString(),
true);
1937 AddNumberError(SchemaType::GetMinItemsString(),
1938 ValueType(actualCount).Move(), SValue(expectedCount).Move());
1941 AddNumberError(SchemaType::GetMaxItemsString(),
1942 ValueType(actualCount).Move(), SValue(expectedCount).Move());
1946 duplicates.PushBack(index1, GetStateAllocator());
1947 duplicates.PushBack(index2, GetStateAllocator());
1948 currentError_.SetObject();
1949 currentError_.AddMember(GetDuplicatesString(), duplicates, GetStateAllocator());
1950 AddCurrentError(SchemaType::GetUniqueItemsString(),
true);
1954 AddNumberError(SchemaType::GetMaxPropertiesString(),
1955 ValueType(actualCount).Move(), SValue(expectedCount).Move());
1958 AddNumberError(SchemaType::GetMinPropertiesString(),
1959 ValueType(actualCount).Move(), SValue(expectedCount).Move());
1962 currentError_.SetArray();
1965 currentError_.PushBack(ValueType(name, GetStateAllocator()).Move(), GetStateAllocator());
1968 if (currentError_.Empty())
1971 error.AddMember(GetMissingString(), currentError_, GetStateAllocator());
1972 currentError_ = error;
1973 AddCurrentError(SchemaType::GetRequiredString());
1977 for (
SizeType i = 0; i < count; ++i)
1978 MergeError(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError());
1981 currentError_.SetObject();
1982 currentError_.AddMember(GetDisallowedString(), ValueType(name, length, GetStateAllocator()).Move(), GetStateAllocator());
1983 AddCurrentError(SchemaType::GetAdditionalPropertiesString(),
true);
1987 currentError_.SetObject();
1990 missingDependents_.SetArray();
1993 missingDependents_.PushBack(ValueType(targetName, GetStateAllocator()).Move(), GetStateAllocator());
1996 if (!missingDependents_.Empty())
1997 currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(),
1998 missingDependents_, GetStateAllocator());
2001 currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(),
2002 static_cast<GenericSchemaValidator*>(subvalidator)->GetError(), GetStateAllocator());
2005 if (currentError_.ObjectEmpty())
2008 error.AddMember(GetErrorsString(), currentError_, GetStateAllocator());
2009 currentError_ = error;
2010 AddCurrentError(SchemaType::GetDependenciesString());
2015 currentError_.SetObject();
2016 AddCurrentError(SchemaType::GetEnumString());
2019 currentError_.SetArray();
2022 currentError_.PushBack(ValueType(expectedType, GetStateAllocator()).Move(), GetStateAllocator());
2026 error.AddMember(GetExpectedString(), currentError_, GetStateAllocator());
2027 error.AddMember(GetActualString(), ValueType(actualType, GetStateAllocator()).Move(), GetStateAllocator());
2028 currentError_ = error;
2029 AddCurrentError(SchemaType::GetTypeString());
2032 for (
SizeType i = 0; i < count; ++i) {
2033 MergeError(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError());
2037 AddErrorArray(SchemaType::GetAnyOfString(), subvalidators, count);
2040 AddErrorArray(SchemaType::GetOneOfString(), subvalidators, count);
2043 currentError_.SetObject();
2044 AddCurrentError(SchemaType::GetNotString());
2047 #define RAPIDJSON_STRING_(name, ...) \ 2048 static const StringRefType& Get##name##String() {\ 2049 static const Ch s[] = { __VA_ARGS__, '\0' };\ 2050 static const StringRefType v(s, static_cast<SizeType>(sizeof(s) / sizeof(Ch) - 1)); \ 2054 RAPIDJSON_STRING_(InstanceRef,
'i',
'n',
's',
't',
'a',
'n',
'c',
'e',
'R',
'e',
'f')
2058 RAPIDJSON_STRING_(Disallowed, 'd', 'i', 's', 'a', 'l', 'l', 'o', 'w', 'e', 'd')
2061 RAPIDJSON_STRING_(Duplicates, 'd', 'u', 'p', 'l', 'i', 'c', 'a', 't', 'e', 's')
2063 #undef RAPIDJSON_STRING_ 2065 #if RAPIDJSON_SCHEMA_VERBOSE 2066 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \ 2067 RAPIDJSON_MULTILINEMACRO_BEGIN\ 2068 *documentStack_.template Push<Ch>() = '\0';\ 2069 documentStack_.template Pop<Ch>(1);\ 2070 internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>());\ 2071 RAPIDJSON_MULTILINEMACRO_END 2073 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() 2076 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\ 2077 if (!valid_) return false; \ 2078 if (!BeginValue() || !CurrentSchema().method arg1) {\ 2079 RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\ 2080 return valid_ = false;\ 2083 #define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\ 2084 for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\ 2085 if (context->hasher)\ 2086 static_cast<HasherType*>(context->hasher)->method arg2;\ 2087 if (context->validators)\ 2088 for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\ 2089 static_cast<GenericSchemaValidator*>(context->validators[i_])->method arg2;\ 2090 if (context->patternPropertiesValidators)\ 2091 for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\ 2092 static_cast<GenericSchemaValidator*>(context->patternPropertiesValidators[i_])->method arg2;\ 2095 #define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\ 2096 return valid_ = EndValue() && (!outputHandler_ || outputHandler_->method arg2) 2098 #define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ 2099 RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\ 2100 RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\ 2101 RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2) 2118 return valid_ = !outputHandler_ || outputHandler_->StartObject();
2122 if (!valid_)
return false;
2123 AppendToken(str, len);
2124 if (!CurrentSchema().Key(CurrentContext(), str, len, copy))
return valid_ =
false;
2126 return valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy);
2130 if (!valid_)
return false;
2132 if (!CurrentSchema().EndObject(CurrentContext(), memberCount))
return valid_ =
false;
2139 return valid_ = !outputHandler_ || outputHandler_->StartArray();
2143 if (!valid_)
return false;
2145 if (!CurrentSchema().EndArray(CurrentContext(), elementCount))
return valid_ =
false;
2149 #undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_ 2150 #undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_ 2151 #undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ 2152 #undef RAPIDJSON_SCHEMA_HANDLE_VALUE_ 2157 #if RAPIDJSON_SCHEMA_VERBOSE 2160 &GetStateAllocator());
2166 StateAllocator::Free(v);
2174 return static_cast<HasherType*
>(hasher)->GetHashCode();
2180 StateAllocator::Free(h);
2184 return GetStateAllocator().Malloc(size);
2188 StateAllocator::Free(p);
2197 const SchemaDocumentType& schemaDocument,
2198 const SchemaType& root,
2199 const char* basePath,
size_t basePathSize,
2203 StateAllocator* allocator = 0,
2204 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
2205 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
2207 schemaDocument_(&schemaDocument),
2209 stateAllocator_(allocator),
2210 ownStateAllocator_(0),
2211 schemaStack_(allocator, schemaStackCapacity),
2212 documentStack_(allocator, documentStackCapacity),
2216 missingDependents_(),
2222 if (basePath && basePathSize)
2223 memcpy(documentStack_.template Push<char>(basePathSize), basePath, basePathSize);
2227 if (!stateAllocator_)
2228 stateAllocator_ = ownStateAllocator_ =
RAPIDJSON_NEW(StateAllocator)();
2229 return *stateAllocator_;
2233 if (schemaStack_.Empty())
2236 if (CurrentContext().inArray)
2239 if (!CurrentSchema().BeginValue(CurrentContext()))
2242 SizeType count = CurrentContext().patternPropertiesSchemaCount;
2243 const SchemaType** sa = CurrentContext().patternPropertiesSchemas;
2244 typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
2245 bool valueUniqueness = CurrentContext().valueUniqueness;
2247 PushSchema(*CurrentContext().valueSchema);
2250 CurrentContext().objectPatternValidatorType = patternValidatorType;
2251 ISchemaValidator**& va = CurrentContext().patternPropertiesValidators;
2252 SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount;
2253 va =
static_cast<ISchemaValidator**
>(MallocState(
sizeof(ISchemaValidator*) * count));
2254 for (
SizeType i = 0; i < count; i++)
2255 va[validatorCount++] = CreateSchemaValidator(*sa[i]);
2258 CurrentContext().arrayUniqueness = valueUniqueness;
2264 if (!CurrentSchema().EndValue(CurrentContext()))
2267 #if RAPIDJSON_SCHEMA_VERBOSE 2269 schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb);
2271 *documentStack_.template Push<Ch>() =
'\0';
2272 documentStack_.template Pop<Ch>(1);
2273 internal::PrintValidatorPointers(depth_, sb.
GetString(), documentStack_.template Bottom<Ch>());
2276 uint64_t h = CurrentContext().arrayUniqueness ?
static_cast<HasherType*
>(CurrentContext().hasher)->GetHashCode() : 0;
2280 if (!schemaStack_.Empty()) {
2281 Context& context = CurrentContext();
2282 if (context.valueUniqueness) {
2283 HashCodeArray* a =
static_cast<HashCodeArray*
>(context.arrayElementHashCodes);
2285 CurrentContext().arrayElementHashCodes = a =
new (GetStateAllocator().Malloc(
sizeof(HashCodeArray))) HashCodeArray(
kArrayType);
2287 if (itr->GetUint64() == h) {
2288 DuplicateItems(static_cast<SizeType>(itr - a->Begin()), a->Size());
2291 a->PushBack(h, GetStateAllocator());
2296 while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) !=
'/')
2303 documentStack_.template Reserve<Ch>(1 + len * 2);
2304 *documentStack_.template PushUnsafe<Ch>() =
'/';
2305 for (
SizeType i = 0; i < len; i++) {
2306 if (str[i] ==
'~') {
2307 *documentStack_.template PushUnsafe<Ch>() =
'~';
2308 *documentStack_.template PushUnsafe<Ch>() =
'0';
2310 else if (str[i] ==
'/') {
2311 *documentStack_.template PushUnsafe<Ch>() =
'~';
2312 *documentStack_.template PushUnsafe<Ch>() =
'1';
2315 *documentStack_.template PushUnsafe<Ch>() = str[i];
2319 RAPIDJSON_FORCEINLINE
void PushSchema(
const SchemaType& schema) {
new (schemaStack_.template Push<Context>()) Context(*
this, *
this, &schema); }
2322 Context* c = schemaStack_.template Pop<Context>(1);
2323 if (HashCodeArray* a = static_cast<HashCodeArray*>(c->arrayElementHashCodes)) {
2324 a->~HashCodeArray();
2325 StateAllocator::Free(a);
2332 PointerType instancePointer = GetInvalidDocumentPointer();
2333 ((parent && instancePointer.GetTokenCount() > 0)
2334 ? PointerType(instancePointer.GetTokens(), instancePointer.GetTokenCount() - 1)
2335 : instancePointer).StringifyUriFragment(sb);
2337 GetStateAllocator());
2338 result.AddMember(GetInstanceRefString(), instanceRef, GetStateAllocator());
2340 memcpy(sb.
Push(CurrentSchema().GetURI().GetStringLength()),
2341 CurrentSchema().GetURI().GetString(),
2342 CurrentSchema().GetURI().GetStringLength() *
sizeof(Ch));
2343 GetInvalidSchemaPointer().StringifyUriFragment(sb);
2345 GetStateAllocator());
2346 result.AddMember(GetSchemaRefString(), schemaRef, GetStateAllocator());
2351 if (member == error_.MemberEnd())
2352 error_.AddMember(keyword, error, GetStateAllocator());
2354 if (member->value.IsObject()) {
2356 errors.PushBack(member->value, GetStateAllocator());
2357 member->value = errors;
2359 member->value.PushBack(error, GetStateAllocator());
2363 void AddCurrentError(
const typename SchemaType::ValueType& keyword,
bool parent =
false) {
2364 AddErrorLocation(currentError_, parent);
2365 AddError(ValueType(keyword, GetStateAllocator(),
false).Move(), currentError_);
2370 AddError(it->name, it->value);
2374 void AddNumberError(
const typename SchemaType::ValueType& keyword, ValueType& actual,
const SValue& expected,
2375 const typename SchemaType::ValueType& (*exclusive)() = 0) {
2376 currentError_.SetObject();
2377 currentError_.AddMember(GetActualString(), actual, GetStateAllocator());
2378 currentError_.AddMember(GetExpectedString(), ValueType(expected, GetStateAllocator()).Move(), GetStateAllocator());
2380 currentError_.AddMember(ValueType(exclusive(), GetStateAllocator()).Move(),
true, GetStateAllocator());
2381 AddCurrentError(keyword);
2385 ISchemaValidator** subvalidators,
SizeType count) {
2387 for (
SizeType i = 0; i < count; ++i)
2388 errors.PushBack(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError(), GetStateAllocator());
2389 currentError_.SetObject();
2390 currentError_.AddMember(GetErrorsString(), errors, GetStateAllocator());
2391 AddCurrentError(keyword);
2394 const SchemaType&
CurrentSchema()
const {
return *schemaStack_.template Top<Context>()->schema; }
2396 const Context&
CurrentContext()
const {
return *schemaStack_.template Top<Context>(); }
2398 static const size_t kDefaultSchemaStackCapacity = 1024;
2399 static const size_t kDefaultDocumentStackCapacity = 256;
2411 #if RAPIDJSON_SCHEMA_VERBOSE 2432 unsigned parseFlags,
2433 typename InputStream,
2434 typename SourceEncoding,
2440 typedef typename InputStream::Ch
Ch;
2450 template <
typename Handler>
2454 parseResult_ = reader.template Parse<parseFlags>(is_, validator);
2456 isValid_ = validator.
IsValid();
2458 invalidSchemaPointer_ = PointerType();
2459 invalidSchemaKeyword_ = 0;
2460 invalidDocumentPointer_ = PointerType();
2467 error_.CopyFrom(validator.
GetError(), allocator_);
2470 return parseResult_;
2482 const SchemaDocumentType&
sd_;
2496 #endif // RAPIDJSON_SCHEMA_H_
const SValue & GetURI() const
SchemaDocumentType::Ch Ch
void PropertyViolations(ISchemaValidator **subvalidators, SizeType count)
const SchemaType * root_
Root schema.
SchemaType::ValueType ValueType
GenericStringRef< Ch > StringRefType
bool RawNumber(const Ch *str, SizeType length, bool copy)
StateAllocator & GetStateAllocator()
char * u64toa(uint64_t value, char *buffer)
bool FindPropertyIndex(const ValueType &name, SizeType *outIndex) const
void MergeError(ValueType &other)
const SchemaType ** patternPropertiesSchemas
bool Key(Context &context, const Ch *str, SizeType len, bool) const
virtual void AddMissingProperty(const SValue &name)=0
const SchemaType * schema
const CharType(& source)[N]
virtual ~IValidationErrorHandler()
void NotOneOf(ISchemaValidator **subvalidators, SizeType count)
RAPIDJSON_FORCEINLINE bool EndValue(Context &context) const
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Schema(SchemaDocumentType *schemaDocument, const PointerType &p, const ValueType &value, const ValueType &document, AllocatorType *allocator)
void TooManyItems(SizeType actualCount, SizeType expectedCount)
Context & CurrentContext()
RAPIDJSON_FORCEINLINE void PopSchema()
virtual void Disallowed()=0
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
virtual void TooFewProperties(SizeType actualCount, SizeType expectedCount)=0
void AboveMaximum(int64_t actual, const SValue &expected, bool exclusive)
virtual void DoesNotMatch(const Ch *str, SizeType length)=0
static void AssignIfExist(bool &out, const ValueType &value, const ValueType &name)
Represents an in-memory output stream.
virtual bool IsValid() const
Checks whether the current state is valid.
virtual void NotAllOf(ISchemaValidator **subvalidators, SizeType count)=0
const SchemaType * GetTypeless() const
virtual void DestroryHasher(void *hasher)
const ValueType & GetError() const
static const ValueType * GetMember(const ValueType &value, const ValueType &name)
bool EndArray(SizeType elementCount)
~GenericSchemaDocument()
Destructor.
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
bool EndObject(Context &context, SizeType memberCount) const
StackAllocator allocator_
void TooFewItems(SizeType actualCount, SizeType expectedCount)
SchemaValidationContext(SchemaValidatorFactoryType &f, ErrorHandlerType &eh, const SchemaType *s)
SchemaDocumentType::PointerType PointerType
bool hasSchemaDependencies_
const PointerType & GetInvalidDocumentPointer() const
virtual void AddMissingDependentProperty(const SValue &targetName)=0
bool Uint(Context &context, unsigned u) const
void NotMultipleOf(uint64_t actual, const SValue &expected)
bool EndArray(SizeType elementCount)
bool Double(Context &context, double d) const
C-runtime library allocator.
virtual void BelowMinimum(int64_t actual, const SValue &expected, bool exclusive)=0
void DisallowedProperty(const Ch *name, SizeType length)
SchemaDocumentType::ValueType ValueType
internal::Stack< Allocator > schemaRef_
const SchemaType * itemsList_
PatternValidatorType objectPatternValidatorType
StateAllocator * ownStateAllocator_
virtual void * MallocState(size_t size)
bool Bool(Context &context, bool) const
#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2)
void EndDisallowedType(const typename SchemaType::ValueType &actualType)
RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType &schema)
const Ch * GetString() const
const SchemaType * dependenciesSchema
OutputHandler * outputHandler_
void AddMissingDependentProperty(const SValue &targetName)
bool Uint64(Context &context, uint64_t u) const
ErrorHandlerType & error_handler
SizeType patternPropertiesValidatorCount
virtual void DisallowedItem(SizeType index)=0
Schema< SchemaDocumentType > SchemaType
void AssignIfExist(SchemaArray &out, SchemaDocumentType &schemaDocument, const PointerType &p, const ValueType &value, const ValueType &name, const ValueType &document)
void DisallowedItem(SizeType index)
size_t GetSize() const
Get the size of string in bytes in the string buffer.
bool CheckDoubleMinimum(Context &context, double d) const
const PointerType & GetInvalidSchemaPointer() const
virtual ISchemaValidator * CreateSchemaValidator(const SchemaType &root)
virtual void TooManyProperties(SizeType actualCount, SizeType expectedCount)=0
virtual void * MallocState(size_t size)=0
virtual ~ISchemaValidator()
SchemaType::SValue SValue
const Ch * GetInvalidSchemaKeyword() const
Gets the keyword of invalid schema.
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, OutputHandler &outputHandler, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Constructor with output handler.
IRemoteSchemaDocumentProviderType * remoteProvider_
const SchemaType * valueSchema
void TooLong(const Ch *str, SizeType length, SizeType expected)
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
internal::Schema< GenericSchemaDocument > SchemaType
virtual void TooLong(const Ch *str, SizeType length, SizeType expected)=0
A helper class for parsing with validation.
SchemaDocumentType::PointerType PointerType
void CreateSchema(const SchemaType **schema, const PointerType &pointer, const ValueType &v, const ValueType &document)
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
const SchemaType ** schema
virtual bool EndDependencyErrors()=0
bool StartArray(Context &context) const
internal::Stack< StateAllocator > documentStack_
stack to store the current path of validating document (Ch)
bool CreateParallelValidator(Context &context) const
GenericValue< EncodingType, AllocatorType > SValue
const SchemaType ** schemas
SchemaEntry(const PointerType &p, SchemaType *s, bool o, Allocator *allocator)
const Ch * invalidSchemaKeyword_
virtual void StartMissingProperties()=0
internal::GenericRegex< EncodingType, AllocatorType > RegexType
virtual void AboveMaximum(int64_t actual, const SValue &expected, bool exclusive)=0
const SchemaType * typeless_
const SchemaType * schema
SchemaDocumentType::SchemaType SchemaType
virtual uint64_t GetHashCode(void *hasher)
void DuplicateItems(SizeType index1, SizeType index2)
ValueType & GetError()
Gets the error object.
virtual void FreeState(void *p)
internal::Stack< StateAllocator > schemaStack_
stack to store the current path of schema (BaseSchemaType *)
~GenericSchemaValidator()
Destructor.
void TooManyProperties(SizeType actualCount, SizeType expectedCount)
const ValueType & GetError() const
#define RAPIDJSON_STRING_(name,...)
RegexType * CreatePattern(const ValueType &value)
virtual void StartDisallowedType()=0
Allocator * ownAllocator_
void BelowMinimum(int64_t actual, const SValue &expected, bool exclusive)
bool CheckInt(Context &context, int64_t i) const
void AddMissingProperty(const SValue &name)
union internal::Hasher::Number::U u
bool WriteNumber(const Number &n)
bool EndArray(Context &context, SizeType elementCount) const
Default implementation of Handler.
void AddType(const ValueType &type)
PointerType invalidDocumentPointer_
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
SizeType patternPropertiesSchemaCount
void AboveMaximum(double actual, const SValue &expected, bool exclusive)
virtual void EndMissingDependentProperties(const SValue &sourceName)=0
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
static uint64_t Hash(uint64_t h, uint64_t d)
const SchemaType * schema
Reference to a constant string (not taking a copy)
virtual void * CreateHasher()=0
virtual void NotMultipleOf(int64_t actual, const SValue &expected)=0
GenericPointer< ValueType, Allocator > PointerType
void BelowMinimum(uint64_t actual, const SValue &expected, bool exclusive)
PatternProperty * patternProperties_
static bool IsPatternMatch(const RegexType *pattern, const Ch *str, SizeType)
GenericValue< EncodingType, StateAllocator > ValueType
IGenericRemoteSchemaDocumentProvider< GenericSchemaDocument > IRemoteSchemaDocumentProviderType
virtual void DisallowedValue()=0
PointerType invalidSchemaPointer_
void AddCurrentError(const typename SchemaType::ValueType &keyword, bool parent=false)
GenericSchemaDocument(const ValueType &document, const Ch *uri=0, SizeType uriLength=0, IRemoteSchemaDocumentProviderType *remoteProvider=0, Allocator *allocator=0)
Constructor.
bool WriteBuffer(Type type, const void *data, size_t len)
bool EndDependencyErrors()
SizeType notValidatorIndex_
virtual ~IGenericRemoteSchemaDocumentProvider()
const Ch * GetInvalidSchemaKeyword() const
const URIType & GetURI() const
const SchemaType * additionalPropertiesSchema_
Default memory allocator used by the parser and DOM.
void Reset()
Reset the internal states.
internal::Stack< Allocator > schemaMap_
GenericValue< EncodingType, Allocator > URIType
void CreateSchemaValidators(Context &context, const SchemaArray &schemas) const
void BelowMinimum(double actual, const SValue &expected, bool exclusive)
bool Key(const Ch *str, SizeType len, bool copy)
uint64_t GetHashCode() const
unsigned __int64 uint64_t
GenericValue< UTF8<>, StateAllocator > HashCodeArray
ISchemaValidator ** patternPropertiesValidators
void DisallowedType(Context &context, const ValueType &actualType) const
PointerType GetPointer(const SchemaType *schema) const
bool Int64(Context &context, int64_t i) const
bool EndObject(SizeType memberCount)
#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)
bool EndObject(SizeType memberCount)
GenericSchemaDocument< Value > SchemaDocument
GenericSchemaDocument using Value type.
void AddDependencySchemaError(const SValue &sourceName, ISchemaValidator *subvalidator)
virtual void DestroySchemaValidator(ISchemaValidator *validator)
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
#define RAPIDJSON_SCHEMA_VERBOSE
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
bool HandleRefSchema(const PointerType &source, const SchemaType **schema, const ValueType &v, const ValueType &document)
const SchemaDocumentType * schemaDocument_
#define RAPIDJSON_DELETE(x)
! customization point for global delete
virtual void AddDependencySchemaError(const SValue &souceName, ISchemaValidator *subvalidator)=0
virtual void * CreateHasher()
void StartMissingDependentProperties()
char * u32toa(uint32_t value, char *buffer)
PatternValidatorType valuePatternValidatorType
const Ch * invalidKeyword
bool String(Context &context, const Ch *str, SizeType length, bool) const
ValueType missingDependents_
virtual void TooManyItems(SizeType actualCount, SizeType expectedCount)=0
bool CheckDoubleMultipleOf(Context &context, double d) const
A type-unsafe stack for storing different types of data.
virtual void TooShort(const Ch *str, SizeType length, SizeType expected)=0
#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)
#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)
bool RawNumber(const Ch *str, SizeType len, bool)
ValueType::EncodingType EncodingType
const ParseResult & GetParseResult() const
void TooShort(const Ch *str, SizeType length, SizeType expected)
SchemaValidatingReader(InputStream &is, const SchemaDocumentType &sd)
Constructor.
virtual bool IsValid() const =0
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
void NotMultipleOf(double actual, const SValue &expected)
virtual void EndDisallowedType(const typename SchemaType::ValueType &actualType)=0
void AboveMaximum(uint64_t actual, const SValue &expected, bool exclusive)
internal::Hasher< EncodingType, StateAllocator > HasherType
bool Int(Context &context, int i) const
void StartDisallowedType()
void AddExpectedType(const typename SchemaType::ValueType &expectedType)
bool BeginValue(Context &context) const
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
PointerType GetInvalidSchemaPointer() const
Gets the JSON pointer pointed to the invalid schema.
const SchemaType & CurrentSchema() const
SchemaType::SValue SValue
bool CheckDoubleMaximum(Context &context, double d) const
ValueType::EncodingType EncodingType
const Context & CurrentContext() const
void * arrayElementHashCodes
SizeType defaultValueLength_
bool StartObject(Context &context) const
const SchemaType * GetSchema(const PointerType &pointer) const
bool EndMissingProperties()
bool operator()(Handler &handler)
void CreateSchemaRecursive(const SchemaType **schema, const PointerType &pointer, const ValueType &v, const ValueType &document)
const GenericPointer< typename T::ValueType > T2 value
SchemaRefEntry(const PointerType &s, const PointerType &t, const SchemaType **outSchema, Allocator *allocator)
void NoneOf(ISchemaValidator **subvalidators, SizeType count)
virtual void NotOneOf(ISchemaValidator **subvalidators, SizeType count)=0
virtual uint64_t GetHashCode(void *hasher)=0
void StartDependencyErrors()
const SchemaDocumentType & sd_
Hasher(Allocator *allocator=0, size_t stackCapacity=kDefaultSize)
Regular expression engine with subset of ECMAscript grammar.
bool Key(const Ch *str, SizeType len, bool copy)
void AddUniqueElement(V1 &a, const V2 &v)
virtual bool EndMissingProperties()=0
SizeType arrayElementIndex
virtual void StartMissingDependentProperties()=0
virtual void AddExpectedType(const typename SchemaType::ValueType &expectedType)=0
void AddNumberError(const typename SchemaType::ValueType &keyword, ValueType &actual, const SValue &expected, const typename SchemaType::ValueType &(*exclusive)()=0)
Result of parsing (wraps ParseErrorCode)
IGenericRemoteSchemaDocumentProvider< SchemaDocument > IRemoteSchemaDocumentProvider
IGenericRemoteSchemaDocumentProvider using SchemaDocument.
void AppendToken(const Ch *str, SizeType len)
Stack< Allocator > stack_
SchemaType::EncodingType EncodingType
bool additionalProperties_
void AddErrorLocation(ValueType &result, bool parent)
PointerType GetInvalidDocumentPointer() const
Gets the JSON pointer pointed to the invalid value.
Schema< SchemaDocumentType > SchemaType
virtual ISchemaValidator * CreateSchemaValidator(const SchemaType &)=0
bool String(const Ch *str, SizeType length, bool copy)
IValidationErrorHandler< SchemaType > ErrorHandlerType
SchemaValidatorFactoryType & factory
bool String(const Ch *str, SizeType len, bool)
bool Null(Context &context) const
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Constructor without output handler.
SizeType dependenciesValidatorIndex
const PointerType & GetPointer() const
virtual ~ISchemaStateFactory()
bool CheckUint(Context &context, uint64_t i) const
StateAllocator * stateAllocator_
const SchemaType * additionalItemsSchema_
const GenericPointer< typename T::ValueType > & pointer
SchemaType::Context Context
SchemaDocumentType::AllocatorType AllocatorType
void NotMultipleOf(int64_t actual, const SValue &expected)
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, const SchemaType &root, const char *basePath, size_t basePathSize, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
bool Search(InputStream &is)
(Constant) member iterator for a JSON object value
void StartMissingProperties()
SchemaDocumentType::PointerType PointerType
void AddErrorArray(const typename SchemaType::ValueType &keyword, ISchemaValidator **subvalidators, SizeType count)
virtual void PropertyViolations(ISchemaValidator **subvalidators, SizeType count)=0
GenericValue< SourceEncoding, StackAllocator > ValueType
const SchemaType ** itemsTuple_
~SchemaValidationContext()
const SchemaType & GetRoot() const
Get the root schema.
ISchemaStateFactory< SchemaType > SchemaValidatorFactoryType
GenericSchemaValidator< SchemaDocument > SchemaValidator
#define RAPIDJSON_ASSERT(x)
Assertion.
SchemaValidationContext< SchemaDocumentType > Context
void AddError(ValueType &keyword, ValueType &error)
void DoesNotMatch(const Ch *str, SizeType length)
SizeType patternPropertyCount_
static void AssignIfExist(SizeType &out, const ValueType &value, const ValueType &name)
virtual void DisallowedProperty(const Ch *name, SizeType length)=0
#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)
virtual void TooFewItems(SizeType actualCount, SizeType expectedCount)=0
virtual void NoneOf(ISchemaValidator **subvalidators, SizeType count)=0
ISchemaValidator ** validators
void TooFewProperties(SizeType actualCount, SizeType expectedCount)
AllocatorType * allocator_
IValidationErrorHandler< Schema > ErrorHandler
virtual void StartDependencyErrors()=0
void NotAllOf(ISchemaValidator **subvalidators, SizeType count)
void EndMissingDependentProperties(const SValue &sourceName)
bool WriteType(Type type)
SizeType itemsTupleCount_