Commit aeb5bda6 authored by miloyip's avatar miloyip

Use Hasher to match enum in schema

parent 573faa90
...@@ -171,6 +171,7 @@ template <typename SchemaDocumentType> ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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;\
......
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