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) && \ 30 (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)) 31 #define RAPIDJSON_SCHEMA_USE_STDREGEX 1 33 #define RAPIDJSON_SCHEMA_USE_STDREGEX 0 36 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 38 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 42 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX 43 #define RAPIDJSON_SCHEMA_HAS_REGEX 1 45 #define RAPIDJSON_SCHEMA_HAS_REGEX 0 48 #ifndef RAPIDJSON_SCHEMA_VERBOSE 49 #define RAPIDJSON_SCHEMA_VERBOSE 0 52 #if RAPIDJSON_SCHEMA_VERBOSE 59 RAPIDJSON_DIAG_OFF(effc++)
63 RAPIDJSON_DIAG_OFF(weak - vtables)
64 RAPIDJSON_DIAG_OFF(exit - time - destructors)
65 RAPIDJSON_DIAG_OFF(c++ 98 - compat - pedantic)
66 RAPIDJSON_DIAG_OFF(variadic - macros)
67 #elif defined(_MSC_VER) 68 RAPIDJSON_DIAG_OFF(4512)
76 #if RAPIDJSON_SCHEMA_VERBOSE 80 inline void PrintInvalidKeyword(
const char* keyword)
82 printf(
"Fail keyword: %s\n", keyword);
85 inline void PrintInvalidKeyword(
const wchar_t* keyword)
87 wprintf(L
"Fail keyword: %ls\n", keyword);
90 inline void PrintInvalidDocument(
const char* document)
92 printf(
"Fail document: %s\n\n", document);
95 inline void PrintInvalidDocument(
const wchar_t* document)
97 wprintf(L
"Fail document: %ls\n\n", document);
100 inline void PrintValidatorPointers(
unsigned depth,
const char*
s,
const char*
d)
102 printf(
"S: %*s%s\nD: %*s%s\n\n", depth * 4,
" ", s, depth * 4,
" ", d);
105 inline void PrintValidatorPointers(
unsigned depth,
const wchar_t* s,
const wchar_t* d)
107 wprintf(L
"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L
" ", s, depth * 4, L
" ", d);
112 #endif // RAPIDJSON_SCHEMA_VERBOSE 117 #if RAPIDJSON_SCHEMA_VERBOSE 118 #define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword) 120 #define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) 123 #define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword) \ 124 RAPIDJSON_MULTILINEMACRO_BEGIN \ 125 context.invalidKeyword = keyword.GetString(); \ 126 RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString()); \ 128 RAPIDJSON_MULTILINEMACRO_END 133 template <
typename ValueType,
typename Allocator>
138 template <
typename SchemaDocumentType>
150 virtual bool IsValid()
const = 0;
156 template <
typename SchemaType>
165 virtual void* CreateHasher() = 0;
166 virtual uint64_t GetHashCode(
void* hasher) = 0;
167 virtual void DestroryHasher(
void* hasher) = 0;
168 virtual void* MallocState(
size_t size) = 0;
169 virtual void FreeState(
void* p) = 0;
175 template <
typename SchemaType>
179 typedef typename SchemaType::Ch
Ch;
180 typedef typename SchemaType::SValue
SValue;
186 virtual void NotMultipleOf(
int64_t actual,
const SValue& expected) = 0;
187 virtual void NotMultipleOf(
uint64_t actual,
const SValue& expected) = 0;
188 virtual void NotMultipleOf(
double actual,
const SValue& expected) = 0;
189 virtual void AboveMaximum(
int64_t actual,
const SValue& expected,
bool exclusive) = 0;
190 virtual void AboveMaximum(
uint64_t actual,
const SValue& expected,
bool exclusive) = 0;
191 virtual void AboveMaximum(
double actual,
const SValue& expected,
bool exclusive) = 0;
192 virtual void BelowMinimum(
int64_t actual,
const SValue& expected,
bool exclusive) = 0;
193 virtual void BelowMinimum(
uint64_t actual,
const SValue& expected,
bool exclusive) = 0;
194 virtual void BelowMinimum(
double actual,
const SValue& expected,
bool exclusive) = 0;
196 virtual void TooLong(
const Ch* str,
SizeType length,
SizeType expected) = 0;
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,
SizeType expectedCount) = 0;
206 virtual void TooFewProperties(
SizeType actualCount,
SizeType expectedCount) = 0;
207 virtual void StartMissingProperties() = 0;
208 virtual void AddMissingProperty(
const SValue& name) = 0;
209 virtual bool EndMissingProperties() = 0;
211 virtual void DisallowedProperty(
const Ch* name,
SizeType length) = 0;
213 virtual void StartDependencyErrors() = 0;
214 virtual void StartMissingDependentProperties() = 0;
215 virtual void AddMissingDependentProperty(
const SValue& targetName) = 0;
216 virtual void EndMissingDependentProperties(
const SValue& sourceName) = 0;
217 virtual void AddDependencySchemaError(
const SValue& souceName,
ISchemaValidator* subvalidator) = 0;
218 virtual bool EndDependencyErrors() = 0;
220 virtual void DisallowedValue() = 0;
221 virtual void StartDisallowedType() = 0;
222 virtual void AddExpectedType(
const typename SchemaType::ValueType& expectedType) = 0;
223 virtual void EndDisallowedType(
const typename SchemaType::ValueType& actualType) = 0;
227 virtual void Disallowed() = 0;
234 template <
typename Encoding,
typename Allocator>
238 typedef typename Encoding::Ch
Ch;
240 Hasher(Allocator* allocator = 0,
size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity)
256 n.
d =
static_cast<double>(i);
257 return WriteNumber(n);
263 n.
d =
static_cast<double>(u);
264 return WriteNumber(n);
270 n.
d =
static_cast<double>(i);
271 return WriteNumber(n);
277 n.
d =
static_cast<double>(u);
278 return WriteNumber(n);
288 return WriteNumber(n);
309 return String(str, len, copy);
314 uint64_t* kv = stack_.template Pop<uint64_t>(memberCount * 2);
315 for (
SizeType i = 0; i < memberCount; i++)
316 h ^= Hash(kv[i * 2], kv[i * 2 + 1]);
317 *stack_.template Push<uint64_t>() = h;
328 uint64_t* e = stack_.template Pop<uint64_t>(elementCount);
329 for (
SizeType i = 0; i < elementCount; i++)
331 *stack_.template Push<uint64_t>() = h;
337 return stack_.GetSize() ==
sizeof(
uint64_t);
343 return *stack_.template Top<uint64_t>();
347 static const size_t kDefaultSize = 256;
360 return WriteBuffer(type, 0, 0);
372 const unsigned char*
d =
static_cast<const unsigned char*
>(data);
373 for (
size_t i = 0; i < len; i++)
375 *stack_.template Push<uint64_t>() = h;
393 template <
typename SchemaDocumentType>
400 typedef typename ValueType::Ch
Ch;
406 kPatternValidatorWithAdditionalProperty
416 , arrayElementHashCodes()
419 , patternPropertiesValidators()
420 , patternPropertiesValidatorCount()
421 , patternPropertiesSchemas()
422 , patternPropertiesSchemaCount()
423 , valuePatternValidatorType(kPatternValidatorOnly)
426 , valueUniqueness(false)
427 , arrayUniqueness(false)
434 factory.DestroryHasher(hasher);
437 for (
SizeType i = 0; i < validatorCount; i++)
438 factory.DestroySchemaValidator(validators[i]);
439 factory.FreeState(validators);
441 if (patternPropertiesValidators)
443 for (
SizeType i = 0; i < patternPropertiesValidatorCount; i++)
444 factory.DestroySchemaValidator(patternPropertiesValidators[i]);
445 factory.FreeState(patternPropertiesValidators);
447 if (patternPropertiesSchemas)
448 factory.FreeState(patternPropertiesSchemas);
450 factory.FreeState(propertyExist);
478 template <
typename SchemaDocumentType>
482 typedef typename SchemaDocumentType::ValueType
ValueType;
486 typedef typename EncodingType::Ch
Ch;
493 Schema(SchemaDocumentType* schemaDocument,
const PointerType& p,
const ValueType&
value,
const ValueType& document,
494 AllocatorType* allocator)
497 , pointer_(p, allocator)
502 , type_((1 << kTotalSchemaType) - 1)
505 , notValidatorIndex_()
507 , additionalPropertiesSchema_()
508 , patternProperties_()
509 , patternPropertyCount_()
513 , additionalProperties_(true)
516 , hasSchemaDependencies_()
517 , additionalItemsSchema_()
523 , additionalItems_(true)
524 , uniqueItems_(false)
528 , exclusiveMinimum_(false)
529 , exclusiveMaximum_(false)
530 , defaultValueLength_(0)
532 typedef typename SchemaDocumentType::ValueType
ValueType;
533 typedef typename ValueType::ConstValueIterator ConstValueIterator;
534 typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
536 if (!value.IsObject())
539 if (
const ValueType* v = GetMember(value, GetTypeString()))
544 else if (v->IsArray())
545 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
549 if (
const ValueType* v = GetMember(value, GetEnumString()))
550 if (v->IsArray() && v->Size() > 0)
553 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
556 char buffer[256u + 24];
558 EnumHasherType h(&hasherAllocator, 256);
560 enum_[enumCount_++] = h.GetHashCode();
566 AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document);
567 AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document);
568 AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document);
571 if (
const ValueType* v = GetMember(value, GetNotString()))
573 schemaDocument->CreateSchema(¬_, p.Append(GetNotString(),
allocator_), *v, document);
574 notValidatorIndex_ = validatorCount_;
580 const ValueType* properties = GetMember(value, GetPropertiesString());
581 const ValueType* required = GetMember(value, GetRequiredString());
582 const ValueType* dependencies = GetMember(value, GetDependenciesString());
587 if (properties && properties->IsObject())
588 for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr)
589 AddUniqueElement(allProperties, itr->name);
591 if (required && required->IsArray())
592 for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
594 AddUniqueElement(allProperties, *itr);
596 if (dependencies && dependencies->IsObject())
597 for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr)
599 AddUniqueElement(allProperties, itr->name);
600 if (itr->value.IsArray())
601 for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i)
603 AddUniqueElement(allProperties, *i);
606 if (allProperties.Size() > 0)
608 propertyCount_ = allProperties.Size();
610 for (
SizeType i = 0; i < propertyCount_; i++)
613 properties_[i].
name = allProperties[i];
619 if (properties && properties->IsObject())
621 PointerType q = p.Append(GetPropertiesString(),
allocator_);
622 for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr)
625 if (FindPropertyIndex(itr->name, &index))
626 schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name,
allocator_), itr->value,
631 if (
const ValueType* v = GetMember(value, GetPatternPropertiesString()))
633 PointerType q = p.Append(GetPatternPropertiesString(),
allocator_);
636 patternPropertyCount_ = 0;
638 for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr)
641 patternProperties_[patternPropertyCount_].
pattern = CreatePattern(itr->name);
642 schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name,
allocator_),
643 itr->value, document);
644 patternPropertyCount_++;
648 if (required && required->IsArray())
649 for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
653 if (FindPropertyIndex(*itr, &index))
655 properties_[index].required =
true;
660 if (dependencies && dependencies->IsObject())
662 PointerType q = p.Append(GetDependenciesString(),
allocator_);
663 hasDependencies_ =
true;
664 for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr)
667 if (FindPropertyIndex(itr->name, &sourceIndex))
669 if (itr->value.IsArray())
671 properties_[sourceIndex].dependencies =
672 static_cast<bool*
>(
allocator_->Malloc(
sizeof(
bool) * propertyCount_));
673 std::memset(properties_[sourceIndex].dependencies, 0,
sizeof(
bool) * propertyCount_);
674 for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr)
677 if (FindPropertyIndex(*targetItr, &targetIndex))
678 properties_[sourceIndex].dependencies[targetIndex] =
true;
681 else if (itr->value.IsObject())
683 hasSchemaDependencies_ =
true;
684 schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name,
allocator_),
685 itr->value, document);
686 properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_;
693 if (
const ValueType* v = GetMember(value, GetAdditionalPropertiesString()))
696 additionalProperties_ = v->GetBool();
697 else if (v->IsObject())
698 schemaDocument->CreateSchema(&additionalPropertiesSchema_,
699 p.Append(GetAdditionalPropertiesString(),
allocator_), *v, document);
702 AssignIfExist(minProperties_, value, GetMinPropertiesString());
703 AssignIfExist(maxProperties_, value, GetMaxPropertiesString());
706 if (
const ValueType* v = GetMember(value, GetItemsString()))
708 PointerType q = p.Append(GetItemsString(),
allocator_);
710 schemaDocument->CreateSchema(&itemsList_, q, *v, document);
711 else if (v->IsArray())
715 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++)
716 schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index,
allocator_), *itr, document);
720 AssignIfExist(minItems_, value, GetMinItemsString());
721 AssignIfExist(maxItems_, value, GetMaxItemsString());
723 if (
const ValueType* v = GetMember(value, GetAdditionalItemsString()))
726 additionalItems_ = v->GetBool();
727 else if (v->IsObject())
728 schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(),
allocator_), *v,
732 AssignIfExist(uniqueItems_, value, GetUniqueItemsString());
735 AssignIfExist(minLength_, value, GetMinLengthString());
736 AssignIfExist(maxLength_, value, GetMaxLengthString());
738 if (
const ValueType* v = GetMember(value, GetPatternString()))
739 pattern_ = CreatePattern(*v);
742 if (
const ValueType* v = GetMember(value, GetMinimumString()))
746 if (
const ValueType* v = GetMember(value, GetMaximumString()))
750 AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString());
751 AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString());
753 if (
const ValueType* v = GetMember(value, GetMultipleOfString()))
754 if (v->IsNumber() && v->GetDouble() > 0.0)
758 if (
const ValueType* v = GetMember(value, GetDefaultValueString()))
760 defaultValueLength_ = v->GetStringLength();
765 AllocatorType::Free(enum_);
768 for (
SizeType i = 0; i < propertyCount_; i++)
770 AllocatorType::Free(properties_);
772 if (patternProperties_)
774 for (
SizeType i = 0; i < patternPropertyCount_; i++)
776 AllocatorType::Free(patternProperties_);
778 AllocatorType::Free(itemsTuple_);
779 #if RAPIDJSON_SCHEMA_HAS_REGEX 782 pattern_->~RegexType();
783 AllocatorType::Free(pattern_);
807 else if (itemsTuple_)
811 else if (additionalItemsSchema_)
813 else if (additionalItems_)
829 RAPIDJSON_FORCEINLINE
bool EndValue(Context& context)
const 833 bool otherValid =
false;
838 bool patternValid =
true;
842 patternValid =
false;
856 if (!patternValid || !otherValid)
862 else if (!patternValid && !otherValid)
872 for (
SizeType i = 0; i < enumCount_; i++)
881 for (
SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++)
890 for (
SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)
900 bool oneValid =
false;
901 for (
SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++)
928 bool Null(Context& context)
const 930 if (!(type_ & (1 << kNullSchemaType)))
932 DisallowedType(context, GetNullString());
935 return CreateParallelValidator(context);
938 bool Bool(Context& context,
bool)
const 940 if (!(type_ & (1 << kBooleanSchemaType)))
942 DisallowedType(context, GetBooleanString());
945 return CreateParallelValidator(context);
948 bool Int(Context& context,
int i)
const 950 if (!CheckInt(context, i))
952 return CreateParallelValidator(context);
955 bool Uint(Context& context,
unsigned u)
const 957 if (!CheckUint(context, u))
959 return CreateParallelValidator(context);
964 if (!CheckInt(context, i))
966 return CreateParallelValidator(context);
971 if (!CheckUint(context, u))
973 return CreateParallelValidator(context);
976 bool Double(Context& context,
double d)
const 978 if (!(type_ & (1 << kNumberSchemaType)))
980 DisallowedType(context, GetNumberString());
984 if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d))
987 if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d))
990 if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d))
993 return CreateParallelValidator(context);
998 if (!(type_ & (1 << kStringSchemaType)))
1000 DisallowedType(context, GetStringString());
1004 if (minLength_ != 0 || maxLength_ !=
SizeType(~0))
1007 if (internal::CountStringCodePoint<EncodingType>(str, length, &count))
1009 if (count < minLength_)
1014 if (count > maxLength_)
1022 if (pattern_ && !IsPatternMatch(pattern_, str, length))
1028 return CreateParallelValidator(context);
1033 if (!(type_ & (1 << kObjectSchemaType)))
1035 DisallowedType(context, GetObjectString());
1039 if (hasDependencies_ || hasRequired_)
1042 std::memset(context.
propertyExist, 0,
sizeof(
bool) * propertyCount_);
1045 if (patternProperties_)
1049 static_cast<const SchemaType**
>(context.
factory.
MallocState(
sizeof(
const SchemaType*) * count));
1054 return CreateParallelValidator(context);
1059 if (patternProperties_)
1062 for (
SizeType i = 0; i < patternPropertyCount_; i++)
1063 if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len))
1071 if (FindPropertyIndex(
ValueType(str, len).Move(), &index))
1088 if (additionalPropertiesSchema_)
1097 context.
valueSchema = additionalPropertiesSchema_;
1100 else if (additionalProperties_)
1120 for (
SizeType index = 0; index < propertyCount_; index++)
1121 if (properties_[index].required && !context.
propertyExist[index])
1122 if (properties_[index].schema->defaultValueLength_ == 0)
1128 if (memberCount < minProperties_)
1134 if (memberCount > maxProperties_)
1140 if (hasDependencies_)
1143 for (
SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++)
1151 for (
SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++)
1159 if (!dependenciesValidator->
IsValid())
1173 if (!(type_ & (1 << kArraySchemaType)))
1175 DisallowedType(context, GetArrayString());
1182 return CreateParallelValidator(context);
1189 if (elementCount < minItems_)
1195 if (elementCount > maxItems_)
1205 #define RAPIDJSON_STRING_(name, ...) \ 1206 static const ValueType& Get##name##String() \ 1208 static const Ch s[] = { __VA_ARGS__, '\0' }; \ 1209 static const ValueType v(s, static_cast<SizeType>(sizeof(s) / sizeof(Ch) - 1)); \ 1226 RAPIDJSON_STRING_(Properties,
'p',
'r',
'o',
'p',
'e',
'r',
't',
'i',
'e',
's')
1228 RAPIDJSON_STRING_(Dependencies,
'd',
'e',
'p',
'e',
'n',
'd',
'e',
'n',
'c',
'i',
'e',
's')
1229 RAPIDJSON_STRING_(PatternProperties,
'p',
'a',
't',
't',
'e',
'r',
'n',
'P',
'r',
'o',
'p',
'e',
'r',
't',
'i',
'e',
1231 RAPIDJSON_STRING_(AdditionalProperties, '
a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e',
1232 'r', 't', 'i', 'e', 's')
1233 RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
1234 RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
1238 RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's')
1239 RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's')
1245 RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm')
1246 RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm')
1247 RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f')
1250 #undef RAPIDJSON_STRING_ 1265 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1267 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 1268 typedef std::basic_regex<Ch> RegexType;
1270 typedef char RegexType;
1280 AllocatorType::Free(schemas);
1287 template <
typename V1,
typename V2>
1290 for (
typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
1293 V1 c(v, *allocator_);
1294 a.PushBack(c, *allocator_);
1299 typename ValueType::ConstMemberIterator itr = value.FindMember(name);
1300 return itr != value.MemberEnd() ? &(itr->value) : 0;
1305 if (
const ValueType* v = GetMember(value, name))
1312 if (
const ValueType* v = GetMember(value, name))
1313 if (v->IsUint64() && v->GetUint64() <=
SizeType(~0))
1314 out = static_cast<SizeType>(v->GetUint64());
1318 const ValueType& name,
const ValueType& document)
1320 if (
const ValueType* v = GetMember(value, name))
1322 if (v->IsArray() && v->Size() > 0)
1324 PointerType q = p.Append(name, allocator_);
1325 out.
count = v->Size();
1329 schemaDocument.CreateSchema(&out.
schemas[i], q.Append(i, allocator_), (*v)[i], document);
1330 out.
begin = validatorCount_;
1331 validatorCount_ += out.
count;
1336 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1337 template <
typename ValueType>
1340 if (value.IsString())
1342 RegexType* r =
new (allocator_->Malloc(
sizeof(RegexType))) RegexType(value.GetString(), allocator_);
1346 AllocatorType::Free(r);
1359 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 1360 template <
typename ValueType>
1361 RegexType* CreatePattern(
const ValueType&
value)
1363 if (value.IsString())
1365 RegexType* r =
static_cast<RegexType*
>(allocator_->Malloc(
sizeof(RegexType)));
1369 RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);
1371 catch (
const std::regex_error&)
1373 AllocatorType::Free(r);
1379 static bool IsPatternMatch(
const RegexType* pattern,
const Ch* str,
SizeType length)
1381 std::match_results<const Ch*> r;
1382 return std::regex_search(str, str + length, r, *pattern);
1385 template <
typename ValueType>
1386 RegexType* CreatePattern(
const ValueType&)
1391 static bool IsPatternMatch(
const RegexType*,
const Ch*,
SizeType)
1395 #endif // RAPIDJSON_SCHEMA_USE_STDREGEX 1399 if (type == GetNullString())
1400 type_ |= 1 << kNullSchemaType;
1401 else if (type == GetBooleanString())
1402 type_ |= 1 << kBooleanSchemaType;
1403 else if (type == GetObjectString())
1404 type_ |= 1 << kObjectSchemaType;
1405 else if (type == GetArrayString())
1406 type_ |= 1 << kArraySchemaType;
1407 else if (type == GetStringString())
1408 type_ |= 1 << kStringSchemaType;
1409 else if (type == GetIntegerString())
1410 type_ |= 1 << kIntegerSchemaType;
1411 else if (type == GetNumberString())
1412 type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
1420 if (validatorCount_)
1428 CreateSchemaValidators(context, allOf_);
1431 CreateSchemaValidators(context, anyOf_);
1434 CreateSchemaValidators(context, oneOf_);
1439 if (hasSchemaDependencies_)
1441 for (
SizeType i = 0; i < propertyCount_; i++)
1442 if (properties_[i].dependenciesSchema)
1443 context.
validators[properties_[i].dependenciesValidatorIndex] =
1460 SizeType len = name.GetStringLength();
1461 const Ch* str = name.GetString();
1462 for (
SizeType index = 0; index < propertyCount_; index++)
1463 if (properties_[index].name.GetStringLength() == len &&
1464 (std::memcmp(properties_[index].name.GetString(), str,
sizeof(Ch) * len) == 0))
1474 if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))
1476 DisallowedType(context, GetIntegerString());
1480 if (!minimum_.IsNull())
1482 if (minimum_.IsInt64())
1484 if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64())
1490 else if (minimum_.IsUint64())
1495 else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1499 if (!maximum_.IsNull())
1501 if (maximum_.IsInt64())
1503 if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64())
1509 else if (maximum_.IsUint64())
1513 else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1517 if (!multipleOf_.IsNull())
1519 if (multipleOf_.IsUint64())
1521 if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0)
1527 else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1536 if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))
1538 DisallowedType(context, GetIntegerString());
1542 if (!minimum_.IsNull())
1544 if (minimum_.IsUint64())
1546 if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64())
1552 else if (minimum_.IsInt64())
1554 else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1558 if (!maximum_.IsNull())
1560 if (maximum_.IsUint64())
1562 if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64())
1568 else if (maximum_.IsInt64())
1573 else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1577 if (!multipleOf_.IsNull())
1579 if (multipleOf_.IsUint64())
1581 if (i % multipleOf_.GetUint64() != 0)
1587 else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1596 if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble())
1606 if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble())
1616 double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());
1617 double q = std::floor(a / b);
1618 double r = a - q * b;
1632 if (type_ & (1 << kNullSchemaType))
1634 if (type_ & (1 << kBooleanSchemaType))
1636 if (type_ & (1 << kObjectSchemaType))
1638 if (type_ & (1 << kArraySchemaType))
1640 if (type_ & (1 << kStringSchemaType))
1643 if (type_ & (1 << kNumberSchemaType))
1645 else if (type_ & (1 << kIntegerSchemaType))
1653 Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false)
1658 AllocatorType::Free(dependencies);
1677 pattern->~RegexType();
1678 AllocatorType::Free(pattern);
1733 template <
typename Stack,
typename Ch>
1738 *documentStack.template Push<Ch>() =
'/';
1741 static_cast<size_t>((
sizeof(
SizeType) == 4 ?
u32toa(index, buffer) :
u64toa(index, buffer)) - buffer);
1742 for (
size_t i = 0; i < length; i++)
1743 *documentStack.template Push<Ch>() =
static_cast<Ch
>(buffer[i]);
1748 template <
typename Stack>
1755 char* buffer = documentStack.template Push<char>(1 + 10);
1758 documentStack.template Pop<char>(
static_cast<size_t>(10 - (end - buffer)));
1762 char* buffer = documentStack.template Push<char>(1 + 20);
1765 documentStack.template Pop<char>(
static_cast<size_t>(20 - (end - buffer)));
1775 template <
typename SchemaDocumentType>
1779 typedef typename SchemaDocumentType::Ch
Ch;
1784 virtual const SchemaDocumentType* GetRemoteDocument(
const Ch* uri,
SizeType length) = 0;
1799 template <
typename ValueT,
typename Allocator = CrtAllocator>
1807 typedef typename EncodingType::Ch
Ch;
1812 template <
typename,
typename,
typename>
1826 IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0)
1827 : remoteProvider_(remoteProvider)
1828 , allocator_(allocator)
1832 , schemaMap_(allocator, kInitialSchemaMapSize)
1833 , schemaRef_(allocator, kInitialSchemaRefSize)
1838 Ch noUri[1] = { 0 };
1839 uri_.SetString(uri ? uri : noUri, uriLength, *allocator_);
1841 typeless_ =
static_cast<SchemaType*
>(allocator_->Malloc(
sizeof(SchemaType)));
1850 while (!schemaRef_.Empty())
1852 SchemaRefEntry* refEntry = schemaRef_.template Pop<SchemaRefEntry>(1);
1853 if (
const SchemaType*
s = GetSchema(refEntry->
target))
1859 if (!GetSchema(refEntry->
source))
1861 new (schemaMap_.template Push<SchemaEntry>())
1865 else if (refEntry->
schema)
1866 *refEntry->
schema = typeless_;
1868 refEntry->~SchemaRefEntry();
1873 schemaRef_.ShrinkToFit();
1876 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 1879 allocator_(rhs.allocator_),
1880 ownAllocator_(rhs.ownAllocator_),
1882 typeless_(rhs.typeless_),
1883 schemaMap_(std::move(rhs.schemaMap_)),
1884 schemaRef_(std::move(rhs.schemaRef_)),
1885 uri_(std::move(rhs.uri_))
1887 rhs.remoteProvider_ = 0;
1889 rhs.ownAllocator_ = 0;
1897 while (!schemaMap_.Empty())
1898 schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry();
1902 typeless_->~SchemaType();
1903 Allocator::Free(typeless_);
1928 SchemaRefEntry(
const PointerType& s,
const PointerType& t,
const SchemaType** outSchema, Allocator* allocator)
1929 :
source(s, allocator), target(t, allocator), schema(outSchema)
1939 SchemaEntry(
const PointerType& p, SchemaType* s,
bool o, Allocator* allocator)
1940 :
pointer(p, allocator), schema(s), owned(o)
1947 schema->~SchemaType();
1948 Allocator::Free(schema);
1957 const ValueType& document)
1960 *schema = typeless_;
1964 const SchemaType*
s = GetSchema(pointer);
1966 CreateSchema(schema, pointer, v, document);
1968 for (
typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
1969 CreateSchemaRecursive(0, pointer.
Append(itr->name, allocator_), itr->value, document);
1972 for (
SizeType i = 0; i < v.Size(); i++)
1973 CreateSchemaRecursive(0, pointer.
Append(i, allocator_), v[i], document);
1977 const ValueType& document)
1982 if (!HandleRefSchema(pointer, schema, v, document))
1984 SchemaType*
s =
new (allocator_->Malloc(
sizeof(SchemaType))) SchemaType(
this, pointer, v, document, allocator_);
1985 new (schemaMap_.template Push<SchemaEntry>())
SchemaEntry(pointer, s,
true, allocator_);
1993 const ValueType& document)
1995 static const Ch kRefString[] = {
'$',
'r',
'e',
'f',
'\0' };
1996 static const ValueType kRefValue(kRefString, 4);
1998 typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue);
1999 if (itr == v.MemberEnd())
2002 if (itr->value.IsString())
2004 SizeType len = itr->value.GetStringLength();
2007 const Ch*
s = itr->value.GetString();
2009 while (i < len && s[i] !=
'#')
2014 if (remoteProvider_)
2018 PointerType
pointer(&s[i], len - i, allocator_);
2019 if (pointer.IsValid())
2021 if (
const SchemaType* sc = remoteDocument->GetSchema(pointer))
2025 new (schemaMap_.template Push<SchemaEntry>())
2026 SchemaEntry(source, const_cast<SchemaType*>(sc),
false, allocator_);
2033 else if (s[i] ==
'#')
2035 PointerType
pointer(&s[i], len - i, allocator_);
2036 if (pointer.IsValid())
2038 if (
const ValueType* nv = pointer.Get(document))
2039 if (HandleRefSchema(source, schema, *nv, document))
2042 new (schemaRef_.template Push<SchemaRefEntry>())
SchemaRefEntry(source, pointer, schema, allocator_);
2053 for (
const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>();
2054 target != schemaMap_.template End<SchemaEntry>(); ++target)
2055 if (pointer == target->pointer)
2056 return target->schema;
2062 for (
const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>();
2063 target != schemaMap_.template End<SchemaEntry>(); ++target)
2064 if (schema == target->schema)
2065 return target->pointer;
2066 return PointerType();
2074 static const size_t kInitialSchemaMapSize = 64;
2075 static const size_t kInitialSchemaRefSize = 64;
2107 template <
typename SchemaDocumentType,
2119 typedef typename EncodingType::Ch
Ch;
2131 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
2132 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
2133 : schemaDocument_(&schemaDocument)
2134 , root_(schemaDocument.GetRoot())
2135 , stateAllocator_(allocator)
2136 , ownStateAllocator_(0)
2137 , schemaStack_(allocator, schemaStackCapacity)
2138 , documentStack_(allocator, documentStackCapacity)
2142 , missingDependents_()
2158 StateAllocator* allocator = 0,
size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
2159 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
2160 : schemaDocument_(&schemaDocument)
2161 , root_(schemaDocument.GetRoot())
2162 , stateAllocator_(allocator)
2163 , ownStateAllocator_(0)
2164 , schemaStack_(allocator, schemaStackCapacity)
2165 , documentStack_(allocator, documentStackCapacity)
2166 , outputHandler_(&outputHandler)
2169 , missingDependents_()
2187 while (!schemaStack_.Empty())
2189 documentStack_.Clear();
2191 currentError_.SetNull();
2192 missingDependents_.SetNull();
2216 return schemaStack_.Empty() ? PointerType() : CurrentSchema().GetPointer();
2222 return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword;
2228 if (documentStack_.Empty())
2230 return PointerType();
2234 return PointerType(documentStack_.template Bottom<Ch>(), documentStack_.GetSize() /
sizeof(Ch));
2240 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected);
2244 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected);
2248 AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected);
2252 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected,
2253 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
2257 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected,
2258 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
2262 AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected,
2263 exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
2267 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected,
2268 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
2272 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected,
2273 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
2277 AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected,
2278 exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
2283 AddNumberError(SchemaType::GetMaxLengthString(), ValueType(str, length, GetStateAllocator()).Move(),
2284 SValue(expected).Move());
2288 AddNumberError(SchemaType::GetMinLengthString(), ValueType(str, length, GetStateAllocator()).Move(),
2289 SValue(expected).Move());
2293 currentError_.SetObject();
2294 currentError_.AddMember(GetActualString(), ValueType(str, length, GetStateAllocator()).Move(), GetStateAllocator());
2295 AddCurrentError(SchemaType::GetPatternString());
2300 currentError_.SetObject();
2301 currentError_.AddMember(GetDisallowedString(), ValueType(index).Move(), GetStateAllocator());
2302 AddCurrentError(SchemaType::GetAdditionalItemsString(),
true);
2306 AddNumberError(SchemaType::GetMinItemsString(), ValueType(actualCount).Move(), SValue(expectedCount).Move());
2310 AddNumberError(SchemaType::GetMaxItemsString(), ValueType(actualCount).Move(), SValue(expectedCount).Move());
2315 duplicates.PushBack(index1, GetStateAllocator());
2316 duplicates.PushBack(index2, GetStateAllocator());
2317 currentError_.SetObject();
2318 currentError_.AddMember(GetDuplicatesString(), duplicates, GetStateAllocator());
2319 AddCurrentError(SchemaType::GetUniqueItemsString(),
true);
2324 AddNumberError(SchemaType::GetMaxPropertiesString(), ValueType(actualCount).Move(), SValue(expectedCount).Move());
2328 AddNumberError(SchemaType::GetMinPropertiesString(), ValueType(actualCount).Move(), SValue(expectedCount).Move());
2332 currentError_.SetArray();
2336 currentError_.PushBack(ValueType(name, GetStateAllocator()).Move(), GetStateAllocator());
2340 if (currentError_.Empty())
2343 error.AddMember(GetMissingString(), currentError_, GetStateAllocator());
2344 currentError_ = error;
2345 AddCurrentError(SchemaType::GetRequiredString());
2351 MergeError(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError());
2355 currentError_.SetObject();
2356 currentError_.AddMember(GetDisallowedString(), ValueType(name, length, GetStateAllocator()).Move(),
2357 GetStateAllocator());
2358 AddCurrentError(SchemaType::GetAdditionalPropertiesString(),
true);
2363 currentError_.SetObject();
2367 missingDependents_.SetArray();
2371 missingDependents_.PushBack(ValueType(targetName, GetStateAllocator()).Move(), GetStateAllocator());
2375 if (!missingDependents_.Empty())
2376 currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(), missingDependents_,
2377 GetStateAllocator());
2381 currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(),
2382 static_cast<GenericSchemaValidator*>(subvalidator)->GetError(), GetStateAllocator());
2386 if (currentError_.ObjectEmpty())
2389 error.AddMember(GetErrorsString(), currentError_, GetStateAllocator());
2390 currentError_ = error;
2391 AddCurrentError(SchemaType::GetDependenciesString());
2397 currentError_.SetObject();
2398 AddCurrentError(SchemaType::GetEnumString());
2402 currentError_.SetArray();
2406 currentError_.PushBack(ValueType(expectedType, GetStateAllocator()).Move(), GetStateAllocator());
2411 error.AddMember(GetExpectedString(), currentError_, GetStateAllocator());
2412 error.AddMember(GetActualString(), ValueType(actualType, GetStateAllocator()).Move(), GetStateAllocator());
2413 currentError_ = error;
2414 AddCurrentError(SchemaType::GetTypeString());
2420 MergeError(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError());
2425 AddErrorArray(SchemaType::GetAnyOfString(), subvalidators, count);
2429 AddErrorArray(SchemaType::GetOneOfString(), subvalidators, count);
2433 currentError_.SetObject();
2434 AddCurrentError(SchemaType::GetNotString());
2437 #define RAPIDJSON_STRING_(name, ...) \ 2438 static const StringRefType& Get##name##String() \ 2440 static const Ch s[] = { __VA_ARGS__, '\0' }; \ 2441 static const StringRefType v(s, static_cast<SizeType>(sizeof(s) / sizeof(Ch) - 1)); \ 2445 RAPIDJSON_STRING_(InstanceRef,
'i',
'n',
's',
't',
'a',
'n',
'c',
'e',
'R',
'e',
'f')
2449 RAPIDJSON_STRING_(Disallowed, 'd', 'i', 's', 'a', 'l', 'l', 'o', 'w', 'e', 'd')
2452 RAPIDJSON_STRING_(Duplicates, 'd', 'u', 'p', 'l', 'i', 'c', 'a', 't', 'e', 's')
2454 #undef RAPIDJSON_STRING_ 2456 #if RAPIDJSON_SCHEMA_VERBOSE 2457 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \ 2458 RAPIDJSON_MULTILINEMACRO_BEGIN \ 2459 *documentStack_.template Push<Ch>() = '\0'; \ 2460 documentStack_.template Pop<Ch>(1); \ 2461 internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>()); \ 2462 RAPIDJSON_MULTILINEMACRO_END 2464 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() 2467 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1) \ 2470 if (!BeginValue() || !CurrentSchema().method arg1) \ 2472 RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_(); \ 2473 return valid_ = false; \ 2476 #define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2) \ 2477 for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); \ 2480 if (context->hasher) \ 2481 static_cast<HasherType*>(context->hasher)->method arg2; \ 2482 if (context->validators) \ 2483 for (SizeType i_ = 0; i_ < context->validatorCount; i_++) \ 2484 static_cast<GenericSchemaValidator*>(context->validators[i_])->method arg2; \ 2485 if (context->patternPropertiesValidators) \ 2486 for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++) \ 2487 static_cast<GenericSchemaValidator*>(context->patternPropertiesValidators[i_])->method arg2; \ 2490 #define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2) \ 2491 return valid_ = EndValue() && (!outputHandler_ || outputHandler_->method arg2) 2493 #define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ 2494 RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1); \ 2495 RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2); \ 2496 RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2) 2539 return valid_ = !outputHandler_ || outputHandler_->StartObject();
2546 AppendToken(str, len);
2547 if (!CurrentSchema().Key(CurrentContext(), str, len, copy))
2548 return valid_ =
false;
2550 return valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy);
2558 if (!CurrentSchema().EndObject(CurrentContext(), memberCount))
2559 return valid_ =
false;
2567 return valid_ = !outputHandler_ || outputHandler_->StartArray();
2575 if (!CurrentSchema().EndArray(CurrentContext(), elementCount))
2576 return valid_ =
false;
2580 #undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_ 2581 #undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_ 2582 #undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ 2583 #undef RAPIDJSON_SCHEMA_HANDLE_VALUE_ 2589 GenericSchemaValidator(*schemaDocument_, root, documentStack_.template Bottom<char>(), documentStack_.GetSize(),
2590 #if RAPIDJSON_SCHEMA_VERBOSE 2593 &GetStateAllocator());
2600 StateAllocator::Free(v);
2610 return static_cast<HasherType*
>(hasher)->GetHashCode();
2617 StateAllocator::Free(h);
2622 return GetStateAllocator().Malloc(size);
2627 StateAllocator::Free(p);
2636 size_t basePathSize,
2640 StateAllocator* allocator = 0,
size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
2641 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
2642 : schemaDocument_(&schemaDocument)
2644 , stateAllocator_(allocator)
2645 , ownStateAllocator_(0)
2646 , schemaStack_(allocator, schemaStackCapacity)
2647 , documentStack_(allocator, documentStackCapacity)
2651 , missingDependents_()
2657 if (basePath && basePathSize)
2658 memcpy(documentStack_.template Push<char>(basePathSize), basePath, basePathSize);
2663 if (!stateAllocator_)
2664 stateAllocator_ = ownStateAllocator_ =
RAPIDJSON_NEW(StateAllocator)();
2665 return *stateAllocator_;
2670 if (schemaStack_.Empty())
2674 if (CurrentContext().inArray)
2676 documentStack_, CurrentContext().arrayElementIndex);
2678 if (!CurrentSchema().BeginValue(CurrentContext()))
2681 SizeType count = CurrentContext().patternPropertiesSchemaCount;
2682 const SchemaType** sa = CurrentContext().patternPropertiesSchemas;
2683 typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
2684 bool valueUniqueness = CurrentContext().valueUniqueness;
2686 PushSchema(*CurrentContext().valueSchema);
2690 CurrentContext().objectPatternValidatorType = patternValidatorType;
2691 ISchemaValidator**& va = CurrentContext().patternPropertiesValidators;
2692 SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount;
2693 va =
static_cast<ISchemaValidator**
>(MallocState(
sizeof(ISchemaValidator*) * count));
2695 va[validatorCount++] = CreateSchemaValidator(*sa[i]);
2698 CurrentContext().arrayUniqueness = valueUniqueness;
2705 if (!CurrentSchema().EndValue(CurrentContext()))
2708 #if RAPIDJSON_SCHEMA_VERBOSE 2710 schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb);
2712 *documentStack_.template Push<Ch>() =
'\0';
2713 documentStack_.template Pop<Ch>(1);
2714 internal::PrintValidatorPointers(depth_, sb.
GetString(), documentStack_.template Bottom<Ch>());
2718 CurrentContext().arrayUniqueness ?
static_cast<HasherType*
>(CurrentContext().hasher)->GetHashCode() : 0;
2722 if (!schemaStack_.Empty())
2724 Context& context = CurrentContext();
2725 if (context.valueUniqueness)
2727 HashCodeArray* a =
static_cast<HashCodeArray*
>(context.arrayElementHashCodes);
2729 CurrentContext().arrayElementHashCodes = a =
2730 new (GetStateAllocator().Malloc(
sizeof(HashCodeArray))) HashCodeArray(
kArrayType);
2732 if (itr->GetUint64() == h)
2734 DuplicateItems(static_cast<SizeType>(itr - a->Begin()), a->Size());
2737 a->PushBack(h, GetStateAllocator());
2742 while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) !=
'/')
2750 documentStack_.template Reserve<Ch>(1 + len * 2);
2751 *documentStack_.template PushUnsafe<Ch>() =
'/';
2756 *documentStack_.template PushUnsafe<Ch>() =
'~';
2757 *documentStack_.template PushUnsafe<Ch>() =
'0';
2759 else if (str[i] ==
'/')
2761 *documentStack_.template PushUnsafe<Ch>() =
'~';
2762 *documentStack_.template PushUnsafe<Ch>() =
'1';
2765 *documentStack_.template PushUnsafe<Ch>() = str[i];
2771 new (schemaStack_.template Push<Context>()) Context(*
this, *
this, &schema);
2776 Context* c = schemaStack_.template Pop<Context>(1);
2777 if (HashCodeArray* a = static_cast<HashCodeArray*>(c->arrayElementHashCodes))
2779 a->~HashCodeArray();
2780 StateAllocator::Free(a);
2788 PointerType instancePointer = GetInvalidDocumentPointer();
2789 ((parent && instancePointer.GetTokenCount() > 0) ?
2790 PointerType(instancePointer.GetTokens(), instancePointer.GetTokenCount() - 1) :
2792 .StringifyUriFragment(sb);
2794 result.AddMember(GetInstanceRefString(), instanceRef, GetStateAllocator());
2796 memcpy(sb.
Push(CurrentSchema().GetURI().GetStringLength()), CurrentSchema().GetURI().GetString(),
2797 CurrentSchema().GetURI().GetStringLength() *
sizeof(Ch));
2798 GetInvalidSchemaPointer().StringifyUriFragment(sb);
2800 result.AddMember(GetSchemaRefString(), schemaRef, GetStateAllocator());
2806 if (member == error_.MemberEnd())
2807 error_.AddMember(keyword, error, GetStateAllocator());
2810 if (member->value.IsObject())
2813 errors.PushBack(member->value, GetStateAllocator());
2814 member->value = errors;
2816 member->value.PushBack(error, GetStateAllocator());
2822 AddErrorLocation(currentError_, parent);
2823 AddError(ValueType(keyword, GetStateAllocator(),
false).Move(), currentError_);
2830 AddError(it->name, it->value);
2834 void AddNumberError(
const typename SchemaType::ValueType& keyword, ValueType& actual,
const SValue& expected,
2835 const typename SchemaType::ValueType& (*exclusive)() = 0)
2837 currentError_.SetObject();
2838 currentError_.AddMember(GetActualString(), actual, GetStateAllocator());
2839 currentError_.AddMember(GetExpectedString(), ValueType(expected, GetStateAllocator()).Move(), GetStateAllocator());
2841 currentError_.AddMember(ValueType(exclusive(), GetStateAllocator()).Move(),
true, GetStateAllocator());
2842 AddCurrentError(keyword);
2849 errors.PushBack(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError(), GetStateAllocator());
2850 currentError_.SetObject();
2851 currentError_.AddMember(GetErrorsString(), errors, GetStateAllocator());
2852 AddCurrentError(keyword);
2857 return *schemaStack_.template Top<Context>()->schema;
2861 return *schemaStack_.template Top<Context>();
2865 return *schemaStack_.template Top<Context>();
2868 static const size_t kDefaultSchemaStackCapacity = 1024;
2869 static const size_t kDefaultDocumentStackCapacity = 256;
2881 #if RAPIDJSON_SCHEMA_VERBOSE 2901 template <
unsigned parseFlags,
typename InputStream,
typename SourceEncoding,
2907 typedef typename InputStream::Ch
Ch;
2916 : is_(is), sd_(sd), invalidSchemaKeyword_(), error_(
kObjectType), isValid_(true)
2920 template <
typename Handler>
2925 parseResult_ = reader.template Parse<parseFlags>(is_, validator);
2927 isValid_ = validator.
IsValid();
2930 invalidSchemaPointer_ = PointerType();
2931 invalidSchemaKeyword_ = 0;
2932 invalidDocumentPointer_ = PointerType();
2940 error_.CopyFrom(validator.
GetError(), allocator_);
2943 return parseResult_;
2948 return parseResult_;
2956 return invalidSchemaPointer_;
2960 return invalidSchemaKeyword_;
2964 return invalidDocumentPointer_;
2973 const SchemaDocumentType&
sd_;
2987 #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)
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.
internal::GenericRegex< EncodingType, AllocatorType > RegexType
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_
Regular expression engine with subset of ECMAscript grammar.
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_
stack to store the current path of validating document (Ch)
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)
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
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)
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
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
OutputHandler * outputHandler_
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_
stack to store the current path of schema (BaseSchemaType *)
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