Commit 1f754027 authored by Yuri Khan's avatar Yuri Khan

refactor Schema: Keep ErrorHandler reference in Context

parent a4b62ff6
...@@ -318,6 +318,7 @@ template <typename SchemaDocumentType> ...@@ -318,6 +318,7 @@ template <typename SchemaDocumentType>
struct SchemaValidationContext { struct SchemaValidationContext {
typedef Schema<SchemaDocumentType> SchemaType; typedef Schema<SchemaDocumentType> SchemaType;
typedef ISchemaStateFactory<SchemaType> SchemaValidatorFactoryType; typedef ISchemaStateFactory<SchemaType> SchemaValidatorFactoryType;
typedef IValidationErrorHandler<SchemaType> ErrorHandlerType;
typedef typename SchemaType::ValueType ValueType; typedef typename SchemaType::ValueType ValueType;
typedef typename ValueType::Ch Ch; typedef typename ValueType::Ch Ch;
...@@ -327,8 +328,9 @@ struct SchemaValidationContext { ...@@ -327,8 +328,9 @@ struct SchemaValidationContext {
kPatternValidatorWithAdditionalProperty kPatternValidatorWithAdditionalProperty
}; };
SchemaValidationContext(SchemaValidatorFactoryType& f, const SchemaType* s) : SchemaValidationContext(SchemaValidatorFactoryType& f, ErrorHandlerType& eh, const SchemaType* s) :
factory(f), factory(f),
error_handler(eh),
schema(s), schema(s),
valueSchema(), valueSchema(),
invalidKeyword(), invalidKeyword(),
...@@ -368,6 +370,7 @@ struct SchemaValidationContext { ...@@ -368,6 +370,7 @@ struct SchemaValidationContext {
} }
SchemaValidatorFactoryType& factory; SchemaValidatorFactoryType& factory;
ErrorHandlerType& error_handler;
const SchemaType* schema; const SchemaType* schema;
const SchemaType* valueSchema; const SchemaType* valueSchema;
const Ch* invalidKeyword; const Ch* invalidKeyword;
...@@ -664,7 +667,7 @@ public: ...@@ -664,7 +667,7 @@ public:
return pointer_; return pointer_;
} }
bool BeginValue(Context& context, ErrorHandler& eh) const { bool BeginValue(Context& context) const {
if (context.inArray) { if (context.inArray) {
if (uniqueItems_) if (uniqueItems_)
context.valueUniqueness = true; context.valueUniqueness = true;
...@@ -679,7 +682,7 @@ public: ...@@ -679,7 +682,7 @@ public:
else if (additionalItems_) else if (additionalItems_)
context.valueSchema = typeless_; context.valueSchema = typeless_;
else { else {
eh.DisallowedItem(context.arrayElementIndex); context.error_handler.DisallowedItem(context.arrayElementIndex);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString());
} }
} }
...@@ -691,7 +694,7 @@ public: ...@@ -691,7 +694,7 @@ public:
return true; return true;
} }
RAPIDJSON_FORCEINLINE bool EndValue(Context& context, ErrorHandler& eh) const { RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const {
if (context.patternPropertiesValidatorCount > 0) { if (context.patternPropertiesValidatorCount > 0) {
bool otherValid = false; bool otherValid = false;
SizeType count = context.patternPropertiesValidatorCount; SizeType count = context.patternPropertiesValidatorCount;
...@@ -707,18 +710,18 @@ public: ...@@ -707,18 +710,18 @@ public:
if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) { if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) {
if (!patternValid) { if (!patternValid) {
eh.PropertyViolations(context.patternPropertiesValidators, count); context.error_handler.PropertyViolations(context.patternPropertiesValidators, count);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
} }
} }
else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) { else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) {
if (!patternValid || !otherValid) { if (!patternValid || !otherValid) {
eh.PropertyViolations(context.patternPropertiesValidators, count + 1); context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
} }
} }
else if (!patternValid && !otherValid) { // kPatternValidatorWithAdditionalProperty) else if (!patternValid && !otherValid) { // kPatternValidatorWithAdditionalProperty)
eh.PropertyViolations(context.patternPropertiesValidators, count + 1); context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
} }
} }
...@@ -728,7 +731,7 @@ public: ...@@ -728,7 +731,7 @@ public:
for (SizeType i = 0; i < enumCount_; i++) for (SizeType i = 0; i < enumCount_; i++)
if (enum_[i] == h) if (enum_[i] == h)
goto foundEnum; goto foundEnum;
eh.DisallowedValue(); context.error_handler.DisallowedValue();
RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString());
foundEnum:; foundEnum:;
} }
...@@ -736,7 +739,7 @@ public: ...@@ -736,7 +739,7 @@ public:
if (allOf_.schemas) if (allOf_.schemas)
for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++) for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++)
if (!context.validators[i]->IsValid()) { if (!context.validators[i]->IsValid()) {
eh.NotAllOf(&context.validators[allOf_.begin], allOf_.count); context.error_handler.NotAllOf(&context.validators[allOf_.begin], allOf_.count);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString());
} }
...@@ -744,7 +747,7 @@ public: ...@@ -744,7 +747,7 @@ public:
for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++) for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)
if (context.validators[i]->IsValid()) if (context.validators[i]->IsValid())
goto foundAny; goto foundAny;
eh.NoneOf(&context.validators[anyOf_.begin], anyOf_.count); context.error_handler.NoneOf(&context.validators[anyOf_.begin], anyOf_.count);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString());
foundAny:; foundAny:;
} }
...@@ -754,86 +757,86 @@ public: ...@@ -754,86 +757,86 @@ public:
for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++) for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++)
if (context.validators[i]->IsValid()) { if (context.validators[i]->IsValid()) {
if (oneValid) { if (oneValid) {
eh.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count); context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());
} else } else
oneValid = true; oneValid = true;
} }
if (!oneValid) { if (!oneValid) {
eh.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count); context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());
} }
} }
if (not_ && context.validators[notValidatorIndex_]->IsValid()) { if (not_ && context.validators[notValidatorIndex_]->IsValid()) {
eh.Disallowed(); context.error_handler.Disallowed();
RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString());
} }
return true; return true;
} }
bool Null(Context& context, ErrorHandler& eh) const { bool Null(Context& context) const {
if (!(type_ & (1 << kNullSchemaType))) { if (!(type_ & (1 << kNullSchemaType))) {
DisallowedType(eh, GetNullString()); DisallowedType(context, GetNullString());
RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
} }
return CreateParallelValidator(context); return CreateParallelValidator(context);
} }
bool Bool(Context& context, ErrorHandler& eh, bool) const { bool Bool(Context& context, bool) const {
if (!(type_ & (1 << kBooleanSchemaType))) { if (!(type_ & (1 << kBooleanSchemaType))) {
DisallowedType(eh, GetBooleanString()); DisallowedType(context, GetBooleanString());
RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
} }
return CreateParallelValidator(context); return CreateParallelValidator(context);
} }
bool Int(Context& context, ErrorHandler& eh, int i) const { bool Int(Context& context, int i) const {
if (!CheckInt(context, eh, i)) if (!CheckInt(context, i))
return false; return false;
return CreateParallelValidator(context); return CreateParallelValidator(context);
} }
bool Uint(Context& context, ErrorHandler& eh, unsigned u) const { bool Uint(Context& context, unsigned u) const {
if (!CheckUint(context, eh, u)) if (!CheckUint(context, u))
return false; return false;
return CreateParallelValidator(context); return CreateParallelValidator(context);
} }
bool Int64(Context& context, ErrorHandler& eh, int64_t i) const { bool Int64(Context& context, int64_t i) const {
if (!CheckInt(context, eh, i)) if (!CheckInt(context, i))
return false; return false;
return CreateParallelValidator(context); return CreateParallelValidator(context);
} }
bool Uint64(Context& context, ErrorHandler& eh, uint64_t u) const { bool Uint64(Context& context, uint64_t u) const {
if (!CheckUint(context, eh, u)) if (!CheckUint(context, u))
return false; return false;
return CreateParallelValidator(context); return CreateParallelValidator(context);
} }
bool Double(Context& context, ErrorHandler& eh, double d) const { bool Double(Context& context, double d) const {
if (!(type_ & (1 << kNumberSchemaType))) { if (!(type_ & (1 << kNumberSchemaType))) {
DisallowedType(eh, GetNumberString()); DisallowedType(context, GetNumberString());
RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
} }
if (!minimum_.IsNull() && !CheckDoubleMinimum(context, eh, d)) if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d))
return false; return false;
if (!maximum_.IsNull() && !CheckDoubleMaximum(context, eh, d)) if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d))
return false; return false;
if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, eh, d)) if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d))
return false; return false;
return CreateParallelValidator(context); return CreateParallelValidator(context);
} }
bool String(Context& context, ErrorHandler& eh, const Ch* str, SizeType length, bool) const { bool String(Context& context, const Ch* str, SizeType length, bool) const {
if (!(type_ & (1 << kStringSchemaType))) { if (!(type_ & (1 << kStringSchemaType))) {
DisallowedType(eh, GetStringString()); DisallowedType(context, GetStringString());
RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
} }
...@@ -841,27 +844,27 @@ public: ...@@ -841,27 +844,27 @@ public:
SizeType count; SizeType count;
if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) { if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {
if (count < minLength_) { if (count < minLength_) {
eh.TooShort(str, length, minLength_); context.error_handler.TooShort(str, length, minLength_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString());
} }
if (count > maxLength_) { if (count > maxLength_) {
eh.TooLong(str, length, maxLength_); context.error_handler.TooLong(str, length, maxLength_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString());
} }
} }
} }
if (pattern_ && !IsPatternMatch(pattern_, str, length)) { if (pattern_ && !IsPatternMatch(pattern_, str, length)) {
eh.DoesNotMatch(str, length); context.error_handler.DoesNotMatch(str, length);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString());
} }
return CreateParallelValidator(context); return CreateParallelValidator(context);
} }
bool StartObject(Context& context, ErrorHandler& eh) const { bool StartObject(Context& context) const {
if (!(type_ & (1 << kObjectSchemaType))) { if (!(type_ & (1 << kObjectSchemaType))) {
DisallowedType(eh, GetObjectString()); DisallowedType(context, GetObjectString());
RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
} }
...@@ -880,7 +883,7 @@ public: ...@@ -880,7 +883,7 @@ public:
return CreateParallelValidator(context); return CreateParallelValidator(context);
} }
bool Key(Context& context, ErrorHandler& eh, const Ch* str, SizeType len, bool) const { bool Key(Context& context, const Ch* str, SizeType len, bool) const {
if (patternProperties_) { if (patternProperties_) {
context.patternPropertiesSchemaCount = 0; context.patternPropertiesSchemaCount = 0;
for (SizeType i = 0; i < patternPropertyCount_; i++) for (SizeType i = 0; i < patternPropertyCount_; i++)
...@@ -922,62 +925,62 @@ public: ...@@ -922,62 +925,62 @@ public:
} }
if (context.patternPropertiesSchemaCount == 0) { // patternProperties are not additional properties if (context.patternPropertiesSchemaCount == 0) { // patternProperties are not additional properties
eh.DisallowedProperty(str, len); context.error_handler.DisallowedProperty(str, len);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString());
} }
return true; return true;
} }
bool EndObject(Context& context, ErrorHandler& eh, SizeType memberCount) const { bool EndObject(Context& context, SizeType memberCount) const {
if (hasRequired_) { if (hasRequired_) {
eh.StartMissingProperties(); context.error_handler.StartMissingProperties();
for (SizeType index = 0; index < propertyCount_; index++) for (SizeType index = 0; index < propertyCount_; index++)
if (properties_[index].required && !context.propertyExist[index]) if (properties_[index].required && !context.propertyExist[index])
eh.AddMissingProperty(properties_[index].name); context.error_handler.AddMissingProperty(properties_[index].name);
if (eh.EndMissingProperties()) if (context.error_handler.EndMissingProperties())
RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString());
} }
if (memberCount < minProperties_) { if (memberCount < minProperties_) {
eh.TooFewProperties(memberCount, minProperties_); context.error_handler.TooFewProperties(memberCount, minProperties_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString());
} }
if (memberCount > maxProperties_) { if (memberCount > maxProperties_) {
eh.TooManyProperties(memberCount, maxProperties_); context.error_handler.TooManyProperties(memberCount, maxProperties_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString());
} }
if (hasDependencies_) { if (hasDependencies_) {
eh.StartDependencyErrors(); context.error_handler.StartDependencyErrors();
for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) { for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) {
const Property& source = properties_[sourceIndex]; const Property& source = properties_[sourceIndex];
if (context.propertyExist[sourceIndex]) { if (context.propertyExist[sourceIndex]) {
if (source.dependencies) { if (source.dependencies) {
eh.StartMissingDependentProperties(); context.error_handler.StartMissingDependentProperties();
for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++) for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++)
if (source.dependencies[targetIndex] && !context.propertyExist[targetIndex]) if (source.dependencies[targetIndex] && !context.propertyExist[targetIndex])
eh.AddMissingDependentProperty(properties_[targetIndex].name); context.error_handler.AddMissingDependentProperty(properties_[targetIndex].name);
eh.EndMissingDependentProperties(source.name); context.error_handler.EndMissingDependentProperties(source.name);
} }
else if (source.dependenciesSchema) { else if (source.dependenciesSchema) {
ISchemaValidator* dependenciesValidator = context.validators[source.dependenciesValidatorIndex]; ISchemaValidator* dependenciesValidator = context.validators[source.dependenciesValidatorIndex];
if (!dependenciesValidator->IsValid()) if (!dependenciesValidator->IsValid())
eh.AddDependencySchemaError(source.name, dependenciesValidator); context.error_handler.AddDependencySchemaError(source.name, dependenciesValidator);
} }
} }
} }
if (eh.EndDependencyErrors()) if (context.error_handler.EndDependencyErrors())
RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString());
} }
return true; return true;
} }
bool StartArray(Context& context, ErrorHandler& eh) const { bool StartArray(Context& context) const {
if (!(type_ & (1 << kArraySchemaType))) { if (!(type_ & (1 << kArraySchemaType))) {
DisallowedType(eh, GetArrayString()); DisallowedType(context, GetArrayString());
RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
} }
...@@ -987,16 +990,16 @@ public: ...@@ -987,16 +990,16 @@ public:
return CreateParallelValidator(context); return CreateParallelValidator(context);
} }
bool EndArray(Context& context, ErrorHandler& eh, SizeType elementCount) const { bool EndArray(Context& context, SizeType elementCount) const {
context.inArray = false; context.inArray = false;
if (elementCount < minItems_) { if (elementCount < minItems_) {
eh.TooFewItems(elementCount, minItems_); context.error_handler.TooFewItems(elementCount, minItems_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString());
} }
if (elementCount > maxItems_) { if (elementCount > maxItems_) {
eh.TooManyItems(elementCount, maxItems_); context.error_handler.TooManyItems(elementCount, maxItems_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString());
} }
...@@ -1218,130 +1221,131 @@ private: ...@@ -1218,130 +1221,131 @@ private:
return false; return false;
} }
bool CheckInt(Context& context, ErrorHandler& eh, int64_t i) const { bool CheckInt(Context& context, int64_t i) const {
if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) { if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) {
DisallowedType(eh, GetIntegerString()); DisallowedType(context, GetIntegerString());
RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
} }
if (!minimum_.IsNull()) { if (!minimum_.IsNull()) {
if (minimum_.IsInt64()) { if (minimum_.IsInt64()) {
if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) { if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) {
eh.BelowMinimum(i, minimum_, exclusiveMinimum_); context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
} }
} }
else if (minimum_.IsUint64()) { else if (minimum_.IsUint64()) {
eh.BelowMinimum(i, minimum_, exclusiveMinimum_); context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64() RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64()
} }
else if (!CheckDoubleMinimum(context, eh, static_cast<double>(i))) else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
return false; return false;
} }
if (!maximum_.IsNull()) { if (!maximum_.IsNull()) {
if (maximum_.IsInt64()) { if (maximum_.IsInt64()) {
if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) { if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) {
eh.AboveMaximum(i, maximum_, exclusiveMaximum_); context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
} }
} }
else if (maximum_.IsUint64()) { } else if (maximum_.IsUint64()) { }
/* do nothing */ // i <= max(int64_t) < maximum_.GetUint64() /* do nothing */ // i <= max(int64_t) < maximum_.GetUint64()
else if (!CheckDoubleMaximum(context, eh, static_cast<double>(i))) else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
return false; return false;
} }
if (!multipleOf_.IsNull()) { if (!multipleOf_.IsNull()) {
if (multipleOf_.IsUint64()) { if (multipleOf_.IsUint64()) {
if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) { if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) {
eh.NotMultipleOf(i, multipleOf_); context.error_handler.NotMultipleOf(i, multipleOf_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
} }
} }
else if (!CheckDoubleMultipleOf(context, eh, static_cast<double>(i))) else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
return false; return false;
} }
return true; return true;
} }
bool CheckUint(Context& context, ErrorHandler& eh, uint64_t i) const { bool CheckUint(Context& context, uint64_t i) const {
if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) { if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) {
DisallowedType(eh, GetIntegerString()); DisallowedType(context, GetIntegerString());
RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
} }
if (!minimum_.IsNull()) { if (!minimum_.IsNull()) {
if (minimum_.IsUint64()) { if (minimum_.IsUint64()) {
if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) { if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) {
eh.BelowMinimum(i, minimum_, exclusiveMinimum_); context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
} }
} }
else if (minimum_.IsInt64()) else if (minimum_.IsInt64())
/* do nothing */; // i >= 0 > minimum.Getint64() /* do nothing */; // i >= 0 > minimum.Getint64()
else if (!CheckDoubleMinimum(context, eh, static_cast<double>(i))) else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
return false; return false;
} }
if (!maximum_.IsNull()) { if (!maximum_.IsNull()) {
if (maximum_.IsUint64()) { if (maximum_.IsUint64()) {
if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) { if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) {
eh.AboveMaximum(i, maximum_, exclusiveMaximum_); context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
} }
} }
else if (maximum_.IsInt64()) { else if (maximum_.IsInt64()) {
eh.AboveMaximum(i, maximum_, exclusiveMaximum_); context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_ RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_
} }
else if (!CheckDoubleMaximum(context, eh, static_cast<double>(i))) else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
return false; return false;
} }
if (!multipleOf_.IsNull()) { if (!multipleOf_.IsNull()) {
if (multipleOf_.IsUint64()) { if (multipleOf_.IsUint64()) {
if (i % multipleOf_.GetUint64() != 0) { if (i % multipleOf_.GetUint64() != 0) {
eh.NotMultipleOf(i, multipleOf_); context.error_handler.NotMultipleOf(i, multipleOf_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
} }
} }
else if (!CheckDoubleMultipleOf(context, eh, static_cast<double>(i))) else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
return false; return false;
} }
return true; return true;
} }
bool CheckDoubleMinimum(Context& context, ErrorHandler& eh, double d) const { bool CheckDoubleMinimum(Context& context, double d) const {
if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) { if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) {
eh.BelowMinimum(d, minimum_, exclusiveMinimum_); context.error_handler.BelowMinimum(d, minimum_, exclusiveMinimum_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
} }
return true; return true;
} }
bool CheckDoubleMaximum(Context& context, ErrorHandler& eh, double d) const { bool CheckDoubleMaximum(Context& context, double d) const {
if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) { if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) {
eh.AboveMaximum(d, maximum_, exclusiveMaximum_); context.error_handler.AboveMaximum(d, maximum_, exclusiveMaximum_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
} }
return true; return true;
} }
bool CheckDoubleMultipleOf(Context& context, ErrorHandler& eh, double d) const { bool CheckDoubleMultipleOf(Context& context, double d) const {
double a = std::abs(d), b = std::abs(multipleOf_.GetDouble()); double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());
double q = std::floor(a / b); double q = std::floor(a / b);
double r = a - q * b; double r = a - q * b;
if (r > 0.0) { if (r > 0.0) {
eh.NotMultipleOf(d, multipleOf_); context.error_handler.NotMultipleOf(d, multipleOf_);
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
} }
return true; return true;
} }
void DisallowedType(ErrorHandler& eh, const ValueType& actualType) const { void DisallowedType(Context& context, const ValueType& actualType) const {
ErrorHandler& eh = context.error_handler;
eh.StartDisallowedType(); eh.StartDisallowedType();
if (type_ & (1 << kNullSchemaType)) eh.AddExpectedType(GetNullString()); if (type_ & (1 << kNullSchemaType)) eh.AddExpectedType(GetNullString());
...@@ -2076,20 +2080,20 @@ RAPIDJSON_MULTILINEMACRO_END ...@@ -2076,20 +2080,20 @@ RAPIDJSON_MULTILINEMACRO_END
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\ RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\
RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2) RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2)
bool Null() { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null, (CurrentContext(), *this), ( )); } bool Null() { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null, (CurrentContext()), ( )); }
bool Bool(bool b) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool, (CurrentContext(), *this, b), (b)); } bool Bool(bool b) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool, (CurrentContext(), b), (b)); }
bool Int(int i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), *this, i), (i)); } bool Int(int i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), i), (i)); }
bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), *this, u), (u)); } bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); }
bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), *this, i), (i)); } bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); }
bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), *this, u), (u)); } bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); }
bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), *this, d), (d)); } bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); }
bool RawNumber(const Ch* str, SizeType length, bool copy) bool RawNumber(const Ch* str, SizeType length, bool copy)
{ RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), *this, str, length, copy), (str, length, copy)); } { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }
bool String(const Ch* str, SizeType length, bool copy) bool String(const Ch* str, SizeType length, bool copy)
{ RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), *this, str, length, copy), (str, length, copy)); } { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }
bool StartObject() { bool StartObject() {
RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext(), *this)); RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext()));
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ()); RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ());
return valid_ = !outputHandler_ || outputHandler_->StartObject(); return valid_ = !outputHandler_ || outputHandler_->StartObject();
} }
...@@ -2097,7 +2101,7 @@ RAPIDJSON_MULTILINEMACRO_END ...@@ -2097,7 +2101,7 @@ RAPIDJSON_MULTILINEMACRO_END
bool Key(const Ch* str, SizeType len, bool copy) { bool Key(const Ch* str, SizeType len, bool copy) {
if (!valid_) return false; if (!valid_) return false;
AppendToken(str, len); AppendToken(str, len);
if (!CurrentSchema().Key(CurrentContext(), *this, str, len, copy)) return valid_ = false; if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false;
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy)); RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy));
return valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy); return valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy);
} }
...@@ -2105,12 +2109,12 @@ RAPIDJSON_MULTILINEMACRO_END ...@@ -2105,12 +2109,12 @@ RAPIDJSON_MULTILINEMACRO_END
bool EndObject(SizeType memberCount) { bool EndObject(SizeType memberCount) {
if (!valid_) return false; if (!valid_) return false;
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount)); RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount));
if (!CurrentSchema().EndObject(CurrentContext(), *this, memberCount)) return valid_ = false; if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false;
RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount)); RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount));
} }
bool StartArray() { bool StartArray() {
RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext(), *this)); RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext()));
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ()); RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ());
return valid_ = !outputHandler_ || outputHandler_->StartArray(); return valid_ = !outputHandler_ || outputHandler_->StartArray();
} }
...@@ -2118,7 +2122,7 @@ RAPIDJSON_MULTILINEMACRO_END ...@@ -2118,7 +2122,7 @@ RAPIDJSON_MULTILINEMACRO_END
bool EndArray(SizeType elementCount) { bool EndArray(SizeType elementCount) {
if (!valid_) return false; if (!valid_) return false;
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount)); RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount));
if (!CurrentSchema().EndArray(CurrentContext(), *this, elementCount)) return valid_ = false; if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false;
RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount)); RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount));
} }
...@@ -2212,7 +2216,7 @@ private: ...@@ -2212,7 +2216,7 @@ private:
if (CurrentContext().inArray) if (CurrentContext().inArray)
internal::TokenHelper<internal::Stack<StateAllocator>, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex); internal::TokenHelper<internal::Stack<StateAllocator>, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex);
if (!CurrentSchema().BeginValue(CurrentContext(), *this)) if (!CurrentSchema().BeginValue(CurrentContext()))
return false; return false;
SizeType count = CurrentContext().patternPropertiesSchemaCount; SizeType count = CurrentContext().patternPropertiesSchemaCount;
...@@ -2237,7 +2241,7 @@ private: ...@@ -2237,7 +2241,7 @@ private:
} }
bool EndValue() { bool EndValue() {
if (!CurrentSchema().EndValue(CurrentContext(), *this)) if (!CurrentSchema().EndValue(CurrentContext()))
return false; return false;
#if RAPIDJSON_SCHEMA_VERBOSE #if RAPIDJSON_SCHEMA_VERBOSE
...@@ -2292,7 +2296,7 @@ private: ...@@ -2292,7 +2296,7 @@ private:
} }
} }
RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push<Context>()) Context(*this, &schema); } RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push<Context>()) Context(*this, *this, &schema); }
RAPIDJSON_FORCEINLINE void PopSchema() { RAPIDJSON_FORCEINLINE void PopSchema() {
Context* c = schemaStack_.template Pop<Context>(1); Context* c = schemaStack_.template Pop<Context>(1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment