19 #ifndef RAPIDJSON_SCHEMA_H_ 20 #define RAPIDJSON_SCHEMA_H_ 27 #if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX) 28 #define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1 30 #define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0 33 #if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && \ 34 defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && \ 35 (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)) 36 #define RAPIDJSON_SCHEMA_USE_STDREGEX 1 38 #define RAPIDJSON_SCHEMA_USE_STDREGEX 0 41 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 43 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 47 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX 48 #define RAPIDJSON_SCHEMA_HAS_REGEX 1 50 #define RAPIDJSON_SCHEMA_HAS_REGEX 0 53 #ifndef RAPIDJSON_SCHEMA_VERBOSE 54 #define RAPIDJSON_SCHEMA_VERBOSE 0 57 #if RAPIDJSON_SCHEMA_VERBOSE 64 RAPIDJSON_DIAG_OFF(effc++)
68 RAPIDJSON_DIAG_OFF(weak - vtables)
69 RAPIDJSON_DIAG_OFF(exit - time - destructors)
70 RAPIDJSON_DIAG_OFF(c++ 98 - compat - pedantic)
71 RAPIDJSON_DIAG_OFF(variadic - macros)
72 #elif defined(_MSC_VER) 73 RAPIDJSON_DIAG_OFF(4512)
81 #if RAPIDJSON_SCHEMA_VERBOSE 85 inline void PrintInvalidKeyword(
const char *keyword) {
86 printf(
"Fail keyword: %s\n", keyword);
89 inline void PrintInvalidKeyword(
const wchar_t *keyword) {
90 wprintf(L
"Fail keyword: %ls\n", keyword);
93 inline void PrintInvalidDocument(
const char *document) {
94 printf(
"Fail document: %s\n\n", document);
97 inline void PrintInvalidDocument(
const wchar_t *document) {
98 wprintf(L
"Fail document: %ls\n\n", document);
101 inline void PrintValidatorPointers(
unsigned depth,
const char *
s,
103 printf(
"S: %*s%s\nD: %*s%s\n\n", depth * 4,
" ", s, depth * 4,
" ", d);
106 inline void PrintValidatorPointers(
unsigned depth,
const wchar_t *s,
108 wprintf(L
"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L
" ", s, depth * 4, L
" ",
114 #endif // RAPIDJSON_SCHEMA_VERBOSE 119 #if RAPIDJSON_SCHEMA_VERBOSE 120 #define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) \ 121 internal::PrintInvalidKeyword(keyword) 123 #define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) 126 #define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword) \ 127 RAPIDJSON_MULTILINEMACRO_BEGIN \ 128 context.invalidKeyword = keyword.GetString(); \ 129 RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString()); \ 131 RAPIDJSON_MULTILINEMACRO_END 136 template <
typename ValueType,
typename Allocator>
141 template <
typename SchemaDocumentType>
150 virtual bool IsValid()
const = 0;
156 template <
typename SchemaType>
162 virtual void *CreateHasher() = 0;
163 virtual uint64_t GetHashCode(
void *hasher) = 0;
164 virtual void DestroryHasher(
void *hasher) = 0;
165 virtual void *MallocState(
size_t size) = 0;
166 virtual void FreeState(
void *p) = 0;
172 template <
typename SchemaType>
175 typedef typename SchemaType::Ch
Ch;
176 typedef typename SchemaType::SValue
SValue;
180 virtual void NotMultipleOf(
int64_t actual,
const SValue &expected) = 0;
181 virtual void NotMultipleOf(
uint64_t actual,
const SValue &expected) = 0;
182 virtual void NotMultipleOf(
double actual,
const SValue &expected) = 0;
183 virtual void AboveMaximum(
int64_t actual,
const SValue &expected,
185 virtual void AboveMaximum(
uint64_t actual,
const SValue &expected,
187 virtual void AboveMaximum(
double actual,
const SValue &expected,
189 virtual void BelowMinimum(
int64_t actual,
const SValue &expected,
191 virtual void BelowMinimum(
uint64_t actual,
const SValue &expected,
193 virtual void BelowMinimum(
double actual,
const SValue &expected,
197 virtual void TooShort(
const Ch *str,
SizeType length,
SizeType expected) = 0;
198 virtual void DoesNotMatch(
const Ch *str,
SizeType length) = 0;
200 virtual void DisallowedItem(
SizeType index) = 0;
202 virtual void TooManyItems(
SizeType actualCount,
SizeType expectedCount) = 0;
205 virtual void TooManyProperties(
SizeType actualCount,
207 virtual void TooFewProperties(
SizeType actualCount,
209 virtual void StartMissingProperties() = 0;
210 virtual void AddMissingProperty(
const SValue &name) = 0;
211 virtual bool EndMissingProperties() = 0;
214 virtual void DisallowedProperty(
const Ch *name,
SizeType length) = 0;
216 virtual void StartDependencyErrors() = 0;
217 virtual void StartMissingDependentProperties() = 0;
218 virtual void AddMissingDependentProperty(
const SValue &targetName) = 0;
219 virtual void EndMissingDependentProperties(
const SValue &sourceName) = 0;
220 virtual void AddDependencySchemaError(
const SValue &souceName,
222 virtual bool EndDependencyErrors() = 0;
224 virtual void DisallowedValue() = 0;
225 virtual void StartDisallowedType() = 0;
226 virtual void AddExpectedType(
227 const typename SchemaType::ValueType &expectedType) = 0;
228 virtual void EndDisallowedType(
229 const typename SchemaType::ValueType &actualType) = 0;
233 virtual void Disallowed() = 0;
240 template <
typename Encoding,
typename Allocator>
243 typedef typename Encoding::Ch
Ch;
245 Hasher(Allocator *allocator = 0,
size_t stackCapacity = kDefaultSize)
246 : stack_(allocator, stackCapacity) {}
253 n.
d =
static_cast<double>(i);
254 return WriteNumber(n);
259 n.
d =
static_cast<double>(u);
260 return WriteNumber(n);
265 n.
d =
static_cast<double>(i);
266 return WriteNumber(n);
271 n.
d =
static_cast<double>(u);
272 return WriteNumber(n);
281 return WriteNumber(n);
296 return String(str, len, copy);
300 uint64_t *kv = stack_.template Pop<uint64_t>(memberCount * 2);
301 for (
SizeType i = 0; i < memberCount; i++)
304 *stack_.template Push<uint64_t>() = h;
311 uint64_t *e = stack_.template Pop<uint64_t>(elementCount);
312 for (
SizeType i = 0; i < elementCount; i++)
314 *stack_.template Push<uint64_t>() = h;
322 return *stack_.template Top<uint64_t>();
326 static const size_t kDefaultSize = 256;
344 const unsigned char *
d =
static_cast<const unsigned char *
>(data);
345 for (
size_t i = 0; i < len; i++) h = Hash(h, d[i]);
346 *stack_.template Push<uint64_t>() = h;
363 template <
typename SchemaDocumentType>
369 typedef typename ValueType::Ch
Ch;
374 kPatternValidatorWithAdditionalProperty
385 arrayElementHashCodes(),
388 patternPropertiesValidators(),
389 patternPropertiesValidatorCount(),
390 patternPropertiesSchemas(),
391 patternPropertiesSchemaCount(),
392 valuePatternValidatorType(kPatternValidatorOnly),
395 valueUniqueness(false),
396 arrayUniqueness(false) {}
399 if (hasher) factory.DestroryHasher(hasher);
401 for (
SizeType i = 0; i < validatorCount; i++)
402 factory.DestroySchemaValidator(validators[i]);
403 factory.FreeState(validators);
405 if (patternPropertiesValidators) {
406 for (
SizeType i = 0; i < patternPropertiesValidatorCount; i++)
407 factory.DestroySchemaValidator(patternPropertiesValidators[i]);
408 factory.FreeState(patternPropertiesValidators);
410 if (patternPropertiesSchemas) factory.FreeState(patternPropertiesSchemas);
411 if (propertyExist) factory.FreeState(propertyExist);
439 template <
typename SchemaDocumentType>
442 typedef typename SchemaDocumentType::ValueType
ValueType;
446 typedef typename EncodingType::Ch
Ch;
453 Schema(SchemaDocumentType *schemaDocument,
const PointerType &p,
454 const ValueType &
value,
const ValueType &document,
455 AllocatorType *allocator)
458 pointer_(p, allocator),
463 type_((1 << kTotalSchemaType) - 1),
465 notValidatorIndex_(),
467 additionalPropertiesSchema_(),
468 patternProperties_(),
469 patternPropertyCount_(),
473 additionalProperties_(true),
476 hasSchemaDependencies_(),
477 additionalItemsSchema_(),
483 additionalItems_(true),
488 exclusiveMinimum_(false),
489 exclusiveMaximum_(false),
490 defaultValueLength_(0) {
491 typedef typename SchemaDocumentType::ValueType
ValueType;
492 typedef typename ValueType::ConstValueIterator ConstValueIterator;
493 typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
495 if (!value.IsObject())
return;
497 if (
const ValueType *v = GetMember(value, GetTypeString())) {
501 else if (v->IsArray())
502 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
506 if (
const ValueType *v = GetMember(value, GetEnumString()))
507 if (v->IsArray() && v->Size() > 0) {
510 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) {
512 char buffer[256u + 24];
514 EnumHasherType h(&hasherAllocator, 256);
516 enum_[enumCount_++] = h.GetHashCode();
520 if (schemaDocument) {
521 AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(),
523 AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(),
525 AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(),
529 if (
const ValueType *v = GetMember(value, GetNotString())) {
530 schemaDocument->CreateSchema(¬_, p.Append(GetNotString(),
allocator_),
532 notValidatorIndex_ = validatorCount_;
538 const ValueType *properties = GetMember(value, GetPropertiesString());
539 const ValueType *required = GetMember(value, GetRequiredString());
540 const ValueType *dependencies = GetMember(value, GetDependenciesString());
545 if (properties && properties->IsObject())
546 for (ConstMemberIterator itr = properties->MemberBegin();
547 itr != properties->MemberEnd(); ++itr)
548 AddUniqueElement(allProperties, itr->name);
550 if (required && required->IsArray())
551 for (ConstValueIterator itr = required->Begin(); itr != required->End();
553 if (itr->IsString()) AddUniqueElement(allProperties, *itr);
555 if (dependencies && dependencies->IsObject())
556 for (ConstMemberIterator itr = dependencies->MemberBegin();
557 itr != dependencies->MemberEnd(); ++itr) {
558 AddUniqueElement(allProperties, itr->name);
559 if (itr->value.IsArray())
560 for (ConstValueIterator i = itr->value.Begin();
561 i != itr->value.End(); ++i)
562 if (i->IsString()) AddUniqueElement(allProperties, *i);
565 if (allProperties.Size() > 0) {
566 propertyCount_ = allProperties.Size();
567 properties_ =
static_cast<Property *
>(
569 for (
SizeType i = 0; i < propertyCount_; i++) {
571 properties_[i].
name = allProperties[i];
577 if (properties && properties->IsObject()) {
578 PointerType q = p.Append(GetPropertiesString(),
allocator_);
579 for (ConstMemberIterator itr = properties->MemberBegin();
580 itr != properties->MemberEnd(); ++itr) {
582 if (FindPropertyIndex(itr->name, &index))
583 schemaDocument->CreateSchema(&properties_[index].schema,
585 itr->value, document);
589 if (
const ValueType *v = GetMember(value, GetPatternPropertiesString())) {
590 PointerType q = p.Append(GetPatternPropertiesString(),
allocator_);
593 patternPropertyCount_ = 0;
595 for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd();
598 patternProperties_[patternPropertyCount_].
pattern =
599 CreatePattern(itr->name);
600 schemaDocument->CreateSchema(
601 &patternProperties_[patternPropertyCount_].schema,
602 q.Append(itr->name,
allocator_), itr->value, document);
603 patternPropertyCount_++;
607 if (required && required->IsArray())
608 for (ConstValueIterator itr = required->Begin(); itr != required->End();
610 if (itr->IsString()) {
612 if (FindPropertyIndex(*itr, &index)) {
613 properties_[index].required =
true;
618 if (dependencies && dependencies->IsObject()) {
619 PointerType q = p.Append(GetDependenciesString(),
allocator_);
620 hasDependencies_ =
true;
621 for (ConstMemberIterator itr = dependencies->MemberBegin();
622 itr != dependencies->MemberEnd(); ++itr) {
624 if (FindPropertyIndex(itr->name, &sourceIndex)) {
625 if (itr->value.IsArray()) {
626 properties_[sourceIndex].dependencies =
static_cast<bool *
>(
627 allocator_->Malloc(
sizeof(
bool) * propertyCount_));
628 std::memset(properties_[sourceIndex].dependencies, 0,
629 sizeof(
bool) * propertyCount_);
630 for (ConstValueIterator targetItr = itr->value.Begin();
631 targetItr != itr->value.End(); ++targetItr) {
633 if (FindPropertyIndex(*targetItr, &targetIndex))
634 properties_[sourceIndex].dependencies[targetIndex] =
true;
636 }
else if (itr->value.IsObject()) {
637 hasSchemaDependencies_ =
true;
638 schemaDocument->CreateSchema(
639 &properties_[sourceIndex].dependenciesSchema,
640 q.Append(itr->name,
allocator_), itr->value, document);
641 properties_[sourceIndex].dependenciesValidatorIndex =
649 if (
const ValueType *v =
650 GetMember(value, GetAdditionalPropertiesString())) {
652 additionalProperties_ = v->GetBool();
653 else if (v->IsObject())
654 schemaDocument->CreateSchema(
655 &additionalPropertiesSchema_,
656 p.Append(GetAdditionalPropertiesString(),
allocator_), *v,
660 AssignIfExist(minProperties_, value, GetMinPropertiesString());
661 AssignIfExist(maxProperties_, value, GetMaxPropertiesString());
664 if (
const ValueType *v = GetMember(value, GetItemsString())) {
665 PointerType q = p.Append(GetItemsString(),
allocator_);
667 schemaDocument->CreateSchema(&itemsList_, q, *v, document);
668 else if (v->IsArray()) {
669 itemsTuple_ =
static_cast<const Schema **
>(
672 for (ConstValueIterator itr = v->Begin(); itr != v->End();
674 schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++],
680 AssignIfExist(minItems_, value, GetMinItemsString());
681 AssignIfExist(maxItems_, value, GetMaxItemsString());
683 if (
const ValueType *v = GetMember(value, GetAdditionalItemsString())) {
685 additionalItems_ = v->GetBool();
686 else if (v->IsObject())
687 schemaDocument->CreateSchema(
688 &additionalItemsSchema_,
689 p.Append(GetAdditionalItemsString(),
allocator_), *v, document);
692 AssignIfExist(uniqueItems_, value, GetUniqueItemsString());
695 AssignIfExist(minLength_, value, GetMinLengthString());
696 AssignIfExist(maxLength_, value, GetMaxLengthString());
698 if (
const ValueType *v = GetMember(value, GetPatternString()))
699 pattern_ = CreatePattern(*v);
702 if (
const ValueType *v = GetMember(value, GetMinimumString()))
703 if (v->IsNumber()) minimum_.CopyFrom(*v, *
allocator_);
705 if (
const ValueType *v = GetMember(value, GetMaximumString()))
706 if (v->IsNumber()) maximum_.CopyFrom(*v, *
allocator_);
708 AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString());
709 AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString());
711 if (
const ValueType *v = GetMember(value, GetMultipleOfString()))
712 if (v->IsNumber() && v->GetDouble() > 0.0)
716 if (
const ValueType *v = GetMember(value, GetDefaultValueString()))
717 if (v->IsString()) defaultValueLength_ = v->GetStringLength();
721 AllocatorType::Free(enum_);
724 AllocatorType::Free(properties_);
726 if (patternProperties_) {
727 for (
SizeType i = 0; i < patternPropertyCount_; i++)
729 AllocatorType::Free(patternProperties_);
731 AllocatorType::Free(itemsTuple_);
732 #if RAPIDJSON_SCHEMA_HAS_REGEX 734 pattern_->~RegexType();
735 AllocatorType::Free(pattern_);
750 else if (itemsTuple_) {
753 else if (additionalItemsSchema_)
755 else if (additionalItems_)
769 RAPIDJSON_FORCEINLINE
bool EndValue(Context &context)
const {
771 bool otherValid =
false;
776 bool patternValid =
true;
777 for (
SizeType i = 0; i < count; i++)
779 patternValid =
false;
784 Context::kPatternValidatorOnly) {
791 Context::kPatternValidatorWithProperty) {
792 if (!patternValid || !otherValid) {
797 }
else if (!patternValid &&
807 for (
SizeType i = 0; i < enumCount_; i++)
808 if (enum_[i] == h)
goto foundEnum;
815 for (
SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++)
822 if (anyOf_.schemas) {
823 for (
SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)
831 if (oneOf_.schemas) {
832 bool oneValid =
false;
833 for (
SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++)
857 bool Null(Context &context)
const {
858 if (!(type_ & (1 << kNullSchemaType))) {
859 DisallowedType(context, GetNullString());
862 return CreateParallelValidator(context);
865 bool Bool(Context &context,
bool)
const {
866 if (!(type_ & (1 << kBooleanSchemaType))) {
867 DisallowedType(context, GetBooleanString());
870 return CreateParallelValidator(context);
873 bool Int(Context &context,
int i)
const {
874 if (!CheckInt(context, i))
return false;
875 return CreateParallelValidator(context);
878 bool Uint(Context &context,
unsigned u)
const {
879 if (!CheckUint(context, u))
return false;
880 return CreateParallelValidator(context);
884 if (!CheckInt(context, i))
return false;
885 return CreateParallelValidator(context);
889 if (!CheckUint(context, u))
return false;
890 return CreateParallelValidator(context);
893 bool Double(Context &context,
double d)
const {
894 if (!(type_ & (1 << kNumberSchemaType))) {
895 DisallowedType(context, GetNumberString());
899 if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d))
return false;
901 if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d))
return false;
903 if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d))
906 return CreateParallelValidator(context);
910 if (!(type_ & (1 << kStringSchemaType))) {
911 DisallowedType(context, GetStringString());
915 if (minLength_ != 0 || maxLength_ !=
SizeType(~0)) {
917 if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {
918 if (count < minLength_) {
922 if (count > maxLength_) {
929 if (pattern_ && !IsPatternMatch(pattern_, str, length)) {
934 return CreateParallelValidator(context);
938 if (!(type_ & (1 << kObjectSchemaType))) {
939 DisallowedType(context, GetObjectString());
943 if (hasDependencies_ || hasRequired_) {
946 std::memset(context.
propertyExist, 0,
sizeof(
bool) * propertyCount_);
949 if (patternProperties_) {
951 patternPropertyCount_ + 1;
956 sizeof(SchemaType *) * count);
959 return CreateParallelValidator(context);
962 bool Key(Context &context,
const Ch *str,
SizeType len,
bool)
const {
963 if (patternProperties_) {
965 for (
SizeType i = 0; i < patternPropertyCount_; i++)
966 if (patternProperties_[i].pattern &&
967 IsPatternMatch(patternProperties_[i].pattern, str, len)) {
970 patternProperties_[i].schema;
976 if (FindPropertyIndex(
ValueType(str, len).Move(), &index)) {
980 properties_[index].schema;
983 Context::kPatternValidatorWithProperty;
992 if (additionalPropertiesSchema_) {
993 if (additionalPropertiesSchema_ &&
997 additionalPropertiesSchema_;
1000 Context::kPatternValidatorWithAdditionalProperty;
1002 context.
valueSchema = additionalPropertiesSchema_;
1004 }
else if (additionalProperties_) {
1021 for (
SizeType index = 0; index < propertyCount_; index++)
1022 if (properties_[index].required && !context.
propertyExist[index])
1023 if (properties_[index].schema->defaultValueLength_ == 0)
1029 if (memberCount < minProperties_) {
1034 if (memberCount > maxProperties_) {
1039 if (hasDependencies_) {
1041 for (
SizeType sourceIndex = 0; sourceIndex < propertyCount_;
1047 for (
SizeType targetIndex = 0; targetIndex < propertyCount_;
1052 properties_[targetIndex].name);
1057 if (!dependenciesValidator->
IsValid())
1059 source.
name, dependenciesValidator);
1071 if (!(type_ & (1 << kArraySchemaType))) {
1072 DisallowedType(context, GetArrayString());
1079 return CreateParallelValidator(context);
1085 if (elementCount < minItems_) {
1090 if (elementCount > maxItems_) {
1099 #define RAPIDJSON_STRING_(name, ...) \ 1100 static const ValueType &Get##name##String() { \ 1101 static const Ch s[] = {__VA_ARGS__, '\0'}; \ 1102 static const ValueType v( \ 1103 s, static_cast<SizeType>(sizeof(s) / sizeof(Ch) - 1)); \ 1120 RAPIDJSON_STRING_(Properties,
'p',
'r',
'o',
'p',
'e',
'r',
't',
'i',
'e',
1123 RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c',
1126 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
1128 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e',
1130 RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r',
1132 RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r',
1138 'a', 'l', 'I', 't', 'e', 'm', 's')
1139 RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e',
1147 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm')
1149 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm')
1150 RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O',
1154 #undef RAPIDJSON_STRING_ 1157 enum SchemaValueType {
1168 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1170 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 1171 typedef std::basic_regex<Ch> RegexType;
1173 typedef char RegexType;
1184 template <
typename V1,
typename V2>
1186 for (
typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
1187 if (*itr == v)
return;
1188 V1 c(v, *allocator_);
1189 a.PushBack(c, *allocator_);
1193 const ValueType &name) {
1194 typename ValueType::ConstMemberIterator itr = value.FindMember(name);
1195 return itr != value.MemberEnd() ? &(itr->value) : 0;
1199 const ValueType &name) {
1200 if (
const ValueType *v = GetMember(value, name))
1201 if (v->IsBool()) out = v->GetBool();
1205 const ValueType &name) {
1206 if (
const ValueType *v = GetMember(value, name))
1207 if (v->IsUint64() && v->GetUint64() <=
SizeType(~0))
1208 out = static_cast<SizeType>(v->GetUint64());
1212 const PointerType &p,
const ValueType &
value,
1213 const ValueType &name,
const ValueType &document) {
1214 if (
const ValueType *v = GetMember(value, name)) {
1215 if (v->IsArray() && v->Size() > 0) {
1216 PointerType q = p.Append(name, allocator_);
1217 out.
count = v->Size();
1219 allocator_->Malloc(out.
count *
sizeof(
const Schema *)));
1222 schemaDocument.CreateSchema(&out.
schemas[i], q.Append(i, allocator_),
1224 out.
begin = validatorCount_;
1225 validatorCount_ += out.
count;
1230 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1231 template <
typename ValueType>
1233 if (value.IsString()) {
1234 RegexType *r =
new (allocator_->Malloc(
sizeof(RegexType)))
1235 RegexType(value.GetString(), allocator_);
1236 if (!r->IsValid()) {
1238 AllocatorType::Free(r);
1251 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 1252 template <
typename ValueType>
1253 RegexType *CreatePattern(
const ValueType &
value) {
1254 if (value.IsString()) {
1256 static_cast<RegexType *
>(allocator_->Malloc(
sizeof(RegexType)));
1259 RegexType(value.GetString(), std::size_t(value.GetStringLength()),
1260 std::regex_constants::ECMAScript);
1261 }
catch (
const std::regex_error &) {
1262 AllocatorType::Free(r);
1268 static bool IsPatternMatch(
const RegexType *pattern,
const Ch *str,
1270 std::match_results<const Ch *> r;
1271 return std::regex_search(str, str + length, r, *pattern);
1274 template <
typename ValueType>
1275 RegexType *CreatePattern(
const ValueType &) {
1279 static bool IsPatternMatch(
const RegexType *,
const Ch *,
SizeType) {
1282 #endif // RAPIDJSON_SCHEMA_USE_STDREGEX 1285 if (type == GetNullString())
1286 type_ |= 1 << kNullSchemaType;
1287 else if (type == GetBooleanString())
1288 type_ |= 1 << kBooleanSchemaType;
1289 else if (type == GetObjectString())
1290 type_ |= 1 << kObjectSchemaType;
1291 else if (type == GetArrayString())
1292 type_ |= 1 << kArraySchemaType;
1293 else if (type == GetStringString())
1294 type_ |= 1 << kStringSchemaType;
1295 else if (type == GetIntegerString())
1296 type_ |= 1 << kIntegerSchemaType;
1297 else if (type == GetNumberString())
1298 type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
1305 if (validatorCount_) {
1312 if (allOf_.schemas) CreateSchemaValidators(context, allOf_);
1314 if (anyOf_.schemas) CreateSchemaValidators(context, anyOf_);
1316 if (oneOf_.schemas) CreateSchemaValidators(context, oneOf_);
1322 if (hasSchemaDependencies_) {
1323 for (
SizeType i = 0; i < propertyCount_; i++)
1324 if (properties_[i].dependenciesSchema)
1325 context.
validators[properties_[i].dependenciesValidatorIndex] =
1327 *properties_[i].dependenciesSchema);
1343 SizeType len = name.GetStringLength();
1344 const Ch *str = name.GetString();
1345 for (
SizeType index = 0; index < propertyCount_; index++)
1346 if (properties_[index].name.GetStringLength() == len &&
1347 (std::memcmp(properties_[index].name.GetString(), str,
1348 sizeof(Ch) * len) == 0)) {
1356 if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) {
1357 DisallowedType(context, GetIntegerString());
1361 if (!minimum_.IsNull()) {
1362 if (minimum_.IsInt64()) {
1363 if (exclusiveMinimum_ ? i <= minimum_.GetInt64()
1364 : i < minimum_.GetInt64()) {
1368 }
else if (minimum_.IsUint64()) {
1371 GetMinimumString());
1372 }
else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1376 if (!maximum_.IsNull()) {
1377 if (maximum_.IsInt64()) {
1378 if (exclusiveMaximum_ ? i >= maximum_.GetInt64()
1379 : i > maximum_.GetInt64()) {
1383 }
else if (maximum_.IsUint64()) {
1386 else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1390 if (!multipleOf_.IsNull()) {
1391 if (multipleOf_.IsUint64()) {
1392 if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() !=
1397 }
else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1405 if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) {
1406 DisallowedType(context, GetIntegerString());
1410 if (!minimum_.IsNull()) {
1411 if (minimum_.IsUint64()) {
1412 if (exclusiveMinimum_ ? i <= minimum_.GetUint64()
1413 : i < minimum_.GetUint64()) {
1417 }
else if (minimum_.IsInt64())
1419 else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1423 if (!maximum_.IsNull()) {
1424 if (maximum_.IsUint64()) {
1425 if (exclusiveMaximum_ ? i >= maximum_.GetUint64()
1426 : i > maximum_.GetUint64()) {
1430 }
else if (maximum_.IsInt64()) {
1433 GetMaximumString());
1434 }
else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1438 if (!multipleOf_.IsNull()) {
1439 if (multipleOf_.IsUint64()) {
1440 if (i % multipleOf_.GetUint64() != 0) {
1444 }
else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1452 if (exclusiveMinimum_ ? d <= minimum_.GetDouble()
1453 : d < minimum_.GetDouble()) {
1461 if (exclusiveMaximum_ ? d >= maximum_.GetDouble()
1462 : d > maximum_.GetDouble()) {
1470 double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());
1471 double q = std::floor(a / b);
1472 double r = a - q * b;
1484 if (type_ & (1 << kNullSchemaType)) eh.
AddExpectedType(GetNullString());
1485 if (type_ & (1 << kBooleanSchemaType))
1487 if (type_ & (1 << kObjectSchemaType)) eh.
AddExpectedType(GetObjectString());
1488 if (type_ & (1 << kArraySchemaType)) eh.
AddExpectedType(GetArrayString());
1489 if (type_ & (1 << kStringSchemaType)) eh.
AddExpectedType(GetStringString());
1491 if (type_ & (1 << kNumberSchemaType))
1493 else if (type_ & (1 << kIntegerSchemaType))
1502 dependenciesSchema(),
1503 dependenciesValidatorIndex(),
1519 pattern->~RegexType();
1520 AllocatorType::Free(pattern);
1575 template <
typename Stack,
typename Ch>
1579 *documentStack.template Push<Ch>() =
'/';
1582 static_cast<size_t>((
sizeof(
SizeType) == 4 ?
u32toa(index, buffer)
1583 :
u64toa(index, buffer)) -
1585 for (
size_t i = 0; i < length; i++)
1586 *documentStack.template Push<Ch>() =
static_cast<Ch
>(buffer[i]);
1591 template <
typename Stack>
1596 char *buffer = documentStack.template Push<char>(1 + 10);
1599 documentStack.template Pop<char>(
1600 static_cast<size_t>(10 - (end - buffer)));
1602 char *buffer = documentStack.template Push<char>(1 + 20);
1605 documentStack.template Pop<char>(
1606 static_cast<size_t>(20 - (end - buffer)));
1616 template <
typename SchemaDocumentType>
1619 typedef typename SchemaDocumentType::Ch
Ch;
1622 virtual const SchemaDocumentType *GetRemoteDocument(
const Ch *uri,
1639 template <
typename ValueT,
typename Allocator = CrtAllocator>
1647 typedef typename EncodingType::Ch
Ch;
1652 template <
typename,
typename,
typename>
1667 const ValueType &document,
const Ch *uri = 0,
SizeType uriLength = 0,
1669 Allocator *allocator = 0)
1670 : remoteProvider_(remoteProvider),
1671 allocator_(allocator),
1675 schemaMap_(allocator, kInitialSchemaMapSize),
1676 schemaRef_(allocator, kInitialSchemaRefSize) {
1677 if (!allocator_) ownAllocator_ = allocator_ =
RAPIDJSON_NEW(Allocator)();
1680 uri_.SetString(uri ? uri : noUri, uriLength, *allocator_);
1683 static_cast<SchemaType *
>(allocator_->Malloc(
sizeof(SchemaType)));
1693 while (!schemaRef_.Empty()) {
1694 SchemaRefEntry *refEntry = schemaRef_.template Pop<SchemaRefEntry>(1);
1695 if (
const SchemaType *
s = GetSchema(refEntry->
target)) {
1699 if (!GetSchema(refEntry->
source)) {
1700 new (schemaMap_.template Push<SchemaEntry>())
SchemaEntry(
1701 refEntry->
source, const_cast<SchemaType *>(
s),
false, allocator_);
1703 }
else if (refEntry->
schema)
1704 *refEntry->
schema = typeless_;
1706 refEntry->~SchemaRefEntry();
1711 schemaRef_.ShrinkToFit();
1714 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 1717 : remoteProvider_(rhs.remoteProvider_),
1718 allocator_(rhs.allocator_),
1719 ownAllocator_(rhs.ownAllocator_),
1721 typeless_(rhs.typeless_),
1722 schemaMap_(std::move(rhs.schemaMap_)),
1723 schemaRef_(std::move(rhs.schemaRef_)),
1724 uri_(std::move(rhs.uri_)) {
1725 rhs.remoteProvider_ = 0;
1727 rhs.ownAllocator_ = 0;
1734 while (!schemaMap_.Empty())
1735 schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry();
1738 typeless_->~SchemaType();
1739 Allocator::Free(typeless_);
1745 const URIType &
GetURI()
const {
return uri_; }
1758 const SchemaType **outSchema, Allocator *allocator)
1759 :
source(s, allocator), target(t, allocator), schema(outSchema) {}
1767 Allocator *allocator)
1768 :
pointer(p, allocator), schema(s), owned(o) {}
1771 schema->~SchemaType();
1772 Allocator::Free(schema);
1781 const PointerType &
pointer,
const ValueType &v,
1782 const ValueType &document) {
1783 if (schema) *schema = typeless_;
1786 const SchemaType *
s = GetSchema(pointer);
1787 if (!s) CreateSchema(schema, pointer, v, document);
1789 for (
typename ValueType::ConstMemberIterator itr = v.MemberBegin();
1790 itr != v.MemberEnd(); ++itr)
1791 CreateSchemaRecursive(0, pointer.
Append(itr->name, allocator_),
1792 itr->value, document);
1794 for (
SizeType i = 0; i < v.Size(); i++)
1795 CreateSchemaRecursive(0, pointer.
Append(i, allocator_), v[i], document);
1799 const ValueType &v,
const ValueType &document) {
1802 if (!HandleRefSchema(pointer, schema, v, document)) {
1803 SchemaType *
s =
new (allocator_->Malloc(
sizeof(SchemaType)))
1804 SchemaType(
this, pointer, v, document, allocator_);
1805 new (schemaMap_.template Push<SchemaEntry>())
1807 if (schema) *schema = s;
1813 const ValueType &v,
const ValueType &document) {
1814 static const Ch kRefString[] = {
'$',
'r',
'e',
'f',
'\0'};
1815 static const ValueType kRefValue(kRefString, 4);
1817 typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue);
1818 if (itr == v.MemberEnd())
return false;
1820 if (itr->value.IsString()) {
1821 SizeType len = itr->value.GetStringLength();
1823 const Ch *
s = itr->value.GetString();
1825 while (i < len && s[i] !=
'#')
1829 if (remoteProvider_) {
1831 remoteProvider_->GetRemoteDocument(s, i)) {
1832 PointerType
pointer(&s[i], len - i, allocator_);
1833 if (pointer.IsValid()) {
1834 if (
const SchemaType *sc = remoteDocument->GetSchema(pointer)) {
1835 if (schema) *schema = sc;
1836 new (schemaMap_.template Push<SchemaEntry>())
SchemaEntry(
1837 source, const_cast<SchemaType *>(sc),
false, allocator_);
1843 }
else if (s[i] ==
'#') {
1844 PointerType
pointer(&s[i], len - i, allocator_);
1845 if (pointer.IsValid()) {
1846 if (
const ValueType *nv = pointer.Get(document))
1847 if (HandleRefSchema(source, schema, *nv, document))
return true;
1849 new (schemaRef_.template Push<SchemaRefEntry>())
1860 for (
const SchemaEntry *target = schemaMap_.template Bottom<SchemaEntry>();
1861 target != schemaMap_.template End<SchemaEntry>(); ++target)
1862 if (pointer == target->pointer)
return target->schema;
1867 for (
const SchemaEntry *target = schemaMap_.template Bottom<SchemaEntry>();
1868 target != schemaMap_.template End<SchemaEntry>(); ++target)
1869 if (schema == target->schema)
return target->pointer;
1870 return PointerType();
1875 static const size_t kInitialSchemaMapSize = 64;
1876 static const size_t kInitialSchemaRefSize = 64;
1910 template <
typename SchemaDocumentType,
1912 typename SchemaDocumentType::SchemaType::EncodingType>,
1915 typename SchemaDocumentType::SchemaType>,
1918 typename SchemaDocumentType::SchemaType> {
1924 typedef typename EncodingType::Ch
Ch;
1937 const SchemaDocumentType &schemaDocument, StateAllocator *allocator = 0,
1938 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1939 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1940 : schemaDocument_(&schemaDocument),
1941 root_(schemaDocument.GetRoot()),
1942 stateAllocator_(allocator),
1943 ownStateAllocator_(0),
1944 schemaStack_(allocator, schemaStackCapacity),
1945 documentStack_(allocator, documentStackCapacity),
1949 missingDependents_(),
1967 const SchemaDocumentType &schemaDocument, OutputHandler &outputHandler,
1968 StateAllocator *allocator = 0,
1969 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1970 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1971 : schemaDocument_(&schemaDocument),
1972 root_(schemaDocument.GetRoot()),
1973 stateAllocator_(allocator),
1974 ownStateAllocator_(0),
1975 schemaStack_(allocator, schemaStackCapacity),
1976 documentStack_(allocator, documentStackCapacity),
1977 outputHandler_(&outputHandler),
1980 missingDependents_(),
1997 while (!schemaStack_.Empty()) PopSchema();
1998 documentStack_.Clear();
2000 currentError_.SetNull();
2001 missingDependents_.SetNull();
2015 return schemaStack_.Empty() ? PointerType() : CurrentSchema().GetPointer();
2020 return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword;
2025 if (documentStack_.Empty()) {
2026 return PointerType();
2028 return PointerType(documentStack_.template Bottom<Ch>(),
2029 documentStack_.GetSize() /
sizeof(Ch));
2034 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(),
2038 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(),
2042 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(),
2046 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(),
2048 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
2051 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(),
2053 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
2056 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(),
2058 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
2061 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(),
2063 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
2066 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(),
2068 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
2071 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(),
2073 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
2077 AddNumberError(SchemaType::GetMaxLengthString(),
2078 ValueType(str, length, GetStateAllocator()).Move(),
2079 SValue(expected).Move());
2082 AddNumberError(SchemaType::GetMinLengthString(),
2083 ValueType(str, length, GetStateAllocator()).Move(),
2084 SValue(expected).Move());
2087 currentError_.SetObject();
2088 currentError_.AddMember(GetActualString(),
2089 ValueType(str, length, GetStateAllocator()).Move(),
2090 GetStateAllocator());
2091 AddCurrentError(SchemaType::GetPatternString());
2095 currentError_.SetObject();
2096 currentError_.AddMember(GetDisallowedString(), ValueType(index).Move(),
2097 GetStateAllocator());
2098 AddCurrentError(SchemaType::GetAdditionalItemsString(),
true);
2101 AddNumberError(SchemaType::GetMinItemsString(),
2102 ValueType(actualCount).Move(), SValue(expectedCount).Move());
2105 AddNumberError(SchemaType::GetMaxItemsString(),
2106 ValueType(actualCount).Move(), SValue(expectedCount).Move());
2110 duplicates.PushBack(index1, GetStateAllocator());
2111 duplicates.PushBack(index2, GetStateAllocator());
2112 currentError_.SetObject();
2113 currentError_.AddMember(GetDuplicatesString(), duplicates,
2114 GetStateAllocator());
2115 AddCurrentError(SchemaType::GetUniqueItemsString(),
true);
2119 AddNumberError(SchemaType::GetMaxPropertiesString(),
2120 ValueType(actualCount).Move(), SValue(expectedCount).Move());
2123 AddNumberError(SchemaType::GetMinPropertiesString(),
2124 ValueType(actualCount).Move(), SValue(expectedCount).Move());
2128 currentError_.PushBack(ValueType(name, GetStateAllocator()).Move(),
2129 GetStateAllocator());
2132 if (currentError_.Empty())
return false;
2134 error.AddMember(GetMissingString(), currentError_, GetStateAllocator());
2135 currentError_ = error;
2136 AddCurrentError(SchemaType::GetRequiredString());
2140 for (
SizeType i = 0; i < count; ++i)
2142 static_cast<GenericSchemaValidator *>(subvalidators[i])->GetError());
2145 currentError_.SetObject();
2146 currentError_.AddMember(GetDisallowedString(),
2147 ValueType(name, length, GetStateAllocator()).Move(),
2148 GetStateAllocator());
2149 AddCurrentError(SchemaType::GetAdditionalPropertiesString(),
true);
2155 missingDependents_.PushBack(
2156 ValueType(targetName, GetStateAllocator()).Move(), GetStateAllocator());
2159 if (!missingDependents_.Empty())
2160 currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(),
2161 missingDependents_, GetStateAllocator());
2164 ISchemaValidator *subvalidator) {
2165 currentError_.AddMember(
2166 ValueType(sourceName, GetStateAllocator()).Move(),
2167 static_cast<GenericSchemaValidator *>(subvalidator)->GetError(),
2168 GetStateAllocator());
2171 if (currentError_.ObjectEmpty())
return false;
2173 error.AddMember(GetErrorsString(), currentError_, GetStateAllocator());
2174 currentError_ = error;
2175 AddCurrentError(SchemaType::GetDependenciesString());
2180 currentError_.SetObject();
2181 AddCurrentError(SchemaType::GetEnumString());
2185 currentError_.PushBack(ValueType(expectedType, GetStateAllocator()).Move(),
2186 GetStateAllocator());
2190 error.AddMember(GetExpectedString(), currentError_, GetStateAllocator());
2191 error.AddMember(GetActualString(),
2192 ValueType(actualType, GetStateAllocator()).Move(),
2193 GetStateAllocator());
2194 currentError_ = error;
2195 AddCurrentError(SchemaType::GetTypeString());
2198 for (
SizeType i = 0; i < count; ++i) {
2200 static_cast<GenericSchemaValidator *>(subvalidators[i])->GetError());
2204 AddErrorArray(SchemaType::GetAnyOfString(), subvalidators, count);
2207 AddErrorArray(SchemaType::GetOneOfString(), subvalidators, count);
2210 currentError_.SetObject();
2211 AddCurrentError(SchemaType::GetNotString());
2214 #define RAPIDJSON_STRING_(name, ...) \ 2215 static const StringRefType &Get##name##String() { \ 2216 static const Ch s[] = {__VA_ARGS__, '\0'}; \ 2217 static const StringRefType v( \ 2218 s, static_cast<SizeType>(sizeof(s) / sizeof(Ch) - 1)); \ 2222 RAPIDJSON_STRING_(InstanceRef,
'i',
'n',
's',
't',
'a',
'n',
'c',
'e',
'R',
2227 RAPIDJSON_STRING_(Disallowed, 'd', 'i', 's', 'a', 'l', 'l', 'o', 'w', 'e',
2231 RAPIDJSON_STRING_(Duplicates, 'd', 'u', 'p', 'l', 'i', 'c', 'a', 't', 'e',
2234 #undef RAPIDJSON_STRING_ 2236 #if RAPIDJSON_SCHEMA_VERBOSE 2237 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \ 2238 RAPIDJSON_MULTILINEMACRO_BEGIN \ 2239 *documentStack_.template Push<Ch>() = '\0'; \ 2240 documentStack_.template Pop<Ch>(1); \ 2241 internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>()); \ 2242 RAPIDJSON_MULTILINEMACRO_END 2244 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() 2247 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1) \ 2248 if (!valid_) return false; \ 2249 if (!BeginValue() || !CurrentSchema().method arg1) { \ 2250 RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_(); \ 2251 return valid_ = false; \ 2254 #define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2) \ 2255 for (Context *context = schemaStack_.template Bottom<Context>(); \ 2256 context != schemaStack_.template End<Context>(); context++) { \ 2257 if (context->hasher) \ 2258 static_cast<HasherType *>(context->hasher)->method arg2; \ 2259 if (context->validators) \ 2260 for (SizeType i_ = 0; i_ < context->validatorCount; i_++) \ 2261 static_cast<GenericSchemaValidator *>(context->validators[i_]) \ 2263 if (context->patternPropertiesValidators) \ 2264 for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; \ 2266 static_cast<GenericSchemaValidator *>( \ 2267 context->patternPropertiesValidators[i_]) \ 2271 #define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2) \ 2272 return valid_ = EndValue() && (!outputHandler_ || outputHandler_->method arg2) 2274 #define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ 2275 RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1); \ 2276 RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2); \ 2277 RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2) 2300 String, (CurrentContext(), str, length, copy), (str, length, copy));
2304 String, (CurrentContext(), str, length, copy), (str, length, copy));
2310 return valid_ = !outputHandler_ || outputHandler_->StartObject();
2314 if (!valid_)
return false;
2315 AppendToken(str, len);
2316 if (!CurrentSchema().Key(CurrentContext(), str, len, copy))
2317 return valid_ =
false;
2319 return valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy);
2323 if (!valid_)
return false;
2325 if (!CurrentSchema().EndObject(CurrentContext(), memberCount))
2326 return valid_ =
false;
2333 return valid_ = !outputHandler_ || outputHandler_->StartArray();
2337 if (!valid_)
return false;
2339 if (!CurrentSchema().EndArray(CurrentContext(), elementCount))
2340 return valid_ =
false;
2344 #undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_ 2345 #undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_ 2346 #undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ 2347 #undef RAPIDJSON_SCHEMA_HANDLE_VALUE_ 2353 documentStack_.template Bottom<char>(),
2354 documentStack_.GetSize(),
2355 #if RAPIDJSON_SCHEMA_VERBOSE 2358 &GetStateAllocator());
2365 StateAllocator::Free(v);
2369 return new (GetStateAllocator().Malloc(
sizeof(
HasherType)))
2374 return static_cast<HasherType *
>(hasher)->GetHashCode();
2380 StateAllocator::Free(h);
2384 return GetStateAllocator().Malloc(size);
2387 virtual void FreeState(
void *p) { StateAllocator::Free(p); }
2395 const SchemaDocumentType &schemaDocument,
const SchemaType &root,
2396 const char *basePath,
size_t basePathSize,
2400 StateAllocator *allocator = 0,
2401 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
2402 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
2403 : schemaDocument_(&schemaDocument),
2405 stateAllocator_(allocator),
2406 ownStateAllocator_(0),
2407 schemaStack_(allocator, schemaStackCapacity),
2408 documentStack_(allocator, documentStackCapacity),
2412 missingDependents_(),
2419 if (basePath && basePathSize)
2420 memcpy(documentStack_.template Push<char>(basePathSize), basePath,
2425 if (!stateAllocator_)
2426 stateAllocator_ = ownStateAllocator_ =
RAPIDJSON_NEW(StateAllocator)();
2427 return *stateAllocator_;
2431 if (schemaStack_.Empty())
2434 if (CurrentContext().inArray)
2436 Ch>::AppendIndexToken(documentStack_,
2438 .arrayElementIndex);
2440 if (!CurrentSchema().BeginValue(CurrentContext()))
return false;
2442 SizeType count = CurrentContext().patternPropertiesSchemaCount;
2443 const SchemaType **sa = CurrentContext().patternPropertiesSchemas;
2444 typename Context::PatternValidatorType patternValidatorType =
2445 CurrentContext().valuePatternValidatorType;
2446 bool valueUniqueness = CurrentContext().valueUniqueness;
2448 PushSchema(*CurrentContext().valueSchema);
2451 CurrentContext().objectPatternValidatorType = patternValidatorType;
2452 ISchemaValidator **&va = CurrentContext().patternPropertiesValidators;
2454 CurrentContext().patternPropertiesValidatorCount;
2455 va =
static_cast<ISchemaValidator **
>(
2456 MallocState(
sizeof(ISchemaValidator *) * count));
2457 for (
SizeType i = 0; i < count; i++)
2458 va[validatorCount++] = CreateSchemaValidator(*sa[i]);
2461 CurrentContext().arrayUniqueness = valueUniqueness;
2467 if (!CurrentSchema().EndValue(CurrentContext()))
return false;
2469 #if RAPIDJSON_SCHEMA_VERBOSE 2471 schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb);
2473 *documentStack_.template Push<Ch>() =
'\0';
2474 documentStack_.template Pop<Ch>(1);
2475 internal::PrintValidatorPointers(depth_, sb.
GetString(),
2476 documentStack_.template Bottom<Ch>());
2480 CurrentContext().arrayUniqueness
2481 ?
static_cast<HasherType *
>(CurrentContext().hasher)->GetHashCode()
2486 if (!schemaStack_.Empty()) {
2487 Context &context = CurrentContext();
2488 if (context.valueUniqueness) {
2490 static_cast<HashCodeArray *
>(context.arrayElementHashCodes);
2492 CurrentContext().arrayElementHashCodes = a =
2493 new (GetStateAllocator().Malloc(
sizeof(HashCodeArray)))
2496 itr != a->End(); ++itr)
2497 if (itr->GetUint64() == h) {
2498 DuplicateItems(static_cast<SizeType>(itr - a->Begin()), a->Size());
2500 SchemaType::GetUniqueItemsString());
2502 a->PushBack(h, GetStateAllocator());
2507 while (!documentStack_.Empty() &&
2508 *documentStack_.template Pop<Ch>(1) !=
'/')
2515 documentStack_.template Reserve<Ch>(
2518 *documentStack_.template PushUnsafe<Ch>() =
'/';
2519 for (
SizeType i = 0; i < len; i++) {
2520 if (str[i] ==
'~') {
2521 *documentStack_.template PushUnsafe<Ch>() =
'~';
2522 *documentStack_.template PushUnsafe<Ch>() =
'0';
2523 }
else if (str[i] ==
'/') {
2524 *documentStack_.template PushUnsafe<Ch>() =
'~';
2525 *documentStack_.template PushUnsafe<Ch>() =
'1';
2527 *documentStack_.template PushUnsafe<Ch>() = str[i];
2531 RAPIDJSON_FORCEINLINE
void PushSchema(
const SchemaType &schema) {
2532 new (schemaStack_.template Push<Context>()) Context(*
this, *
this, &schema);
2536 Context *c = schemaStack_.template Pop<Context>(1);
2537 if (HashCodeArray *a =
2538 static_cast<HashCodeArray *>(c->arrayElementHashCodes)) {
2539 a->~HashCodeArray();
2540 StateAllocator::Free(a);
2547 PointerType instancePointer = GetInvalidDocumentPointer();
2548 ((parent && instancePointer.GetTokenCount() > 0)
2549 ? PointerType(instancePointer.GetTokens(),
2550 instancePointer.GetTokenCount() - 1)
2552 .StringifyUriFragment(sb);
2555 GetStateAllocator());
2556 result.AddMember(GetInstanceRefString(), instanceRef, GetStateAllocator());
2558 memcpy(sb.
Push(CurrentSchema().GetURI().GetStringLength()),
2559 CurrentSchema().GetURI().GetString(),
2560 CurrentSchema().GetURI().GetStringLength() *
sizeof(Ch));
2561 GetInvalidSchemaPointer().StringifyUriFragment(sb);
2564 GetStateAllocator());
2565 result.AddMember(GetSchemaRefString(), schemaRef, GetStateAllocator());
2570 if (member == error_.MemberEnd())
2571 error_.AddMember(keyword, error, GetStateAllocator());
2573 if (member->value.IsObject()) {
2575 errors.PushBack(member->value, GetStateAllocator());
2576 member->value = errors;
2578 member->value.PushBack(error, GetStateAllocator());
2583 bool parent =
false) {
2584 AddErrorLocation(currentError_, parent);
2585 AddError(ValueType(keyword, GetStateAllocator(),
false).Move(),
2591 end = other.MemberEnd();
2593 AddError(it->name, it->value);
2598 const typename SchemaType::ValueType &keyword, ValueType &actual,
2599 const SValue &expected,
2600 const typename SchemaType::ValueType &(*exclusive)() = 0) {
2601 currentError_.SetObject();
2602 currentError_.AddMember(GetActualString(), actual, GetStateAllocator());
2603 currentError_.AddMember(GetExpectedString(),
2604 ValueType(expected, GetStateAllocator()).Move(),
2605 GetStateAllocator());
2607 currentError_.AddMember(
2608 ValueType(exclusive(), GetStateAllocator()).Move(),
true,
2609 GetStateAllocator());
2610 AddCurrentError(keyword);
2614 ISchemaValidator **subvalidators,
SizeType count) {
2616 for (
SizeType i = 0; i < count; ++i)
2618 static_cast<GenericSchemaValidator *>(subvalidators[i])->GetError(),
2619 GetStateAllocator());
2620 currentError_.SetObject();
2621 currentError_.AddMember(GetErrorsString(), errors, GetStateAllocator());
2622 AddCurrentError(keyword);
2626 return *schemaStack_.template Top<Context>()->schema;
2630 return *schemaStack_.template Top<Context>();
2633 static const size_t kDefaultSchemaStackCapacity = 1024;
2634 static const size_t kDefaultDocumentStackCapacity = 256;
2644 OutputHandler *outputHandler_;
2650 #if RAPIDJSON_SCHEMA_VERBOSE 2671 template <
unsigned parseFlags,
typename InputStream,
typename SourceEncoding,
2677 typedef typename InputStream::Ch
Ch;
2688 invalidSchemaKeyword_(),
2692 template <
typename Handler>
2694 GenericReader<SourceEncoding,
typename SchemaDocumentType::EncodingType,
2698 parseResult_ = reader.template Parse<parseFlags>(is_, validator);
2700 isValid_ = validator.
IsValid();
2702 invalidSchemaPointer_ = PointerType();
2703 invalidSchemaKeyword_ = 0;
2704 invalidDocumentPointer_ = PointerType();
2710 error_.CopyFrom(validator.
GetError(), allocator_);
2713 return parseResult_;
2719 return invalidSchemaPointer_;
2723 return invalidDocumentPointer_;
2729 const SchemaDocumentType &
sd_;
2743 #endif // RAPIDJSON_SCHEMA_H_
bool Key(Context &context, const Ch *str, SizeType len, bool) const
SchemaDocumentType::Ch Ch
virtual void AboveMaximum(int64_t actual, const SValue &expected, bool exclusive)=0
char * u64toa(uint64_t value, char *buffer)
void NotAllOf(ISchemaValidator **subvalidators, SizeType count)
Allocator * ownAllocator_
size_t GetSize() const
Get the size of string in bytes in the string buffer.
const CharType(& source)[N]
SizeType patternPropertyCount_
SizeType defaultValueLength_
IGenericRemoteSchemaDocumentProvider< GenericSchemaDocument > IRemoteSchemaDocumentProviderType
const SchemaType ** patternPropertiesSchemas
SchemaDocumentType::PointerType PointerType
bool RawNumber(const Ch *str, SizeType len, bool)
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
void CreateSchemaRecursive(const SchemaType **schema, const PointerType &pointer, const ValueType &v, const ValueType &document)
virtual void DestroySchemaValidator(ISchemaValidator *validator)
bool WriteType(Type type)
virtual bool IsValid() const =0
#define RAPIDJSON_ASSERT(x)
Assertion.
virtual void AddDependencySchemaError(const SValue &souceName, ISchemaValidator *subvalidator)=0
PointerType invalidDocumentPointer_
const Ch * invalidSchemaKeyword_
PointerType invalidSchemaPointer_
GenericValue< EncodingType, Allocator > URIType
void MergeError(ValueType &other)
AllocatorType * allocator_
virtual bool EndDependencyErrors()=0
void AddErrorLocation(ValueType &result, bool parent)
const SchemaType ** schemas
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
static bool IsPatternMatch(const RegexType *pattern, const Ch *str, SizeType)
virtual void TooFewProperties(SizeType actualCount, SizeType expectedCount)=0
Default implementation of Handler.
const SchemaType * GetSchema(const PointerType &pointer) const
static void AssignIfExist(SizeType &out, const ValueType &value, const ValueType &name)
bool operator()(Handler &handler)
const Ch * GetString() const
Schema< SchemaDocumentType > SchemaType
void AddUniqueElement(V1 &a, const V2 &v)
Schema< SchemaDocumentType > SchemaType
const SValue & GetURI() const
PatternValidatorType objectPatternValidatorType
void AddNumberError(const typename SchemaType::ValueType &keyword, ValueType &actual, const SValue &expected, const typename SchemaType::ValueType &(*exclusive)()=0)
const SchemaType * typeless_
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
SchemaValidationContext(SchemaValidatorFactoryType &f, ErrorHandlerType &eh, const SchemaType *s)
PatternProperty * patternProperties_
(Constant) member iterator for a JSON object value
virtual void FreeState(void *p)
StateAllocator * stateAllocator_
SchemaDocumentType::PointerType PointerType
SchemaDocumentType::SchemaType SchemaType
void DoesNotMatch(const Ch *str, SizeType length)
~GenericSchemaValidator()
Destructor.
const SchemaType * additionalItemsSchema_
#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2)
void AppendToken(const Ch *str, SizeType len)
s s s s m RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f') private typedef internal::GenericRegex< EncodingType, AllocatorType > RegexType
virtual void EndMissingDependentProperties(const SValue &sourceName)=0
GenericValue< EncodingType, StateAllocator > ValueType
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, const SchemaType &root, const char *basePath, size_t basePathSize, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
const ValueType & GetError() const
virtual bool EndMissingProperties()=0
Stack< Allocator > stack_
virtual ~IGenericRemoteSchemaDocumentProvider()
bool String(const Ch *str, SizeType length, bool copy)
A type-unsafe stack for storing different types of data.
void AboveMaximum(int64_t actual, const SValue &expected, bool exclusive)
SchemaValidatingReader(InputStream &is, const SchemaDocumentType &sd)
Constructor.
SchemaType::EncodingType EncodingType
bool EndArray(SizeType elementCount)
PatternValidatorType valuePatternValidatorType
internal::Stack< Allocator > schemaRef_
IValidationErrorHandler< Schema > ErrorHandler
const SchemaType * dependenciesSchema
void * arrayElementHashCodes
StateAllocator * ownStateAllocator_
ValueType & GetError()
Gets the error object.
void BelowMinimum(uint64_t actual, const SValue &expected, bool exclusive)
const SchemaType * GetTypeless() const
SizeType notValidatorIndex_
void DisallowedItem(SizeType index)
IRemoteSchemaDocumentProviderType * remoteProvider_
bool EndArray(SizeType elementCount)
bool EndObject(Context &context, SizeType memberCount) const
bool BeginValue(Context &context) const
void AddCurrentError(const typename SchemaType::ValueType &keyword, bool parent=false)
static const ValueType * GetMember(const ValueType &value, const ValueType &name)
bool Key(const Ch *str, SizeType len, bool copy)
void AddDependencySchemaError(const SValue &sourceName, ISchemaValidator *subvalidator)
Hasher(Allocator *allocator=0, size_t stackCapacity=kDefaultSize)
const SchemaType * schema
const SchemaType * valueSchema
const SchemaType * itemsList_
void NotMultipleOf(uint64_t actual, const SValue &expected)
const SchemaType ** itemsTuple_
SchemaType::ValueType ValueType
Result of parsing (wraps ParseErrorCode)
SizeType arrayElementIndex
SizeType itemsTupleCount_
internal::Stack< StateAllocator > documentStack_
bool HandleRefSchema(const PointerType &source, const SchemaType **schema, const ValueType &v, const ValueType &document)
internal::Schema< GenericSchemaDocument > SchemaType
void StartDisallowedType()
RAPIDJSON_FORCEINLINE void PopSchema()
const URIType & GetURI() const
void Reset()
Reset the internal states.
virtual void TooLong(const Ch *str, SizeType length, SizeType expected)=0
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
SchemaType::SValue SValue
#define RAPIDJSON_STRING_(name,...)
bool CreateParallelValidator(Context &context) const
SchemaType::SValue SValue
ISchemaValidator ** patternPropertiesValidators
bool WriteBuffer(Type type, const void *data, size_t len)
bool EndDependencyErrors()
GenericValue< EncodingType, AllocatorType > SValue
ISchemaValidator ** validators
virtual void DisallowedProperty(const Ch *name, SizeType length)=0
ValueType::EncodingType EncodingType
virtual void Disallowed()=0
bool EndMissingProperties()
void AssignIfExist(SchemaArray &out, SchemaDocumentType &schemaDocument, const PointerType &p, const ValueType &value, const ValueType &name, const ValueType &document)
bool CheckDoubleMultipleOf(Context &context, double d) const
SchemaValidatorFactoryType & factory
ValueType missingDependents_
virtual void NotAllOf(ISchemaValidator **subvalidators, SizeType count)=0
SizeType dependenciesValidatorIndex
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
~SchemaValidationContext()
void AddMissingDependentProperty(const SValue &targetName)
bool Uint64(Context &context, uint64_t u) const
union internal::Hasher::Number::U u
void TooShort(const Ch *str, SizeType length, SizeType expected)
virtual ISchemaValidator * CreateSchemaValidator(const SchemaType &)=0
void NoneOf(ISchemaValidator **subvalidators, SizeType count)
const SchemaType * additionalPropertiesSchema_
void NotMultipleOf(double actual, const SValue &expected)
void EndDisallowedType(const typename SchemaType::ValueType &actualType)
SchemaDocumentType::PointerType PointerType
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, OutputHandler &outputHandler, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Constructor with output handler.
virtual void NotMultipleOf(int64_t actual, const SValue &expected)=0
PointerType GetPointer(const SchemaType *schema) const
virtual void NoneOf(ISchemaValidator **subvalidators, SizeType count)=0
void DisallowedProperty(const Ch *name, SizeType length)
void DisallowedType(Context &context, const ValueType &actualType) const
virtual void StartDependencyErrors()=0
SchemaValidationContext< SchemaDocumentType > Context
SizeType patternPropertiesValidatorCount
void TooFewProperties(SizeType actualCount, SizeType expectedCount)
bool CheckUint(Context &context, uint64_t i) const
void CreateSchema(const SchemaType **schema, const PointerType &pointer, const ValueType &v, const ValueType &document)
uint64_t GetHashCode() const
IValidationErrorHandler< SchemaType > ErrorHandlerType
void AddExpectedType(const typename SchemaType::ValueType &expectedType)
const PointerType & GetInvalidSchemaPointer() const
bool Int(Context &context, int i) const
GenericStringRef< Ch > StringRefType
const SchemaDocumentType * schemaDocument_
virtual void PropertyViolations(ISchemaValidator **subvalidators, SizeType count)=0
void AddError(ValueType &keyword, ValueType &error)
bool Key(const Ch *str, SizeType len, bool copy)
internal::Hasher< EncodingType, StateAllocator > HasherType
virtual ~ISchemaValidator()
virtual void AddExpectedType(const typename SchemaType::ValueType &expectedType)=0
Context & CurrentContext()
unsigned __int64 uint64_t
bool CheckDoubleMaximum(Context &context, double d) const
const ParseResult & GetParseResult() const
virtual void * MallocState(size_t size)
void AboveMaximum(uint64_t actual, const SValue &expected, bool exclusive)
const PointerType & GetInvalidDocumentPointer() const
void CreateSchemaValidators(Context &context, const SchemaArray &schemas) const
void StartMissingDependentProperties()
PointerType GetInvalidSchemaPointer() const
Gets the JSON pointer pointed to the invalid schema.
#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)
const SchemaDocumentType & sd_
void AddErrorArray(const typename SchemaType::ValueType &keyword, ISchemaValidator **subvalidators, SizeType count)
void BelowMinimum(int64_t actual, const SValue &expected, bool exclusive)
GenericSchemaDocument< Value > SchemaDocument
GenericSchemaDocument using Value type.
void AboveMaximum(double actual, const SValue &expected, bool exclusive)
bool Double(Context &context, double d) const
#define RAPIDJSON_SCHEMA_VERBOSE
bool CheckInt(Context &context, int64_t i) const
void TooLong(const Ch *str, SizeType length, SizeType expected)
virtual ~IValidationErrorHandler()
void NotMultipleOf(int64_t actual, const SValue &expected)
#define RAPIDJSON_DELETE(x)
! customization point for global delete
const ValueType & GetError() const
SchemaEntry(const PointerType &p, SchemaType *s, bool o, Allocator *allocator)
virtual void DisallowedValue()=0
char * u32toa(uint32_t value, char *buffer)
bool CheckDoubleMinimum(Context &context, double d) const
virtual void NotOneOf(ISchemaValidator **subvalidators, SizeType count)=0
ISchemaStateFactory< SchemaType > SchemaValidatorFactoryType
void TooFewItems(SizeType actualCount, SizeType expectedCount)
#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)
#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)
void NotOneOf(ISchemaValidator **subvalidators, SizeType count)
virtual void * CreateHasher()
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
virtual void StartMissingDependentProperties()=0
const Ch * invalidKeyword
void BelowMinimum(double actual, const SValue &expected, bool exclusive)
bool Search(InputStream &is)
static uint64_t Hash(uint64_t h, uint64_t d)
virtual ~ISchemaStateFactory()
ErrorHandlerType & error_handler
PointerType GetInvalidDocumentPointer() const
Gets the JSON pointer pointed to the invalid value.
C-runtime library allocator.
StateAllocator & GetStateAllocator()
virtual bool IsValid() const
Checks whether the current state is valid.
A helper class for parsing with validation.
Represents an in-memory output stream.
StackAllocator allocator_
ValueType::EncodingType EncodingType
SchemaDocumentType::AllocatorType AllocatorType
const SchemaType * schema
const Ch * GetInvalidSchemaKeyword() const
Gets the keyword of invalid schema.
const GenericPointer< typename T::ValueType > T2 value
bool String(const Ch *str, SizeType len, bool)
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
SchemaDocumentType::ValueType ValueType
virtual void EndDisallowedType(const typename SchemaType::ValueType &actualType)=0
GenericValue< UTF8<>, StateAllocator > HashCodeArray
SchemaType::Context Context
Schema(SchemaDocumentType *schemaDocument, const PointerType &p, const ValueType &value, const ValueType &document, AllocatorType *allocator)
void PropertyViolations(ISchemaValidator **subvalidators, SizeType count)
bool StartObject(Context &context) const
const SchemaType & GetRoot() const
Get the root schema.
const PointerType & GetPointer() const
GenericSchemaDocument(const ValueType &document, const Ch *uri=0, SizeType uriLength=0, IRemoteSchemaDocumentProviderType *remoteProvider=0, Allocator *allocator=0)
Constructor.
void StartDependencyErrors()
internal::Stack< Allocator > schemaMap_
IGenericRemoteSchemaDocumentProvider< SchemaDocument > IRemoteSchemaDocumentProvider
IGenericRemoteSchemaDocumentProvider using SchemaDocument.
const SchemaType * schema
const SchemaType * root_
Root schema.
virtual void StartDisallowedType()=0
virtual void * MallocState(size_t size)=0
void AddMissingProperty(const SValue &name)
SchemaRefEntry(const PointerType &s, const PointerType &t, const SchemaType **outSchema, Allocator *allocator)
bool additionalProperties_
internal::Stack< StateAllocator > schemaStack_
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
bool Int64(Context &context, int64_t i) const
void EndMissingDependentProperties(const SValue &sourceName)
bool StartArray(Context &context) const
Reference to a constant string (not taking a copy)
bool Null(Context &context) const
bool EndArray(Context &context, SizeType elementCount) const
bool FindPropertyIndex(const ValueType &name, SizeType *outIndex) const
virtual void TooManyProperties(SizeType actualCount, SizeType expectedCount)=0
const SchemaType ** schema
const SchemaType & CurrentSchema() const
virtual void * CreateHasher()=0
bool EndObject(SizeType memberCount)
~GenericSchemaDocument()
Destructor.
const GenericPointer< typename T::ValueType > & pointer
bool hasSchemaDependencies_
bool String(Context &context, const Ch *str, SizeType length, bool) const
void TooManyProperties(SizeType actualCount, SizeType expectedCount)
void StartMissingProperties()
virtual void DoesNotMatch(const Ch *str, SizeType length)=0
RAPIDJSON_FORCEINLINE bool EndValue(Context &context) const
virtual uint64_t GetHashCode(void *hasher)
virtual void AddMissingProperty(const SValue &name)=0
GenericValue< SourceEncoding, StackAllocator > ValueType
Default memory allocator used by the parser and DOM.
RegexType * CreatePattern(const ValueType &value)
virtual void StartMissingProperties()=0
bool RawNumber(const Ch *str, SizeType length, bool copy)
virtual void DisallowedItem(SizeType index)=0
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Constructor without output handler.
const Ch * GetInvalidSchemaKeyword() const
virtual uint64_t GetHashCode(void *hasher)=0
GenericSchemaValidator< SchemaDocument > SchemaValidator
bool WriteNumber(const Number &n)
static void AssignIfExist(bool &out, const ValueType &value, const ValueType &name)
virtual void TooShort(const Ch *str, SizeType length, SizeType expected)=0
SizeType patternPropertiesSchemaCount
void DuplicateItems(SizeType index1, SizeType index2)
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)
virtual void TooFewItems(SizeType actualCount, SizeType expectedCount)=0
virtual void TooManyItems(SizeType actualCount, SizeType expectedCount)=0
virtual void BelowMinimum(int64_t actual, const SValue &expected, bool exclusive)=0
virtual void DestroryHasher(void *hasher)
RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType &schema)
void TooManyItems(SizeType actualCount, SizeType expectedCount)
bool Uint(Context &context, unsigned u) const
void AddType(const ValueType &type)
bool Bool(Context &context, bool) const
bool EndObject(SizeType memberCount)
virtual void AddMissingDependentProperty(const SValue &targetName)=0
virtual ISchemaValidator * CreateSchemaValidator(const SchemaType &root)
const Context & CurrentContext() const
GenericPointer< ValueType, Allocator > PointerType