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
58RAPIDJSON_DIAG_OFF(effc++)
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)
75#if RAPIDJSON_SCHEMA_VERBOSE
79inline void PrintInvalidKeyword(
const char* keyword) {
80 printf(
"Fail keyword: %s\n", keyword);
83inline void PrintInvalidKeyword(
const wchar_t* keyword) {
84 wprintf(L
"Fail keyword: %ls\n", keyword);
87inline void PrintInvalidDocument(
const char* document) {
88 printf(
"Fail document: %s\n\n", document);
91inline void PrintInvalidDocument(
const wchar_t* document) {
92 wprintf(L
"Fail document: %ls\n\n", document);
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);
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);
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)\
117RAPIDJSON_MULTILINEMACRO_BEGIN\
118 context.invalidKeyword = keyword.GetString();\
119 RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\
121RAPIDJSON_MULTILINEMACRO_END
126template <
typename ValueType,
typename Allocator>
131template <
typename SchemaDocumentType>
146template <
typename SchemaType>
162template <
typename SchemaType>
165 typedef typename SchemaType::Ch
Ch;
166 typedef typename SchemaType::SValue
SValue;
219template<
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); }
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); }
237 return WriteNumber(n);
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;
288 bool WriteType(
Type type) {
return WriteBuffer(type, 0, 0); }
290 bool WriteNumber(
const Number& n) {
return WriteBuffer(
kNumberType, &n,
sizeof(n)); }
292 bool WriteBuffer(
Type type,
const void* data,
size_t len) {
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;
309 Stack<Allocator> stack_;
315template <
typename SchemaDocumentType>
321 typedef typename ValueType::Ch
Ch;
395template <
typename SchemaDocumentType>
398 typedef typename SchemaDocumentType::ValueType
ValueType;
402 typedef typename EncodingType::Ch
Ch;
410 allocator_(allocator),
411 uri_(schemaDocument->
GetURI(), *allocator),
412 pointer_(
p, allocator),
413 typeless_(schemaDocument->GetTypeless()),
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())
457 else if (v->IsArray())
458 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
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[256u + 24];
468 MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer));
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);
482 schemaDocument->CreateSchema(&
not_,
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();
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_;
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_);
536 patternProperties_ =
static_cast<PatternProperty*
>(allocator_->Malloc(
sizeof(PatternProperty) * v->MemberCount()));
537 patternPropertyCount_ = 0;
539 for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {
540 new (&patternProperties_[patternPropertyCount_]) PatternProperty();
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());
596 schemaDocument->CreateSchema(&itemsList_, q, *v, document);
597 else if (v->IsArray()) {
598 itemsTuple_ =
static_cast<const Schema**
>(allocator_->Malloc(
sizeof(
const Schema*) * v->Size()));
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());
622 pattern_ = CreatePattern(*v);
627 minimum_.CopyFrom(*v, *allocator_);
631 maximum_.CopyFrom(*v, *allocator_);
633 AssignIfExist(exclusiveMinimum_,
value, GetExclusiveMinimumString());
634 AssignIfExist(exclusiveMaximum_,
value, GetExclusiveMaximumString());
637 if (v->IsNumber() && v->GetDouble() > 0.0)
638 multipleOf_.CopyFrom(*v, *allocator_);
641 if (
const ValueType* v = GetMember(
value, GetDefaultValueString()))
643 defaultValueLength_ = v->GetStringLength();
648 AllocatorType::Free(enum_);
650 for (
SizeType i = 0; i < propertyCount_; i++)
651 properties_[i].~Property();
652 AllocatorType::Free(properties_);
654 if (patternProperties_) {
655 for (
SizeType i = 0; i < patternPropertyCount_; i++)
656 patternProperties_[i].~PatternProperty();
657 AllocatorType::Free(patternProperties_);
659 AllocatorType::Free(itemsTuple_);
660#if RAPIDJSON_SCHEMA_HAS_REGEX
662 pattern_->~RegexType();
663 AllocatorType::Free(pattern_);
679 context.valueUniqueness =
true;
682 context.valueSchema = itemsList_;
683 else if (itemsTuple_) {
684 if (
context.arrayElementIndex < itemsTupleCount_)
686 else if (additionalItemsSchema_)
687 context.valueSchema = additionalItemsSchema_;
688 else if (additionalItems_)
689 context.valueSchema = typeless_;
696 context.valueSchema = typeless_;
704 if (
context.patternPropertiesValidatorCount > 0) {
705 bool otherValid =
false;
707 if (
context.objectPatternValidatorType != Context::kPatternValidatorOnly)
708 otherValid =
context.patternPropertiesValidators[--
count]->IsValid();
710 bool patternValid =
true;
712 if (!
context.patternPropertiesValidators[i]->IsValid()) {
713 patternValid =
false;
717 if (
context.objectPatternValidatorType == Context::kPatternValidatorOnly) {
723 else if (
context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) {
724 if (!patternValid || !otherValid) {
729 else if (!patternValid && !otherValid) {
737 for (
SizeType i = 0; i < enumCount_; i++)
740 context.error_handler.DisallowedValue();
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);
752 if (anyOf_.schemas) {
753 for (
SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)
754 if (
context.validators[i]->IsValid())
756 context.error_handler.NoneOf(&
context.validators[anyOf_.begin], anyOf_.count);
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()) {
766 context.error_handler.NotOneOf(&
context.validators[oneOf_.begin], oneOf_.count);
772 context.error_handler.NotOneOf(&
context.validators[oneOf_.begin], oneOf_.count);
777 if (
not_ &&
context.validators[notValidatorIndex_]->IsValid()) {
778 context.error_handler.Disallowed();
786 if (!(type_ & (1 << kNullSchemaType))) {
787 DisallowedType(
context, GetNullString());
790 return CreateParallelValidator(
context);
794 if (!(type_ & (1 << kBooleanSchemaType))) {
795 DisallowedType(
context, GetBooleanString());
798 return CreateParallelValidator(
context);
804 return CreateParallelValidator(
context);
810 return CreateParallelValidator(
context);
816 return CreateParallelValidator(
context);
822 return CreateParallelValidator(
context);
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)) {
852 if (
count < minLength_) {
853 context.error_handler.TooShort(str, length, minLength_);
856 if (
count > maxLength_) {
857 context.error_handler.TooLong(str, length, maxLength_);
863 if (pattern_ && !IsPatternMatch(pattern_, str, length)) {
864 context.error_handler.DoesNotMatch(str, length);
868 return CreateParallelValidator(
context);
872 if (!(type_ & (1 << kObjectSchemaType))) {
873 DisallowedType(
context, GetObjectString());
877 if (hasDependencies_ || hasRequired_) {
878 context.propertyExist =
static_cast<bool*
>(
context.factory.MallocState(
sizeof(
bool) * propertyCount_));
879 std::memset(
context.propertyExist, 0,
sizeof(
bool) * propertyCount_);
882 if (patternProperties_) {
885 context.patternPropertiesSchemaCount = 0;
889 return CreateParallelValidator(
context);
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_;
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;
910 context.valueSchema = properties_[index].schema;
913 context.propertyExist[index] =
true;
918 if (additionalPropertiesSchema_) {
919 if (additionalPropertiesSchema_ &&
context.patternPropertiesSchemaCount > 0) {
920 context.patternPropertiesSchemas[
context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_;
921 context.valueSchema = typeless_;
922 context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty;
925 context.valueSchema = additionalPropertiesSchema_;
928 else if (additionalProperties_) {
929 context.valueSchema = typeless_;
933 if (
context.patternPropertiesSchemaCount == 0) {
934 context.error_handler.DisallowedProperty(str,
len);
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())
952 if (memberCount < minProperties_) {
953 context.error_handler.TooFewProperties(memberCount, minProperties_);
957 if (memberCount > maxProperties_) {
958 context.error_handler.TooManyProperties(memberCount, maxProperties_);
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);
974 else if (
source.dependenciesSchema) {
976 if (!dependenciesValidator->
IsValid())
977 context.error_handler.AddDependencySchemaError(
source.name, dependenciesValidator);
981 if (
context.error_handler.EndDependencyErrors())
989 if (!(type_ & (1 << kArraySchemaType))) {
990 DisallowedType(
context, GetArrayString());
997 return CreateParallelValidator(
context);
1003 if (elementCount < minItems_) {
1004 context.error_handler.TooFewItems(elementCount, minItems_);
1008 if (elementCount > maxItems_) {
1009 context.error_handler.TooManyItems(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_
1062 enum SchemaValueType {
1073#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX
1075#elif RAPIDJSON_SCHEMA_USE_STDREGEX
1076 typedef std::basic_regex<Ch> RegexType;
1078 typedef char RegexType;
1081 struct SchemaArray {
1082 SchemaArray() : schemas(),
count() {}
1083 ~SchemaArray() { AllocatorType::Free(schemas); }
1084 const SchemaType** schemas;
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)
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;
1103 static void AssignIfExist(
bool& out,
const ValueType&
value,
const ValueType&
name) {
1104 if (
const ValueType* v = GetMember(
value,
name))
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());
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*)));
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;
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()) {
1137 AllocatorType::Free(
r);
1145 static bool IsPatternMatch(
const RegexType* pattern,
const Ch *str,
SizeType) {
1146 GenericRegexSearch<RegexType> rs(*pattern);
1147 return rs.Search(str);
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; }
1174 void AddType(
const ValueType& type) {
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);
1184 bool CreateParallelValidator(Context&
context)
const {
1185 if (enum_ ||
context.arrayUniqueness)
1188 if (validatorCount_) {
1190 context.validators =
static_cast<ISchemaValidator**
>(
context.factory.MallocState(
sizeof(ISchemaValidator*) * validatorCount_));
1191 context.validatorCount = validatorCount_;
1194 CreateSchemaValidators(
context, allOf_);
1197 CreateSchemaValidators(
context, anyOf_);
1200 CreateSchemaValidators(
context, oneOf_);
1203 context.validators[notValidatorIndex_] =
context.factory.CreateSchemaValidator(*
not_);
1205 if (hasSchemaDependencies_) {
1206 for (
SizeType i = 0; i < propertyCount_; i++)
1207 if (properties_[i].dependenciesSchema)
1208 context.validators[properties_[i].dependenciesValidatorIndex] =
context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema);
1215 void CreateSchemaValidators(Context&
context,
const SchemaArray& schemas)
const {
1216 for (
SizeType i = 0; i < schemas.count; i++)
1217 context.validators[schemas.begin + i] =
context.factory.CreateSchemaValidator(*schemas.schemas[i]);
1221 bool FindPropertyIndex(
const ValueType&
name,
SizeType* outIndex)
const {
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()) {
1243 context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
1247 else if (minimum_.IsUint64()) {
1248 context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
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()) {
1258 context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
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) {
1271 context.error_handler.NotMultipleOf(i, multipleOf_);
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()) {
1291 context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
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()) {
1304 context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
1308 else if (maximum_.IsInt64()) {
1309 context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
1312 else if (!CheckDoubleMaximum(
context,
static_cast<double>(i)))
1316 if (!multipleOf_.IsNull()) {
1317 if (multipleOf_.IsUint64()) {
1318 if (i % multipleOf_.GetUint64() != 0) {
1319 context.error_handler.NotMultipleOf(i, multipleOf_);
1323 else if (!CheckDoubleMultipleOf(
context,
static_cast<double>(i)))
1330 bool CheckDoubleMinimum(Context&
context,
double d)
const {
1331 if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) {
1332 context.error_handler.BelowMinimum(d, minimum_, exclusiveMinimum_);
1338 bool CheckDoubleMaximum(Context&
context,
double d)
const {
1339 if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) {
1340 context.error_handler.AboveMaximum(d, maximum_, exclusiveMaximum_);
1346 bool CheckDoubleMultipleOf(Context&
context,
double d)
const {
1347 double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());
1348 double q = std::floor(
a / b);
1349 double r =
a - q * b;
1351 context.error_handler.NotMultipleOf(d, multipleOf_);
1357 void DisallowedType(Context&
context,
const ValueType& actualType)
const {
1358 ErrorHandler& eh =
context.error_handler;
1359 eh.StartDisallowedType();
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());
1370 eh.EndDisallowedType(actualType);
1374 Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {}
1375 ~Property() { AllocatorType::Free(dependencies); }
1377 const SchemaType* schema;
1378 const SchemaType* dependenciesSchema;
1379 SizeType dependenciesValidatorIndex;
1384 struct PatternProperty {
1385 PatternProperty() : schema(), pattern() {}
1386 ~PatternProperty() {
1388 pattern->~RegexType();
1389 AllocatorType::Free(pattern);
1392 const SchemaType* schema;
1396 AllocatorType* allocator_;
1398 PointerType pointer_;
1399 const SchemaType* typeless_;
1405 const SchemaType*
not_;
1410 Property* properties_;
1411 const SchemaType* additionalPropertiesSchema_;
1412 PatternProperty* patternProperties_;
1417 bool additionalProperties_;
1418 bool hasDependencies_;
1420 bool hasSchemaDependencies_;
1422 const SchemaType* additionalItemsSchema_;
1423 const SchemaType* itemsList_;
1424 const SchemaType** itemsTuple_;
1428 bool additionalItems_;
1431 RegexType* pattern_;
1438 bool exclusiveMinimum_;
1439 bool exclusiveMaximum_;
1444template<
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]);
1456template <
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)));
1479template <
typename SchemaDocumentType>
1482 typedef typename SchemaDocumentType::Ch
Ch;
1500template <
typename ValueT,
typename Allocator = CrtAllocator>
1507 typedef typename EncodingType::Ch
Ch;
1512 template <
typename,
typename,
typename>
1527 remoteProvider_(remoteProvider),
1528 allocator_(allocator),
1532 schemaMap_(allocator, kInitialSchemaMapSize),
1533 schemaRef_(allocator, kInitialSchemaRefSize)
1539 uri_.SetString(uri ? uri : noUri, uriLength, *allocator_);
1546 CreateSchemaRecursive(&root_,
PointerType(), document, document);
1549 while (!schemaRef_.Empty()) {
1550 SchemaRefEntry* refEntry = schemaRef_.template Pop<SchemaRefEntry>(1);
1551 if (
const SchemaType*
s = GetSchema(refEntry->target)) {
1552 if (refEntry->schema)
1553 *refEntry->schema =
s;
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_);
1614 struct SchemaRefEntry {
1621 struct SchemaEntry {
1625 schema->~SchemaType();
1626 Allocator::Free(schema);
1636 *schema = typeless_;
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);
1654 if (!HandleRefSchema(
pointer, schema, v, document)) {
1656 new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(
pointer,
s,
true, allocator_);
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()) {
1674 const Ch*
s = itr->value.GetString();
1676 while (i <
len &&
s[i] !=
'#')
1680 if (remoteProvider_) {
1687 new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(
source,
const_cast<SchemaType*
>(sc),
false, allocator_);
1694 else if (
s[i] ==
'#') {
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;
1724 const SchemaType* GetTypeless()
const {
return typeless_; }
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()) {
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(),
1941 AddNumberError(SchemaType::GetMaxItemsString(),
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(),
1958 AddNumberError(SchemaType::GetMinPropertiesString(),
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());
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(),
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());
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_() \
2067RAPIDJSON_MULTILINEMACRO_BEGIN\
2068 *documentStack_.template Push<Ch>() = '\0';\
2069 documentStack_.template Pop<Ch>(1);\
2070 internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>());\
2071RAPIDJSON_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_
2160 &GetStateAllocator());
2166 StateAllocator::Free(v);
2180 StateAllocator::Free(h);
2184 return GetStateAllocator().Malloc(size);
2188 StateAllocator::Free(
p);
2192 typedef typename SchemaType::Context Context;
2197 const SchemaDocumentType& schemaDocument,
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);
2226 StateAllocator& GetStateAllocator() {
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));
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) {
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>() =
'/';
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); }
2321 RAPIDJSON_FORCEINLINE
void PopSchema() {
2322 Context* c = schemaStack_.template Pop<Context>(1);
2323 if (HashCodeArray*
a =
static_cast<HashCodeArray*
>(c->arrayElementHashCodes)) {
2324 a->~HashCodeArray();
2325 StateAllocator::Free(
a);
2330 void AddErrorLocation(
ValueType& result,
bool parent) {
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));
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);
2384 void AddErrorArray(
const typename SchemaType::ValueType& keyword,
2389 currentError_.SetObject();
2390 currentError_.AddMember(GetErrorsString(), errors, GetStateAllocator());
2391 AddCurrentError(keyword);
2394 const SchemaType& CurrentSchema()
const {
return *schemaStack_.template Top<Context>()->schema; }
2395 Context& CurrentContext() {
return *schemaStack_.template Top<Context>(); }
2396 const Context& CurrentContext()
const {
return *schemaStack_.template Top<Context>(); }
2398 static const size_t kDefaultSchemaStackCapacity = 1024;
2399 static const size_t kDefaultDocumentStackCapacity = 256;
2400 const SchemaDocumentType* schemaDocument_;
2402 StateAllocator* stateAllocator_;
2403 StateAllocator* ownStateAllocator_;
2406 OutputHandler* outputHandler_;
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();
2459 invalidSchemaKeyword_ = 0;
2467 error_.CopyFrom(validator.
GetError(), allocator_);
2470 return parseResult_;
2482 const SchemaDocumentType& sd_;
2486 const Ch* invalidSchemaKeyword_;
2488 StackAllocator allocator_;
C-runtime library allocator.
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
const URIType & GetURI() const
GenericValue< EncodingType, Allocator > URIType
internal::Schema< GenericSchemaDocument > SchemaType
GenericPointer< ValueType, Allocator > PointerType
ValueType::EncodingType EncodingType
const SchemaType & GetRoot() const
Get the root schema.
~GenericSchemaDocument()
Destructor.
GenericSchemaDocument(const ValueType &document, const Ch *uri=0, SizeType uriLength=0, IRemoteSchemaDocumentProviderType *remoteProvider=0, Allocator *allocator=0)
Constructor.
IGenericRemoteSchemaDocumentProvider< GenericSchemaDocument > IRemoteSchemaDocumentProviderType
virtual void DestroryHasher(void *hasher)
void BelowMinimum(int64_t actual, const SValue &expected, bool exclusive)
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Constructor without output handler.
ValueType & GetError()
Gets the error object.
void TooLong(const Ch *str, SizeType length, SizeType expected)
SchemaType::SValue SValue
void AddDependencySchemaError(const SValue &sourceName, ISchemaValidator *subvalidator)
void PropertyViolations(ISchemaValidator **subvalidators, SizeType count)
void DisallowedItem(SizeType index)
bool String(const Ch *str, SizeType length, bool copy)
~GenericSchemaValidator()
Destructor.
SchemaDocumentType::SchemaType SchemaType
void StartMissingProperties()
void NotAllOf(ISchemaValidator **subvalidators, SizeType count)
void DisallowedProperty(const Ch *name, SizeType length)
virtual void * CreateHasher()
void Reset()
Reset the internal states.
void AboveMaximum(int64_t actual, const SValue &expected, bool exclusive)
GenericStringRef< Ch > StringRefType
virtual void FreeState(void *p)
bool EndMissingProperties()
PointerType GetInvalidSchemaPointer() const
Gets the JSON pointer pointed to the invalid schema.
void NotMultipleOf(uint64_t actual, const SValue &expected)
bool EndArray(SizeType elementCount)
void AddExpectedType(const typename SchemaType::ValueType &expectedType)
virtual ISchemaValidator * CreateSchemaValidator(const SchemaType &root)
bool Key(const Ch *str, SizeType len, bool copy)
void StartDependencyErrors()
void TooShort(const Ch *str, SizeType length, SizeType expected)
void TooManyItems(SizeType actualCount, SizeType expectedCount)
void DuplicateItems(SizeType index1, SizeType index2)
void AddMissingDependentProperty(const SValue &targetName)
void AddMissingProperty(const SValue &name)
virtual bool IsValid() const
Checks whether the current state is valid.
void AboveMaximum(uint64_t actual, const SValue &expected, bool exclusive)
void StartDisallowedType()
SchemaDocumentType::PointerType PointerType
virtual void * MallocState(size_t size)
SchemaType::EncodingType EncodingType
bool EndObject(SizeType memberCount)
void NoneOf(ISchemaValidator **subvalidators, SizeType count)
void TooFewProperties(SizeType actualCount, SizeType expectedCount)
void NotMultipleOf(int64_t actual, const SValue &expected)
const Ch * GetInvalidSchemaKeyword() const
Gets the keyword of invalid schema.
bool EndDependencyErrors()
void AboveMaximum(double actual, const SValue &expected, bool exclusive)
virtual uint64_t GetHashCode(void *hasher)
PointerType GetInvalidDocumentPointer() const
Gets the JSON pointer pointed to the invalid value.
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, OutputHandler &outputHandler, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Constructor with output handler.
void StartMissingDependentProperties()
void BelowMinimum(uint64_t actual, const SValue &expected, bool exclusive)
void NotOneOf(ISchemaValidator **subvalidators, SizeType count)
const ValueType & GetError() const
void TooManyProperties(SizeType actualCount, SizeType expectedCount)
GenericValue< EncodingType, StateAllocator > ValueType
void EndDisallowedType(const typename SchemaType::ValueType &actualType)
virtual void DestroySchemaValidator(ISchemaValidator *validator)
bool RawNumber(const Ch *str, SizeType length, bool copy)
void NotMultipleOf(double actual, const SValue &expected)
void DoesNotMatch(const Ch *str, SizeType length)
void TooFewItems(SizeType actualCount, SizeType expectedCount)
void EndMissingDependentProperties(const SValue &sourceName)
void BelowMinimum(double actual, const SValue &expected, bool exclusive)
Represents an in-memory output stream.
const Ch * GetString() const
size_t GetSize() const
Get the size of string in bytes in the string buffer.
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
SchemaDocumentType::Ch Ch
virtual ~IGenericRemoteSchemaDocumentProvider()
virtual const SchemaDocumentType * GetRemoteDocument(const Ch *uri, SizeType length)=0
A helper class for parsing with validation.
const PointerType & GetInvalidDocumentPointer() const
SchemaDocumentType::PointerType PointerType
const PointerType & GetInvalidSchemaPointer() const
bool operator()(Handler &handler)
GenericValue< SourceEncoding, StackAllocator > ValueType
const Ch * GetInvalidSchemaKeyword() const
const ParseResult & GetParseResult() const
SchemaValidatingReader(InputStream &is, const SchemaDocumentType &sd)
Constructor.
const ValueType & GetError() const
Regular expression engine with subset of ECMAscript grammar.
bool Key(const Ch *str, SizeType len, bool copy)
bool EndObject(SizeType memberCount)
Hasher(Allocator *allocator=0, size_t stackCapacity=kDefaultSize)
bool String(const Ch *str, SizeType len, bool)
uint64_t GetHashCode() const
bool EndArray(SizeType elementCount)
bool RawNumber(const Ch *str, SizeType len, bool)
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()
virtual bool IsValid() const =0
virtual ~ISchemaValidator()
virtual void EndMissingDependentProperties(const SValue &sourceName)=0
virtual void DisallowedItem(SizeType index)=0
virtual void NotMultipleOf(int64_t actual, const SValue &expected)=0
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
SchemaType::SValue SValue
virtual void NotAllOf(ISchemaValidator **subvalidators, SizeType count)=0
virtual void AddDependencySchemaError(const SValue &souceName, ISchemaValidator *subvalidator)=0
virtual void Disallowed()=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()
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 DisallowedValue()=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
bool Int64(Context &context, int64_t i) const
bool StartArray(Context &context) const
bool StartObject(Context &context) const
IValidationErrorHandler< Schema > ErrorHandler
SchemaDocumentType::PointerType PointerType
bool Int(Context &context, int i) const
bool Uint64(Context &context, uint64_t u) const
SchemaDocumentType::ValueType ValueType
Schema< SchemaDocumentType > SchemaType
Schema(SchemaDocumentType *schemaDocument, const PointerType &p, const ValueType &value, const ValueType &document, AllocatorType *allocator)
ValueType::EncodingType EncodingType
GenericValue< EncodingType, AllocatorType > SValue
bool EndObject(Context &context, SizeType memberCount) const
SchemaValidationContext< SchemaDocumentType > Context
bool EndArray(Context &context, SizeType elementCount) const
bool Double(Context &context, double d) const
SchemaDocumentType::AllocatorType AllocatorType
const PointerType & GetPointer() const
bool String(Context &context, const Ch *str, SizeType length, bool) const
bool Bool(Context &context, bool) const
bool Uint(Context &context, unsigned u) const
bool Key(Context &context, const Ch *str, SizeType len, bool) const
bool Null(Context &context) const
const SValue & GetURI() const
bool BeginValue(Context &context) const
RAPIDJSON_FORCEINLINE bool EndValue(Context &context) const
A type-unsafe stack for storing different types of data.
Concept for allocating, resizing and freeing memory block.
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
#define RAPIDJSON_ASSERT(x)
Assertion.
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
bip::allocator< T, pinnable_mapped_file::segment_manager > allocator
char * u64toa(uint64_t value, char *buffer)
bool CountStringCodePoint(const typename Encoding::Ch *s, SizeType length, SizeType *outCount)
Returns number of code points in a encoded string.
char * u32toa(uint32_t value, char *buffer)
const GenericPointer< typename T::ValueType > & pointer
const CharType(& source)[N]
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
#define RAPIDJSON_DELETE(x)
! customization point for global delete
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
GenericSchemaValidator< SchemaDocument > SchemaValidator
#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)
#define RAPIDJSON_SCHEMA_VERBOSE
GenericSchemaDocument< Value > SchemaDocument
GenericSchemaDocument using Value type.
#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2)
#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)
#define RAPIDJSON_STRING_(name,...)
#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)
#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)
IGenericRemoteSchemaDocumentProvider< SchemaDocument > IRemoteSchemaDocumentProvider
IGenericRemoteSchemaDocumentProvider using SchemaDocument.
unsigned __int64 uint64_t
Default implementation of Handler.
Reference to a constant string (not taking a copy)
Result of parsing (wraps ParseErrorCode)
const SchemaType ** patternPropertiesSchemas
IValidationErrorHandler< SchemaType > ErrorHandlerType
ISchemaValidator ** validators
SizeType arrayElementIndex
SizeType patternPropertiesValidatorCount
const SchemaType * valueSchema
@ kPatternValidatorWithProperty
@ kPatternValidatorWithAdditionalProperty
void * arrayElementHashCodes
ISchemaValidator ** patternPropertiesValidators
SizeType patternPropertiesSchemaCount
SchemaType::ValueType ValueType
const Ch * invalidKeyword
Schema< SchemaDocumentType > SchemaType
~SchemaValidationContext()
PatternValidatorType valuePatternValidatorType
SchemaValidationContext(SchemaValidatorFactoryType &f, ErrorHandlerType &eh, const SchemaType *s)
ErrorHandlerType & error_handler
PatternValidatorType objectPatternValidatorType
SchemaValidatorFactoryType & factory
ISchemaStateFactory< SchemaType > SchemaValidatorFactoryType
const SchemaType * schema
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
void not_(const Operand &op)
memset(pInfo->slotDescription, ' ', 64)
memcpy((char *) pInfo->slotDescription, s, l)