15 #ifndef RAPIDJSON_SCHEMA_H_ 16 #define RAPIDJSON_SCHEMA_H_ 22 #if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX) 23 #define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1 25 #define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0 28 #if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && !defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)) 29 #define RAPIDJSON_SCHEMA_USE_STDREGEX 1 31 #define RAPIDJSON_SCHEMA_USE_STDREGEX 0 34 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 36 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 40 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX 41 #define RAPIDJSON_SCHEMA_HAS_REGEX 1 43 #define RAPIDJSON_SCHEMA_HAS_REGEX 0 46 #ifndef RAPIDJSON_SCHEMA_VERBOSE 47 #define RAPIDJSON_SCHEMA_VERBOSE 0 50 #if RAPIDJSON_SCHEMA_VERBOSE 57 RAPIDJSON_DIAG_OFF(effc++)
61 RAPIDJSON_DIAG_OFF(weak-vtables)
62 RAPIDJSON_DIAG_OFF(exit-time-destructors)
63 RAPIDJSON_DIAG_OFF(c++98-compat-pedantic)
64 RAPIDJSON_DIAG_OFF(variadic-macros)
68 RAPIDJSON_DIAG_OFF(4512)
76 #if RAPIDJSON_SCHEMA_VERBOSE 80 inline void PrintInvalidKeyword(
const char* keyword) {
81 printf(
"Fail keyword: %s\n", keyword);
84 inline void PrintInvalidKeyword(
const wchar_t* keyword) {
85 wprintf(L
"Fail keyword: %ls\n", keyword);
88 inline void PrintInvalidDocument(
const char* document) {
89 printf(
"Fail document: %s\n\n", document);
92 inline void PrintInvalidDocument(
const wchar_t* document) {
93 wprintf(L
"Fail document: %ls\n\n", document);
96 inline void PrintValidatorPointers(
unsigned depth,
const char*
s,
const char*
d) {
97 printf(
"S: %*s%s\nD: %*s%s\n\n", depth * 4,
" ", s, depth * 4,
" ", d);
100 inline void PrintValidatorPointers(
unsigned depth,
const wchar_t* s,
const wchar_t* d) {
101 wprintf(L
"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L
" ", s, depth * 4, L
" ", d);
106 #endif // RAPIDJSON_SCHEMA_VERBOSE 111 #if RAPIDJSON_SCHEMA_VERBOSE 112 #define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword) 114 #define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) 117 #define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\ 118 RAPIDJSON_MULTILINEMACRO_BEGIN\ 119 context.invalidKeyword = keyword.GetString();\ 120 RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\ 122 RAPIDJSON_MULTILINEMACRO_END 127 template <
typename ValueType,
typename Allocator>
132 template <
typename SchemaDocumentType>
141 virtual bool IsValid()
const = 0;
147 template <
typename SchemaType>
153 virtual void* CreateHasher() = 0;
154 virtual uint64_t GetHashCode(
void* hasher) = 0;
155 virtual void DestroryHasher(
void* hasher) = 0;
156 virtual void* MallocState(
size_t size) = 0;
157 virtual void FreeState(
void* p) = 0;
164 template<
typename Encoding,
typename Allocator>
167 typedef typename Encoding::Ch
Ch;
169 Hasher(Allocator* allocator = 0,
size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {}
173 bool Int(
int i) {
Number n; n.
u.
i = i; n.
d =
static_cast<double>(i);
return WriteNumber(n); }
174 bool Uint(
unsigned u) {
Number n; n.
u.
u = u; n.
d =
static_cast<double>(u);
return WriteNumber(n); }
179 if (d < 0) n.
u.
i =
static_cast<int64_t>(d);
182 return WriteNumber(n);
196 bool Key(
const Ch* str,
SizeType len,
bool copy) {
return String(str, len, copy); }
199 uint64_t* kv = stack_.template Pop<uint64_t>(memberCount * 2);
200 for (
SizeType i = 0; i < memberCount; i++)
201 h ^= Hash(kv[i * 2], kv[i * 2 + 1]);
202 *stack_.template Push<uint64_t>() = h;
209 uint64_t* e = stack_.template Pop<uint64_t>(elementCount);
210 for (
SizeType i = 0; i < elementCount; i++)
212 *stack_.template Push<uint64_t>() = h;
220 return *stack_.template Top<uint64_t>();
224 static const size_t kDefaultSize = 256;
240 const unsigned char*
d =
static_cast<const unsigned char*
>(data);
241 for (
size_t i = 0; i < len; i++)
243 *stack_.template Push<uint64_t>() = h;
260 template <
typename SchemaDocumentType>
265 typedef typename ValueType::Ch
Ch;
270 kPatternValidatorWithAdditionalProperty
279 arrayElementHashCodes(),
282 patternPropertiesValidators(),
283 patternPropertiesValidatorCount(),
284 patternPropertiesSchemas(),
285 patternPropertiesSchemaCount(),
286 valuePatternValidatorType(kPatternValidatorOnly),
289 valueUniqueness(false),
290 arrayUniqueness(false)
296 factory.DestroryHasher(hasher);
298 for (
SizeType i = 0; i < validatorCount; i++)
299 factory.DestroySchemaValidator(validators[i]);
300 factory.FreeState(validators);
302 if (patternPropertiesValidators) {
303 for (
SizeType i = 0; i < patternPropertiesValidatorCount; i++)
304 factory.DestroySchemaValidator(patternPropertiesValidators[i]);
305 factory.FreeState(patternPropertiesValidators);
307 if (patternPropertiesSchemas)
308 factory.FreeState(patternPropertiesSchemas);
310 factory.FreeState(propertyExist);
337 template <
typename SchemaDocumentType>
340 typedef typename SchemaDocumentType::ValueType
ValueType;
344 typedef typename EncodingType::Ch
Ch;
350 Schema(SchemaDocumentType* schemaDocument,
const PointerType& p,
const ValueType&
value,
const ValueType& document, AllocatorType* allocator) :
356 type_((1 << kTotalSchemaType) - 1),
359 additionalPropertiesSchema_(),
360 patternProperties_(),
361 patternPropertyCount_(),
365 additionalProperties_(true),
368 hasSchemaDependencies_(),
369 additionalItemsSchema_(),
375 additionalItems_(true),
380 exclusiveMinimum_(false),
381 exclusiveMaximum_(false)
383 typedef typename SchemaDocumentType::ValueType
ValueType;
384 typedef typename ValueType::ConstValueIterator ConstValueIterator;
385 typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
387 if (!value.IsObject())
390 if (
const ValueType* v = GetMember(value, GetTypeString())) {
394 else if (v->IsArray())
395 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
399 if (
const ValueType* v = GetMember(value, GetEnumString()))
400 if (v->IsArray() && v->Size() > 0) {
402 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) {
404 char buffer[256 + 24];
406 EnumHasherType h(&hasherAllocator, 256);
408 enum_[enumCount_++] = h.GetHashCode();
412 if (schemaDocument) {
413 AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document);
414 AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document);
415 AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document);
418 if (
const ValueType* v = GetMember(value, GetNotString())) {
419 schemaDocument->CreateSchema(¬_, p.Append(GetNotString(),
allocator_), *v, document);
420 notValidatorIndex_ = validatorCount_;
426 const ValueType* properties = GetMember(value, GetPropertiesString());
427 const ValueType* required = GetMember(value, GetRequiredString());
428 const ValueType* dependencies = GetMember(value, GetDependenciesString());
433 if (properties && properties->IsObject())
434 for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr)
435 AddUniqueElement(allProperties, itr->name);
437 if (required && required->IsArray())
438 for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
440 AddUniqueElement(allProperties, *itr);
442 if (dependencies && dependencies->IsObject())
443 for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {
444 AddUniqueElement(allProperties, itr->name);
445 if (itr->value.IsArray())
446 for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i)
448 AddUniqueElement(allProperties, *i);
451 if (allProperties.Size() > 0) {
452 propertyCount_ = allProperties.Size();
454 for (
SizeType i = 0; i < propertyCount_; i++) {
456 properties_[i].
name = allProperties[i];
462 if (properties && properties->IsObject()) {
463 PointerType q = p.Append(GetPropertiesString(),
allocator_);
464 for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) {
466 if (FindPropertyIndex(itr->name, &index))
467 schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name,
allocator_), itr->value, document);
471 if (
const ValueType* v = GetMember(value, GetPatternPropertiesString())) {
472 PointerType q = p.Append(GetPatternPropertiesString(),
allocator_);
474 patternPropertyCount_ = 0;
476 for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {
478 patternProperties_[patternPropertyCount_].
pattern = CreatePattern(itr->name);
479 schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name,
allocator_), itr->value, document);
480 patternPropertyCount_++;
484 if (required && required->IsArray())
485 for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
486 if (itr->IsString()) {
488 if (FindPropertyIndex(*itr, &index)) {
489 properties_[index].required =
true;
494 if (dependencies && dependencies->IsObject()) {
495 PointerType q = p.Append(GetDependenciesString(),
allocator_);
496 hasDependencies_ =
true;
497 for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {
499 if (FindPropertyIndex(itr->name, &sourceIndex)) {
500 if (itr->value.IsArray()) {
501 properties_[sourceIndex].dependencies =
static_cast<bool*
>(
allocator_->Malloc(
sizeof(
bool) * propertyCount_));
502 std::memset(properties_[sourceIndex].dependencies, 0,
sizeof(
bool)* propertyCount_);
503 for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) {
505 if (FindPropertyIndex(*targetItr, &targetIndex))
506 properties_[sourceIndex].dependencies[targetIndex] =
true;
509 else if (itr->value.IsObject()) {
510 hasSchemaDependencies_ =
true;
511 schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name,
allocator_), itr->value, document);
512 properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_;
519 if (
const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) {
521 additionalProperties_ = v->GetBool();
522 else if (v->IsObject())
523 schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(),
allocator_), *v, document);
526 AssignIfExist(minProperties_, value, GetMinPropertiesString());
527 AssignIfExist(maxProperties_, value, GetMaxPropertiesString());
530 if (
const ValueType* v = GetMember(value, GetItemsString())) {
531 PointerType q = p.Append(GetItemsString(),
allocator_);
533 schemaDocument->CreateSchema(&itemsList_, q, *v, document);
534 else if (v->IsArray()) {
537 for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++)
538 schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index,
allocator_), *itr, document);
542 AssignIfExist(minItems_, value, GetMinItemsString());
543 AssignIfExist(maxItems_, value, GetMaxItemsString());
545 if (
const ValueType* v = GetMember(value, GetAdditionalItemsString())) {
547 additionalItems_ = v->GetBool();
548 else if (v->IsObject())
549 schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(),
allocator_), *v, document);
552 AssignIfExist(uniqueItems_, value, GetUniqueItemsString());
555 AssignIfExist(minLength_, value, GetMinLengthString());
556 AssignIfExist(maxLength_, value, GetMaxLengthString());
558 if (
const ValueType* v = GetMember(value, GetPatternString()))
559 pattern_ = CreatePattern(*v);
562 if (
const ValueType* v = GetMember(value, GetMinimumString()))
566 if (
const ValueType* v = GetMember(value, GetMaximumString()))
570 AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString());
571 AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString());
573 if (
const ValueType* v = GetMember(value, GetMultipleOfString()))
574 if (v->IsNumber() && v->GetDouble() > 0.0)
579 AllocatorType::Free(enum_);
581 for (
SizeType i = 0; i < propertyCount_; i++)
583 AllocatorType::Free(properties_);
585 if (patternProperties_) {
586 for (
SizeType i = 0; i < patternPropertyCount_; i++)
588 AllocatorType::Free(patternProperties_);
590 AllocatorType::Free(itemsTuple_);
591 #if RAPIDJSON_SCHEMA_HAS_REGEX 593 pattern_->~RegexType();
594 AllocatorType::Free(pattern_);
606 else if (itemsTuple_) {
609 else if (additionalItemsSchema_)
611 else if (additionalItems_)
624 RAPIDJSON_FORCEINLINE
bool EndValue(Context& context)
const {
626 bool otherValid =
false;
631 bool patternValid =
true;
632 for (
SizeType i = 0; i < count; i++)
634 patternValid =
false;
643 if (!patternValid || !otherValid)
646 else if (!patternValid && !otherValid)
652 for (
SizeType i = 0; i < enumCount_; i++)
660 for (
SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++)
664 if (anyOf_.schemas) {
665 for (
SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)
672 if (oneOf_.schemas) {
673 bool oneValid =
false;
674 for (
SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++)
691 bool Null(Context& context)
const {
692 if (!(type_ & (1 << kNullSchemaType)))
694 return CreateParallelValidator(context);
697 bool Bool(Context& context,
bool)
const {
698 if (!(type_ & (1 << kBooleanSchemaType)))
700 return CreateParallelValidator(context);
703 bool Int(Context& context,
int i)
const {
704 if (!CheckInt(context, i))
706 return CreateParallelValidator(context);
709 bool Uint(Context& context,
unsigned u)
const {
710 if (!CheckUint(context, u))
712 return CreateParallelValidator(context);
716 if (!CheckInt(context, i))
718 return CreateParallelValidator(context);
722 if (!CheckUint(context, u))
724 return CreateParallelValidator(context);
727 bool Double(Context& context,
double d)
const {
728 if (!(type_ & (1 << kNumberSchemaType)))
731 if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d))
734 if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d))
737 if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d))
740 return CreateParallelValidator(context);
744 if (!(type_ & (1 << kStringSchemaType)))
747 if (minLength_ != 0 || maxLength_ !=
SizeType(~0)) {
749 if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {
750 if (count < minLength_)
752 if (count > maxLength_)
757 if (pattern_ && !IsPatternMatch(pattern_, str, length))
760 return CreateParallelValidator(context);
764 if (!(type_ & (1 << kObjectSchemaType)))
767 if (hasDependencies_ || hasRequired_) {
769 std::memset(context.
propertyExist, 0,
sizeof(
bool) * propertyCount_);
772 if (patternProperties_) {
773 SizeType count = patternPropertyCount_ + 1;
779 return CreateParallelValidator(context);
782 bool Key(Context& context,
const Ch* str,
SizeType len,
bool)
const {
783 if (patternProperties_) {
785 for (
SizeType i = 0; i < patternPropertyCount_; i++)
786 if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) {
793 if (FindPropertyIndex(
ValueType(str, len).Move(), &index)) {
808 if (additionalPropertiesSchema_) {
818 else if (additionalProperties_) {
831 for (
SizeType index = 0; index < propertyCount_; index++)
832 if (properties_[index].required)
836 if (memberCount < minProperties_)
839 if (memberCount > maxProperties_)
842 if (hasDependencies_) {
843 for (
SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++)
845 if (properties_[sourceIndex].dependencies) {
846 for (
SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++)
847 if (properties_[sourceIndex].dependencies[targetIndex] && !context.
propertyExist[targetIndex])
850 else if (properties_[sourceIndex].dependenciesSchema)
851 if (!context.
validators[properties_[sourceIndex].dependenciesValidatorIndex]->
IsValid())
860 if (!(type_ & (1 << kArraySchemaType)))
866 return CreateParallelValidator(context);
872 if (elementCount < minItems_)
875 if (elementCount > maxItems_)
882 #define RAPIDJSON_STRING_(name, ...) \ 883 static const ValueType& Get##name##String() {\ 884 static const Ch s[] = { __VA_ARGS__, '\0' };\ 885 static const ValueType v(s, static_cast<SizeType>(sizeof(s) / sizeof(Ch) - 1));\ 902 RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
904 RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's')
905 RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
906 RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
907 RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
908 RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
912 RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's')
913 RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's')
919 RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm')
920 RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm')
921 RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f')
923 #undef RAPIDJSON_STRING_ 937 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 939 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 940 typedef std::basic_regex<Ch> RegexType;
942 typedef char RegexType;
953 template <
typename V1,
typename V2>
955 for (
typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
958 V1 c(v, *allocator_);
959 a.PushBack(c, *allocator_);
962 static const ValueType*
GetMember(
const ValueType&
value,
const ValueType& name) {
963 typename ValueType::ConstMemberIterator itr = value.FindMember(name);
964 return itr != value.MemberEnd() ? &(itr->value) : 0;
968 if (
const ValueType* v = GetMember(value, name))
974 if (
const ValueType* v = GetMember(value, name))
975 if (v->IsUint64() && v->GetUint64() <=
SizeType(~0))
976 out = static_cast<SizeType>(v->GetUint64());
979 void AssignIfExist(
SchemaArray& out, SchemaDocumentType& schemaDocument,
const PointerType& p,
const ValueType&
value,
const ValueType& name,
const ValueType& document) {
980 if (
const ValueType* v = GetMember(value, name)) {
981 if (v->IsArray() && v->Size() > 0) {
982 PointerType q = p.Append(name, allocator_);
983 out.
count = v->Size();
987 schemaDocument.CreateSchema(&out.
schemas[i], q.Append(i, allocator_), (*v)[i], document);
988 out.
begin = validatorCount_;
989 validatorCount_ += out.
count;
994 #if RAPIDJSON_SCHEMA_USE_INTERNALREGEX 995 template <
typename ValueType>
997 if (value.IsString()) {
998 RegexType* r =
new (allocator_->Malloc(
sizeof(RegexType))) RegexType(value.GetString());
1001 AllocatorType::Free(r);
1013 #elif RAPIDJSON_SCHEMA_USE_STDREGEX 1014 template <
typename ValueType>
1015 RegexType* CreatePattern(
const ValueType&
value) {
1016 if (value.IsString())
1018 return new (allocator_->Malloc(
sizeof(RegexType))) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);
1020 catch (
const std::regex_error&) {
1025 static bool IsPatternMatch(
const RegexType* pattern,
const Ch *str,
SizeType length) {
1026 std::match_results<const Ch*> r;
1027 return std::regex_search(str, str + length, r, *pattern);
1030 template <
typename ValueType>
1031 RegexType* CreatePattern(
const ValueType&) {
return 0; }
1033 static bool IsPatternMatch(
const RegexType*,
const Ch *,
SizeType) {
return true; }
1034 #endif // RAPIDJSON_SCHEMA_USE_STDREGEX 1037 if (type == GetNullString() ) type_ |= 1 << kNullSchemaType;
1038 else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType;
1039 else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType;
1040 else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType;
1041 else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType;
1042 else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType;
1043 else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
1050 if (validatorCount_) {
1056 CreateSchemaValidators(context, allOf_);
1059 CreateSchemaValidators(context, anyOf_);
1062 CreateSchemaValidators(context, oneOf_);
1067 if (hasSchemaDependencies_) {
1068 for (
SizeType i = 0; i < propertyCount_; i++)
1069 if (properties_[i].dependenciesSchema)
1084 SizeType len = name.GetStringLength();
1085 const Ch* str = name.GetString();
1086 for (
SizeType index = 0; index < propertyCount_; index++)
1087 if (properties_[index].name.GetStringLength() == len &&
1088 (std::memcmp(properties_[index].name.GetString(), str,
sizeof(Ch) * len) == 0))
1097 if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))
1100 if (!minimum_.IsNull()) {
1101 if (minimum_.IsInt64()) {
1102 if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64())
1105 else if (minimum_.IsUint64()) {
1108 else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1112 if (!maximum_.IsNull()) {
1113 if (maximum_.IsInt64()) {
1114 if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64())
1117 else if (maximum_.IsUint64()) { }
1119 else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1123 if (!multipleOf_.IsNull()) {
1124 if (multipleOf_.IsUint64()) {
1125 if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0)
1128 else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1136 if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))
1139 if (!minimum_.IsNull()) {
1140 if (minimum_.IsUint64()) {
1141 if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64())
1144 else if (minimum_.IsInt64())
1146 else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
1150 if (!maximum_.IsNull()) {
1151 if (maximum_.IsUint64()) {
1152 if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64())
1155 else if (maximum_.IsInt64())
1157 else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
1161 if (!multipleOf_.IsNull()) {
1162 if (multipleOf_.IsUint64()) {
1163 if (i % multipleOf_.GetUint64() != 0)
1166 else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
1174 if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble())
1180 if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble())
1186 double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());
1187 double q = std::floor(a / b);
1188 double r = a - q * b;
1195 Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {}
1209 pattern->~RegexType();
1210 AllocatorType::Free(pattern);
1261 template<
typename Stack,
typename Ch>
1264 *documentStack.template Push<Ch>() =
'/';
1266 size_t length =
static_cast<size_t>((
sizeof(
SizeType) == 4 ?
u32toa(index, buffer) :
u64toa(index, buffer)) - buffer);
1267 for (
size_t i = 0; i < length; i++)
1268 *documentStack.template Push<Ch>() =
static_cast<Ch
>(buffer[i]);
1273 template <
typename Stack>
1277 char *buffer = documentStack.template Push<char>(1 + 10);
1280 documentStack.template Pop<char>(
static_cast<size_t>(10 - (end - buffer)));
1283 char *buffer = documentStack.template Push<char>(1 + 20);
1286 documentStack.template Pop<char>(
static_cast<size_t>(20 - (end - buffer)));
1296 template <
typename SchemaDocumentType>
1299 typedef typename SchemaDocumentType::Ch
Ch;
1302 virtual const SchemaDocumentType* GetRemoteDocument(
const Ch* uri,
SizeType length) = 0;
1317 template <
typename ValueT,
typename Allocator = CrtAllocator>
1324 typedef typename EncodingType::Ch
Ch;
1328 template <
typename,
typename,
typename>
1339 explicit GenericSchemaDocument(
const ValueType& document, IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) :
1340 remoteProvider_(remoteProvider),
1341 allocator_(allocator),
1345 schemaMap_(allocator, kInitialSchemaMapSize),
1346 schemaRef_(allocator, kInitialSchemaRefSize)
1351 typeless_ =
static_cast<SchemaType*
>(allocator_->Malloc(
sizeof(SchemaType)));
1359 while (!schemaRef_.Empty()) {
1360 SchemaRefEntry* refEntry = schemaRef_.template Pop<SchemaRefEntry>(1);
1361 if (
const SchemaType*
s = GetSchema(refEntry->
target)) {
1366 if (!GetSchema(refEntry->
source)) {
1367 new (schemaMap_.template Push<SchemaEntry>())
SchemaEntry(refEntry->
source, const_cast<SchemaType*>(
s),
false, allocator_);
1370 else if (refEntry->
schema)
1371 *refEntry->
schema = typeless_;
1373 refEntry->~SchemaRefEntry();
1378 schemaRef_.ShrinkToFit();
1381 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 1384 remoteProvider_(rhs.remoteProvider_),
1385 allocator_(rhs.allocator_),
1386 ownAllocator_(rhs.ownAllocator_),
1388 typeless_(rhs.typeless_),
1389 schemaMap_(std::move(rhs.schemaMap_)),
1390 schemaRef_(std::move(rhs.schemaRef_))
1392 rhs.remoteProvider_ = 0;
1394 rhs.ownAllocator_ = 0;
1401 while (!schemaMap_.Empty())
1402 schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry();
1405 typeless_->~SchemaType();
1406 Allocator::Free(typeless_);
1422 SchemaRefEntry(
const PointerType& s,
const PointerType& t,
const SchemaType** outSchema, Allocator *allocator) :
source(s, allocator), target(t, allocator), schema(outSchema) {}
1429 SchemaEntry(
const PointerType& p, SchemaType* s,
bool o, Allocator* allocator) :
pointer(p, allocator), schema(s), owned(o) {}
1432 schema->~SchemaType();
1433 Allocator::Free(schema);
1443 *schema = typeless_;
1446 const SchemaType*
s = GetSchema(pointer);
1448 CreateSchema(schema, pointer, v, document);
1450 for (
typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
1451 CreateSchemaRecursive(0, pointer.
Append(itr->name, allocator_), itr->
value, document);
1454 for (
SizeType i = 0; i < v.Size(); i++)
1455 CreateSchemaRecursive(0, pointer.
Append(i, allocator_), v[i], document);
1458 void CreateSchema(
const SchemaType** schema,
const PointerType&
pointer,
const ValueType& v,
const ValueType& document) {
1461 if (!HandleRefSchema(pointer, schema, v, document)) {
1462 SchemaType*
s =
new (allocator_->Malloc(
sizeof(SchemaType))) SchemaType(
this, pointer, v, document, allocator_);
1463 new (schemaMap_.template Push<SchemaEntry>())
SchemaEntry(pointer, s,
true, allocator_);
1470 bool HandleRefSchema(
const PointerType&
source,
const SchemaType** schema,
const ValueType& v,
const ValueType& document) {
1471 static const Ch kRefString[] = {
'$',
'r',
'e',
'f',
'\0' };
1472 static const ValueType kRefValue(kRefString, 4);
1474 typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue);
1475 if (itr == v.MemberEnd())
1478 if (itr->value.IsString()) {
1479 SizeType len = itr->value.GetStringLength();
1481 const Ch*
s = itr->value.GetString();
1483 while (i < len && s[i] !=
'#')
1487 if (remoteProvider_) {
1489 PointerType
pointer(&s[i], len - i, allocator_);
1490 if (pointer.IsValid()) {
1491 if (
const SchemaType* sc = remoteDocument->GetSchema(pointer)) {
1500 else if (s[i] ==
'#') {
1501 PointerType
pointer(&s[i], len - i, allocator_);
1502 if (pointer.IsValid()) {
1503 if (
const ValueType* nv = pointer.Get(document))
1504 if (HandleRefSchema(source, schema, *nv, document))
1507 new (schemaRef_.template Push<SchemaRefEntry>())
SchemaRefEntry(source, pointer, schema, allocator_);
1517 for (
const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
1518 if (pointer == target->pointer)
1519 return target->schema;
1524 for (
const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
1525 if (schema == target->schema)
1526 return target->pointer;
1527 return PointerType();
1532 static const size_t kInitialSchemaMapSize = 64;
1533 static const size_t kInitialSchemaRefSize = 64;
1565 typename SchemaDocumentType,
1576 typedef typename EncodingType::Ch
Ch;
1586 const SchemaDocumentType& schemaDocument,
1587 StateAllocator* allocator = 0,
1588 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1589 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1591 schemaDocument_(&schemaDocument),
1592 root_(schemaDocument.GetRoot()),
1593 stateAllocator_(allocator),
1594 ownStateAllocator_(0),
1595 schemaStack_(allocator, schemaStackCapacity),
1596 documentStack_(allocator, documentStackCapacity),
1613 const SchemaDocumentType& schemaDocument,
1614 OutputHandler& outputHandler,
1615 StateAllocator* allocator = 0,
1616 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1617 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1619 schemaDocument_(&schemaDocument),
1620 root_(schemaDocument.GetRoot()),
1621 stateAllocator_(allocator),
1622 ownStateAllocator_(0),
1623 schemaStack_(allocator, schemaStackCapacity),
1624 documentStack_(allocator, documentStackCapacity),
1625 outputHandler_(&outputHandler),
1641 while (!schemaStack_.Empty())
1643 documentStack_.Clear();
1653 return schemaStack_.Empty() ? PointerType() : schemaDocument_->GetPointer(&CurrentSchema());
1658 return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword;
1663 return documentStack_.Empty() ? PointerType() : PointerType(documentStack_.template Bottom<Ch>(), documentStack_.GetSize() /
sizeof(Ch));
1666 #if RAPIDJSON_SCHEMA_VERBOSE 1667 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \ 1668 RAPIDJSON_MULTILINEMACRO_BEGIN\ 1669 *documentStack_.template Push<Ch>() = '\0';\ 1670 documentStack_.template Pop<Ch>(1);\ 1671 internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>());\ 1672 RAPIDJSON_MULTILINEMACRO_END 1674 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() 1677 #define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\ 1678 if (!valid_) return false; \ 1679 if (!BeginValue() || !CurrentSchema().method arg1) {\ 1680 RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\ 1681 return valid_ = false;\ 1684 #define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\ 1685 for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\ 1686 if (context->hasher)\ 1687 static_cast<HasherType*>(context->hasher)->method arg2;\ 1688 if (context->validators)\ 1689 for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\ 1690 static_cast<GenericSchemaValidator*>(context->validators[i_])->method arg2;\ 1691 if (context->patternPropertiesValidators)\ 1692 for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\ 1693 static_cast<GenericSchemaValidator*>(context->patternPropertiesValidators[i_])->method arg2;\ 1696 #define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\ 1697 return valid_ = EndValue() && (!outputHandler_ || outputHandler_->method arg2) 1699 #define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ 1700 RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\ 1701 RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\ 1702 RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2) 1719 return valid_ = !outputHandler_ || outputHandler_->StartObject();
1723 if (!valid_)
return false;
1724 AppendToken(str, len);
1725 if (!CurrentSchema().Key(CurrentContext(), str, len, copy))
return valid_ =
false;
1727 return valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy);
1731 if (!valid_)
return false;
1733 if (!CurrentSchema().EndObject(CurrentContext(), memberCount))
return valid_ =
false;
1740 return valid_ = !outputHandler_ || outputHandler_->StartArray();
1744 if (!valid_)
return false;
1746 if (!CurrentSchema().EndArray(CurrentContext(), elementCount))
return valid_ =
false;
1750 #undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_ 1751 #undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_ 1752 #undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ 1753 #undef RAPIDJSON_SCHEMA_HANDLE_VALUE_ 1761 &GetStateAllocator());
1767 StateAllocator::Free(v);
1775 return static_cast<HasherType*
>(hasher)->GetHashCode();
1781 StateAllocator::Free(h);
1785 return GetStateAllocator().Malloc(size);
1789 StateAllocator::Free(p);
1798 const SchemaDocumentType& schemaDocument,
1799 const SchemaType& root,
1803 StateAllocator* allocator = 0,
1804 size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
1805 size_t documentStackCapacity = kDefaultDocumentStackCapacity)
1807 schemaDocument_(&schemaDocument),
1809 stateAllocator_(allocator),
1810 ownStateAllocator_(0),
1811 schemaStack_(allocator, schemaStackCapacity),
1812 documentStack_(allocator, documentStackCapacity),
1822 if (!stateAllocator_)
1823 stateAllocator_ = ownStateAllocator_ =
RAPIDJSON_NEW(StateAllocator)();
1824 return *stateAllocator_;
1828 if (schemaStack_.Empty())
1831 if (CurrentContext().inArray)
1834 if (!CurrentSchema().BeginValue(CurrentContext()))
1837 SizeType count = CurrentContext().patternPropertiesSchemaCount;
1838 const SchemaType** sa = CurrentContext().patternPropertiesSchemas;
1839 typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
1840 bool valueUniqueness = CurrentContext().valueUniqueness;
1842 PushSchema(*CurrentContext().valueSchema);
1845 CurrentContext().objectPatternValidatorType = patternValidatorType;
1846 ISchemaValidator**& va = CurrentContext().patternPropertiesValidators;
1847 SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount;
1848 va =
static_cast<ISchemaValidator**
>(MallocState(
sizeof(ISchemaValidator*) * count));
1849 for (
SizeType i = 0; i < count; i++)
1850 va[validatorCount++] = CreateSchemaValidator(*sa[i]);
1853 CurrentContext().arrayUniqueness = valueUniqueness;
1859 if (!CurrentSchema().EndValue(CurrentContext()))
1862 #if RAPIDJSON_SCHEMA_VERBOSE 1864 schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb);
1866 *documentStack_.template Push<Ch>() =
'\0';
1867 documentStack_.template Pop<Ch>(1);
1868 internal::PrintValidatorPointers(depth_, sb.
GetString(), documentStack_.template Bottom<Ch>());
1871 uint64_t h = CurrentContext().arrayUniqueness ?
static_cast<HasherType*
>(CurrentContext().hasher)->GetHashCode() : 0;
1875 if (!schemaStack_.Empty()) {
1876 Context& context = CurrentContext();
1877 if (context.valueUniqueness) {
1878 HashCodeArray*
a =
static_cast<HashCodeArray*
>(context.arrayElementHashCodes);
1880 CurrentContext().arrayElementHashCodes = a =
new (GetStateAllocator().Malloc(
sizeof(HashCodeArray))) HashCodeArray(
kArrayType);
1882 if (itr->GetUint64() == h)
1884 a->PushBack(h, GetStateAllocator());
1889 while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) !=
'/')
1896 documentStack_.template Reserve<Ch>(1 + len * 2);
1897 *documentStack_.template PushUnsafe<Ch>() =
'/';
1898 for (
SizeType i = 0; i < len; i++) {
1899 if (str[i] ==
'~') {
1900 *documentStack_.template PushUnsafe<Ch>() =
'~';
1901 *documentStack_.template PushUnsafe<Ch>() =
'0';
1903 else if (str[i] ==
'/') {
1904 *documentStack_.template PushUnsafe<Ch>() =
'~';
1905 *documentStack_.template PushUnsafe<Ch>() =
'1';
1908 *documentStack_.template PushUnsafe<Ch>() = str[i];
1912 RAPIDJSON_FORCEINLINE
void PushSchema(
const SchemaType& schema) {
new (schemaStack_.template Push<Context>()) Context(*
this, &schema); }
1915 Context* c = schemaStack_.template Pop<Context>(1);
1916 if (HashCodeArray*
a = static_cast<HashCodeArray*>(c->arrayElementHashCodes)) {
1917 a->~HashCodeArray();
1918 StateAllocator::Free(
a);
1923 const SchemaType&
CurrentSchema()
const {
return *schemaStack_.template Top<Context>()->schema; }
1925 const Context&
CurrentContext()
const {
return *schemaStack_.template Top<Context>(); }
1927 static const size_t kDefaultSchemaStackCapacity = 1024;
1928 static const size_t kDefaultDocumentStackCapacity = 256;
1937 #if RAPIDJSON_SCHEMA_VERBOSE 1958 unsigned parseFlags,
1959 typename InputStream,
1960 typename SourceEncoding,
1966 typedef typename InputStream::Ch
Ch;
1973 SchemaValidatingReader(InputStream& is,
const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), isValid_(true) {}
1975 template <
typename Handler>
1979 parseResult_ = reader.template Parse<parseFlags>(is_, validator);
1981 isValid_ = validator.
IsValid();
1983 invalidSchemaPointer_ = PointerType();
1984 invalidSchemaKeyword_ = 0;
1985 invalidDocumentPointer_ = PointerType();
1993 return parseResult_;
2004 const SchemaDocumentType&
sd_;
2016 #endif // RAPIDJSON_SCHEMA_H_
bool Key(Context &context, const Ch *str, SizeType len, bool) const
SchemaDocumentType::Ch Ch
char * u64toa(uint64_t value, char *buffer)
Allocator * ownAllocator_
const CharType(& source)[N]
SizeType patternPropertyCount_
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.
PointerType invalidDocumentPointer_
const Ch * invalidSchemaKeyword_
PointerType invalidSchemaPointer_
AllocatorType * allocator_
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)
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
GenericSchemaDocument(const ValueType &document, IRemoteSchemaDocumentProviderType *remoteProvider=0, Allocator *allocator=0)
Constructor.
Schema< SchemaDocumentType > SchemaType
void AddUniqueElement(V1 &a, const V2 &v)
Schema< SchemaDocumentType > SchemaType
PatternValidatorType objectPatternValidatorType
const SchemaType * typeless_
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
PatternProperty * patternProperties_
virtual void FreeState(void *p)
StateAllocator * stateAllocator_
SchemaDocumentType::PointerType PointerType
SchemaDocumentType::SchemaType SchemaType
~GenericSchemaValidator()
Destructor.
const SchemaType * additionalItemsSchema_
#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2)
void AppendToken(const Ch *str, SizeType len)
Stack< Allocator > stack_
virtual ~IGenericRemoteSchemaDocumentProvider()
bool String(const Ch *str, SizeType length, bool copy)
A type-unsafe stack for storing different types of data.
SchemaValidatingReader(InputStream &is, const SchemaDocumentType &sd)
Constructor.
SchemaType::EncodingType EncodingType
bool EndArray(SizeType elementCount)
PatternValidatorType valuePatternValidatorType
internal::Stack< Allocator > schemaRef_
const SchemaType * dependenciesSchema
void * arrayElementHashCodes
StateAllocator * ownStateAllocator_
const SchemaType * GetTypeless() const
SizeType notValidatorIndex_
IRemoteSchemaDocumentProviderType * remoteProvider_
bool EndArray(SizeType elementCount)
bool EndObject(Context &context, SizeType memberCount) const
bool BeginValue(Context &context) const
static const ValueType * GetMember(const ValueType &value, const ValueType &name)
bool Key(const Ch *str, SizeType len, bool copy)
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.
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
RAPIDJSON_FORCEINLINE void PopSchema()
void Reset()
Reset the internal states.
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, const SchemaType &root, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
#define RAPIDJSON_STRING_(name,...)
bool CreateParallelValidator(Context &context) const
ISchemaValidator ** patternPropertiesValidators
bool WriteBuffer(Type type, const void *data, size_t len)
GenericValue< EncodingType, AllocatorType > SValue
ISchemaValidator ** validators
ValueType::EncodingType EncodingType
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
SizeType dependenciesValidatorIndex
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
~SchemaValidationContext()
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
bool Uint64(Context &context, uint64_t u) const
virtual ISchemaValidator * CreateSchemaValidator(const SchemaType &)=0
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
const SchemaType * additionalPropertiesSchema_
SchemaDocumentType::PointerType PointerType
GenericSchemaValidator(const SchemaDocumentType &schemaDocument, OutputHandler &outputHandler, StateAllocator *allocator=0, size_t schemaStackCapacity=kDefaultSchemaStackCapacity, size_t documentStackCapacity=kDefaultDocumentStackCapacity)
Constructor with output handler.
PointerType GetPointer(const SchemaType *schema) const
OutputHandler * outputHandler_
SchemaValidationContext< SchemaDocumentType > Context
SizeType patternPropertiesValidatorCount
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
const PointerType & GetInvalidSchemaPointer() const
bool Int(Context &context, int i) const
const SchemaDocumentType * schemaDocument_
bool Key(const Ch *str, SizeType len, bool copy)
internal::Hasher< EncodingType, StateAllocator > HasherType
virtual ~ISchemaValidator()
Context & CurrentContext()
unsigned __int64 uint64_t
bool CheckDoubleMaximum(Context &context, double d) const
const ParseResult & GetParseResult() const
virtual void * MallocState(size_t size)
const PointerType & GetInvalidDocumentPointer() const
void CreateSchemaValidators(Context &context, const SchemaArray &schemas) const
PointerType GetInvalidSchemaPointer() const
Gets the JSON pointer pointed to the invalid schema.
#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)
const SchemaDocumentType & sd_
GenericSchemaDocument< Value > SchemaDocument
GenericSchemaDocument using Value type.
bool Double(Context &context, double d) const
#define RAPIDJSON_SCHEMA_VERBOSE
bool CheckInt(Context &context, int64_t i) const
#define RAPIDJSON_DELETE(x)
! customization point for global delete
SchemaEntry(const PointerType &p, SchemaType *s, bool o, Allocator *allocator)
char * u32toa(uint32_t value, char *buffer)
SchemaValidationContext(SchemaValidatorFactoryType &f, const SchemaType *s)
bool CheckDoubleMinimum(Context &context, double d) const
ISchemaStateFactory< SchemaType > SchemaValidatorFactoryType
#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)
#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)
virtual void * CreateHasher()
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
const Ch * invalidKeyword
bool Search(InputStream &is)
static uint64_t Hash(uint64_t h, uint64_t d)
virtual ~ISchemaStateFactory()
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.
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
GenericValue< UTF8<>, StateAllocator > HashCodeArray
SchemaType::Context Context
Schema(SchemaDocumentType *schemaDocument, const PointerType &p, const ValueType &value, const ValueType &document, AllocatorType *allocator)
bool StartObject(Context &context) const
const SchemaType & GetRoot() const
Get the root schema.
union internal::Hasher::Number::U u
internal::Stack< Allocator > schemaMap_
IGenericRemoteSchemaDocumentProvider< SchemaDocument > IRemoteSchemaDocumentProvider
IGenericRemoteSchemaDocumentProvider using SchemaDocument.
const SchemaType * schema
const SchemaType * root_
Root schema.
virtual void * MallocState(size_t size)=0
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
bool StartArray(Context &context) const
bool Null(Context &context) const
bool EndArray(Context &context, SizeType elementCount) const
bool FindPropertyIndex(const ValueType &name, SizeType *outIndex) const
const SchemaType ** schema
const SchemaType & CurrentSchema() const
internal::GenericRegex< EncodingType > RegexType
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
RAPIDJSON_FORCEINLINE bool EndValue(Context &context) const
virtual uint64_t GetHashCode(void *hasher)
RegexType * CreatePattern(const ValueType &value)
bool RawNumber(const Ch *str, SizeType length, bool copy)
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)
SizeType patternPropertiesSchemaCount
static RAPIDJSON_FORCEINLINE void AppendIndexToken(Stack &documentStack, SizeType index)
#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)
virtual void DestroryHasher(void *hasher)
RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType &schema)
bool Uint(Context &context, unsigned u) const
void AddType(const ValueType &type)
bool Bool(Context &context, bool) const
bool EndObject(SizeType memberCount)
virtual ISchemaValidator * CreateSchemaValidator(const SchemaType &root)
const Context & CurrentContext() const
GenericPointer< ValueType, Allocator > PointerType