Use Hasher to match enum in schema
This commit is contained in:
parent
573faa9025
commit
aeb5bda600
@ -171,6 +171,7 @@ template <typename SchemaDocumentType>
|
|||||||
struct SchemaValidationContext {
|
struct SchemaValidationContext {
|
||||||
typedef Schema<SchemaDocumentType> SchemaType;
|
typedef Schema<SchemaDocumentType> SchemaType;
|
||||||
typedef ISchemaValidatorFactory<SchemaType> SchemaValidatorFactoryType;
|
typedef ISchemaValidatorFactory<SchemaType> SchemaValidatorFactoryType;
|
||||||
|
typedef Hasher<typename SchemaDocumentType::ValueType, typename SchemaDocumentType::AllocatorType> HasherType;
|
||||||
|
|
||||||
enum PatternValidatorType {
|
enum PatternValidatorType {
|
||||||
kPatternValidatorOnly,
|
kPatternValidatorOnly,
|
||||||
@ -194,6 +195,7 @@ struct SchemaValidationContext {
|
|||||||
factory(f),
|
factory(f),
|
||||||
schema(s),
|
schema(s),
|
||||||
valueSchema(),
|
valueSchema(),
|
||||||
|
hasher(),
|
||||||
patternPropertiesSchemas(),
|
patternPropertiesSchemas(),
|
||||||
notValidator(),
|
notValidator(),
|
||||||
refValidator(),
|
refValidator(),
|
||||||
@ -205,6 +207,7 @@ struct SchemaValidationContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
~SchemaValidationContext() {
|
~SchemaValidationContext() {
|
||||||
|
delete hasher;
|
||||||
delete notValidator;
|
delete notValidator;
|
||||||
delete refValidator;
|
delete refValidator;
|
||||||
delete[] patternPropertiesSchemas;
|
delete[] patternPropertiesSchemas;
|
||||||
@ -214,6 +217,7 @@ struct SchemaValidationContext {
|
|||||||
const SchemaValidatorFactoryType* factory;
|
const SchemaValidatorFactoryType* factory;
|
||||||
const SchemaType* schema;
|
const SchemaType* schema;
|
||||||
const SchemaType* valueSchema;
|
const SchemaType* valueSchema;
|
||||||
|
HasherType* hasher;
|
||||||
SchemaValidatorArray allOfValidators;
|
SchemaValidatorArray allOfValidators;
|
||||||
SchemaValidatorArray anyOfValidators;
|
SchemaValidatorArray anyOfValidators;
|
||||||
SchemaValidatorArray oneOfValidators;
|
SchemaValidatorArray oneOfValidators;
|
||||||
@ -244,9 +248,12 @@ public:
|
|||||||
typedef typename EncodingType::Ch Ch;
|
typedef typename EncodingType::Ch Ch;
|
||||||
typedef SchemaValidationContext<SchemaDocumentType> Context;
|
typedef SchemaValidationContext<SchemaDocumentType> Context;
|
||||||
typedef Schema<SchemaDocumentType> SchemaType;
|
typedef Schema<SchemaDocumentType> SchemaType;
|
||||||
|
typedef Hasher<ValueType, AllocatorType> HasherType;
|
||||||
friend class GenericSchemaDocument<ValueType, AllocatorType>;
|
friend class GenericSchemaDocument<ValueType, AllocatorType>;
|
||||||
|
|
||||||
Schema(SchemaDocumentType* document, const PointerType& p, const ValueType& value) :
|
Schema(SchemaDocumentType* document, const PointerType& p, const ValueType& value) :
|
||||||
|
enum_(),
|
||||||
|
enumCount_(),
|
||||||
not_(),
|
not_(),
|
||||||
ref_(),
|
ref_(),
|
||||||
type_((1 << kTotalSchemaType) - 1), // typeless
|
type_((1 << kTotalSchemaType) - 1), // typeless
|
||||||
@ -295,8 +302,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (const ValueType* v = GetMember(value, "enum"))
|
if (const ValueType* v = GetMember(value, "enum"))
|
||||||
if (v->IsArray() && v->Size() > 0)
|
if (v->IsArray() && v->Size() > 0) {
|
||||||
enum_.CopyFrom(*v, allocator_);
|
enum_ = new uint64_t[v->Size()];
|
||||||
|
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) {
|
||||||
|
HasherType h;
|
||||||
|
itr->Accept(h);
|
||||||
|
enum_[enumCount_++] = h.GetHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AssigIfExist(allOf_, document, p, value, "allOf");
|
AssigIfExist(allOf_, document, p, value, "allOf");
|
||||||
AssigIfExist(anyOf_, document, p, value, "anyOf");
|
AssigIfExist(anyOf_, document, p, value, "anyOf");
|
||||||
@ -465,6 +478,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
~Schema() {
|
~Schema() {
|
||||||
|
delete [] enum_;
|
||||||
delete [] properties_;
|
delete [] properties_;
|
||||||
delete [] patternProperties_;
|
delete [] patternProperties_;
|
||||||
delete [] itemsTuple_;
|
delete [] itemsTuple_;
|
||||||
@ -521,6 +535,15 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (enum_) {
|
||||||
|
const uint64_t h = context.hasher->GetHashCode();
|
||||||
|
for (SizeType i = 0; i < enumCount_; i++)
|
||||||
|
if (enum_[i] == h)
|
||||||
|
goto foundEnum;
|
||||||
|
return false;
|
||||||
|
foundEnum:;
|
||||||
|
}
|
||||||
|
|
||||||
if (allOf_.schemas)
|
if (allOf_.schemas)
|
||||||
for (SizeType i = 0; i < allOf_.count; i++)
|
for (SizeType i = 0; i < allOf_.count; i++)
|
||||||
if (!context.allOfValidators.validators[i]->IsValid())
|
if (!context.allOfValidators.validators[i]->IsValid())
|
||||||
@ -555,56 +578,47 @@ public:
|
|||||||
|
|
||||||
bool Null(Context& context) const {
|
bool Null(Context& context) const {
|
||||||
CreateParallelValidator(context);
|
CreateParallelValidator(context);
|
||||||
return
|
return (type_ & (1 << kNullSchemaType));
|
||||||
(type_ & (1 << kNullSchemaType)) &&
|
|
||||||
(!enum_.IsArray() || CheckEnum(ValueType().Move()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bool(Context& context, bool b) const {
|
bool Bool(Context& context, bool) const {
|
||||||
CreateParallelValidator(context);
|
CreateParallelValidator(context);
|
||||||
return
|
return (type_ & (1 << kBooleanSchemaType));
|
||||||
(type_ & (1 << kBooleanSchemaType)) &&
|
|
||||||
(!enum_.IsArray() || CheckEnum(ValueType(b).Move()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Int(Context& context, int i) const {
|
bool Int(Context& context, int i) const {
|
||||||
CreateParallelValidator(context);
|
CreateParallelValidator(context);
|
||||||
if ((type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))) == 0)
|
if ((type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
return CheckDouble(i);
|
||||||
return CheckDouble(i) && (!enum_.IsArray() || CheckEnum(ValueType(i).Move()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Uint(Context& context, unsigned u) const {
|
bool Uint(Context& context, unsigned u) const {
|
||||||
CreateParallelValidator(context);
|
CreateParallelValidator(context);
|
||||||
if ((type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))) == 0)
|
if ((type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
return CheckDouble(u);
|
||||||
return CheckDouble(u) && (!enum_.IsArray() || CheckEnum(ValueType(u).Move()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Int64(Context& context, int64_t i) const {
|
bool Int64(Context& context, int64_t i) const {
|
||||||
CreateParallelValidator(context);
|
CreateParallelValidator(context);
|
||||||
if ((type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))) == 0)
|
if ((type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
return CheckDouble(i);
|
||||||
return CheckDouble(i) && (!enum_.IsArray() || CheckEnum(ValueType(i).Move()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Uint64(Context& context, uint64_t u) const {
|
bool Uint64(Context& context, uint64_t u) const {
|
||||||
CreateParallelValidator(context);
|
CreateParallelValidator(context);
|
||||||
if ((type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))) == 0)
|
if ((type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
return CheckDouble(u);
|
||||||
return CheckDouble(u) && (!enum_.IsArray() || CheckEnum(ValueType(u).Move()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Double(Context& context, double d) const {
|
bool Double(Context& context, double d) const {
|
||||||
CreateParallelValidator(context);
|
CreateParallelValidator(context);
|
||||||
if ((type_ & (1 << kNumberSchemaType)) == 0)
|
if ((type_ & (1 << kNumberSchemaType)) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
return CheckDouble(d);
|
||||||
return CheckDouble(d) && (!enum_.IsArray() || CheckEnum(ValueType(d).Move()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool String(Context& context, const Ch* str, SizeType length, bool) const {
|
bool String(Context& context, const Ch* str, SizeType length, bool) const {
|
||||||
@ -621,10 +635,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pattern_ && !IsPatternMatch(pattern_, str, length))
|
return !pattern_ || IsPatternMatch(pattern_, str, length);
|
||||||
return false;
|
|
||||||
|
|
||||||
return !enum_.IsArray() || CheckEnum(ValueType(str, length).Move());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartObject(Context& context) const {
|
bool StartObject(Context& context) const {
|
||||||
@ -836,14 +847,9 @@ private:
|
|||||||
else if (type == "number" ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
|
else if (type == "number" ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckEnum(const ValueType& v) const {
|
|
||||||
for (typename ValueType::ConstValueIterator itr = enum_.Begin(); itr != enum_.End(); ++itr)
|
|
||||||
if (v == *itr)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateParallelValidator(Context& context) const {
|
void CreateParallelValidator(Context& context) const {
|
||||||
|
if (enum_)
|
||||||
|
context.hasher = new HasherType;
|
||||||
if (allOf_.schemas) CreateSchemaValidators(context, context.allOfValidators, allOf_);
|
if (allOf_.schemas) CreateSchemaValidators(context, context.allOfValidators, allOf_);
|
||||||
if (anyOf_.schemas) CreateSchemaValidators(context, context.anyOfValidators, anyOf_);
|
if (anyOf_.schemas) CreateSchemaValidators(context, context.anyOfValidators, anyOf_);
|
||||||
if (oneOf_.schemas) CreateSchemaValidators(context, context.oneOfValidators, oneOf_);
|
if (oneOf_.schemas) CreateSchemaValidators(context, context.oneOfValidators, oneOf_);
|
||||||
@ -922,7 +928,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
AllocatorType allocator_;
|
AllocatorType allocator_;
|
||||||
ValueType enum_;
|
uint64_t* enum_;
|
||||||
|
SizeType enumCount_;
|
||||||
SchemaArray allOf_;
|
SchemaArray allOf_;
|
||||||
SchemaArray anyOf_;
|
SchemaArray anyOf_;
|
||||||
SchemaArray oneOf_;
|
SchemaArray oneOf_;
|
||||||
@ -1163,6 +1170,8 @@ public:
|
|||||||
|
|
||||||
#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\
|
#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\
|
||||||
for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\
|
for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\
|
||||||
|
if (context->hasher)\
|
||||||
|
context->hasher->method arg2;\
|
||||||
if (context->allOfValidators.validators)\
|
if (context->allOfValidators.validators)\
|
||||||
for (SizeType i_ = 0; i_ < context->allOfValidators.count; i_++)\
|
for (SizeType i_ = 0; i_ < context->allOfValidators.count; i_++)\
|
||||||
static_cast<GenericSchemaValidator*>(context->allOfValidators.validators[i_])->method arg2;\
|
static_cast<GenericSchemaValidator*>(context->allOfValidators.validators[i_])->method arg2;\
|
||||||
|
Loading…
x
Reference in New Issue
Block a user