Refactor template parameters and add ISchemaValidator
This commit is contained in:
parent
a5eabe8d0c
commit
24f060f7cb
@ -16,6 +16,7 @@
|
|||||||
#define RAPIDJSON_SCHEMA_H_
|
#define RAPIDJSON_SCHEMA_H_
|
||||||
|
|
||||||
#include "document.h"
|
#include "document.h"
|
||||||
|
#include "pointer.h"
|
||||||
#include <cmath> // HUGE_VAL, abs, floor
|
#include <cmath> // HUGE_VAL, abs, floor
|
||||||
|
|
||||||
#if !defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800))
|
#if !defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800))
|
||||||
@ -41,7 +42,7 @@ RAPIDJSON_DIAG_OFF(effc++)
|
|||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
enum SchemaType {
|
enum SchemaValueType {
|
||||||
kNullSchemaType,
|
kNullSchemaType,
|
||||||
kBooleanSchemaType,
|
kBooleanSchemaType,
|
||||||
kObjectSchemaType,
|
kObjectSchemaType,
|
||||||
@ -52,13 +53,28 @@ enum SchemaType {
|
|||||||
kTotalSchemaType
|
kTotalSchemaType
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Encoding>
|
template <typename Encoding, typename Allocator>
|
||||||
class Schema;
|
class Schema;
|
||||||
|
|
||||||
template <typename Encoding, typename OutputHandler, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
|
class GenericSchemaDocument;
|
||||||
|
|
||||||
|
template <typename Encoding, typename OutputHandler, typename StateAllocator>
|
||||||
class GenericSchemaValidator;
|
class GenericSchemaValidator;
|
||||||
|
|
||||||
template <typename Encoding>
|
class ISchemaValidator {
|
||||||
|
public:
|
||||||
|
virtual ~ISchemaValidator() {}
|
||||||
|
virtual bool IsValid() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename SchemaType>
|
||||||
|
class ISchemaValidatorFactory {
|
||||||
|
public:
|
||||||
|
virtual ~ISchemaValidatorFactory() {}
|
||||||
|
virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct SchemaValidatorArray {
|
struct SchemaValidatorArray {
|
||||||
SchemaValidatorArray() : validators(), count() {}
|
SchemaValidatorArray() : validators(), count() {}
|
||||||
~SchemaValidatorArray() {
|
~SchemaValidatorArray() {
|
||||||
@ -67,11 +83,11 @@ struct SchemaValidatorArray {
|
|||||||
delete[] validators;
|
delete[] validators;
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericSchemaValidator<Encoding, BaseReaderHandler<>, CrtAllocator>** validators;
|
ISchemaValidator** validators;
|
||||||
SizeType count;
|
SizeType count;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Encoding>
|
template <typename Encoding, typename Allocator>
|
||||||
struct SchemaArray {
|
struct SchemaArray {
|
||||||
SchemaArray() : schemas(), count() {}
|
SchemaArray() : schemas(), count() {}
|
||||||
~SchemaArray() {
|
~SchemaArray() {
|
||||||
@ -80,7 +96,7 @@ struct SchemaArray {
|
|||||||
delete[] schemas;
|
delete[] schemas;
|
||||||
}
|
}
|
||||||
|
|
||||||
Schema<Encoding>** schemas;
|
Schema<Encoding, Allocator>** schemas;
|
||||||
SizeType count;
|
SizeType count;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,9 +106,14 @@ enum PatternValidatorType {
|
|||||||
kPatternValidatorWithAdditionalProperty
|
kPatternValidatorWithAdditionalProperty
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Encoding>
|
template <typename Encoding, typename Allocator>
|
||||||
struct SchemaValidationContext {
|
struct SchemaValidationContext {
|
||||||
SchemaValidationContext(const Schema<Encoding>* s) :
|
typedef Schema<Encoding, Allocator> SchemaType;
|
||||||
|
typedef GenericSchemaValidator<SchemaType, BaseReaderHandler<>, CrtAllocator> SchemaValidatorType;
|
||||||
|
typedef ISchemaValidatorFactory<SchemaType> SchemaValidatorFactoryType;
|
||||||
|
|
||||||
|
SchemaValidationContext(const SchemaValidatorFactoryType* f, const SchemaType* s) :
|
||||||
|
factory(f),
|
||||||
schema(s),
|
schema(s),
|
||||||
valueSchema(),
|
valueSchema(),
|
||||||
patternPropertiesSchemas(),
|
patternPropertiesSchemas(),
|
||||||
@ -110,15 +131,16 @@ struct SchemaValidationContext {
|
|||||||
delete[] objectDependencies;
|
delete[] objectDependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Schema<Encoding>* schema;
|
const SchemaValidatorFactoryType* factory;
|
||||||
const Schema<Encoding>* valueSchema;
|
const SchemaType* schema;
|
||||||
SchemaValidatorArray<Encoding> allOfValidators;
|
const SchemaType* valueSchema;
|
||||||
SchemaValidatorArray<Encoding> anyOfValidators;
|
SchemaValidatorArray allOfValidators;
|
||||||
SchemaValidatorArray<Encoding> oneOfValidators;
|
SchemaValidatorArray anyOfValidators;
|
||||||
SchemaValidatorArray<Encoding> dependencyValidators;
|
SchemaValidatorArray oneOfValidators;
|
||||||
SchemaValidatorArray<Encoding> patternPropertiesValidators;
|
SchemaValidatorArray dependencyValidators;
|
||||||
const Schema<Encoding>** patternPropertiesSchemas;
|
SchemaValidatorArray patternPropertiesValidators;
|
||||||
GenericSchemaValidator<Encoding, BaseReaderHandler<>, CrtAllocator>* notValidator;
|
const SchemaType** patternPropertiesSchemas;
|
||||||
|
ISchemaValidator* notValidator;
|
||||||
SizeType patternPropertiesSchemaCount;
|
SizeType patternPropertiesSchemaCount;
|
||||||
PatternValidatorType valuePatternValidatorType;
|
PatternValidatorType valuePatternValidatorType;
|
||||||
PatternValidatorType objectPatternValidatorType;
|
PatternValidatorType objectPatternValidatorType;
|
||||||
@ -128,14 +150,19 @@ struct SchemaValidationContext {
|
|||||||
bool inArray;
|
bool inArray;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Encoding>
|
template <typename Encoding, typename Allocator>
|
||||||
class Schema {
|
class Schema {
|
||||||
public:
|
public:
|
||||||
|
typedef Encoding EncodingType;
|
||||||
typedef typename Encoding::Ch Ch;
|
typedef typename Encoding::Ch Ch;
|
||||||
typedef SchemaValidationContext<Encoding> Context;
|
typedef SchemaValidationContext<Encoding, Allocator> Context;
|
||||||
|
typedef GenericSchemaDocument<Encoding, Allocator> SchemaDocumentType;
|
||||||
|
typedef Schema<Encoding, Allocator> SchemaType;
|
||||||
|
typedef GenericValue<Encoding, Allocator> ValueType;
|
||||||
|
typedef GenericPointer<ValueType> PointerType;
|
||||||
|
|
||||||
template <typename ValueType>
|
template <typename ValueType>
|
||||||
Schema(const ValueType& value) :
|
Schema(SchemaDocumentType* document, const PointerType& p, const ValueType& value) :
|
||||||
not_(),
|
not_(),
|
||||||
type_((1 << kTotalSchemaType) - 1), // typeless
|
type_((1 << kTotalSchemaType) - 1), // typeless
|
||||||
properties_(),
|
properties_(),
|
||||||
@ -185,12 +212,12 @@ public:
|
|||||||
if (v->IsArray() && v->Size() > 0)
|
if (v->IsArray() && v->Size() > 0)
|
||||||
enum_.CopyFrom(*v, allocator_);
|
enum_.CopyFrom(*v, allocator_);
|
||||||
|
|
||||||
AssigIfExist(allOf_, value, "allOf");
|
AssigIfExist(allOf_, document, p, value, "allOf");
|
||||||
AssigIfExist(anyOf_, value, "anyOf");
|
AssigIfExist(anyOf_, document, p, value, "anyOf");
|
||||||
AssigIfExist(oneOf_, value, "oneOf");
|
AssigIfExist(oneOf_, document, p, value, "oneOf");
|
||||||
|
|
||||||
if (const ValueType* v = GetMember(value, "not"))
|
if (const ValueType* v = GetMember(value, "not"))
|
||||||
not_ = new Schema<Encoding>(*v);
|
not_ = document->CreateSchema(p, *v);
|
||||||
|
|
||||||
// Object
|
// Object
|
||||||
|
|
||||||
@ -233,7 +260,7 @@ public:
|
|||||||
for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) {
|
for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) {
|
||||||
SizeType index;
|
SizeType index;
|
||||||
if (FindPropertyIndex(itr->name, &index)) {
|
if (FindPropertyIndex(itr->name, &index)) {
|
||||||
properties_[index].schema = new Schema(itr->value);
|
properties_[index].schema = document->CreateSchema(p, itr->value);
|
||||||
properties_[index].typeless = false;
|
properties_[index].typeless = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,7 +271,7 @@ public:
|
|||||||
|
|
||||||
for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {
|
for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {
|
||||||
patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name);
|
patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name);
|
||||||
patternProperties_[patternPropertyCount_].schema = new Schema<Encoding>(itr->value);
|
patternProperties_[patternPropertyCount_].schema = document->CreateSchema(p, itr->value);
|
||||||
patternPropertyCount_++;
|
patternPropertyCount_++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -275,7 +302,7 @@ public:
|
|||||||
}
|
}
|
||||||
else if (itr->value.IsObject()) {
|
else if (itr->value.IsObject()) {
|
||||||
hasSchemaDependencies_ = true;
|
hasSchemaDependencies_ = true;
|
||||||
properties_[sourceIndex].dependenciesSchema = new Schema<Encoding>(itr->value);
|
properties_[sourceIndex].dependenciesSchema = document->CreateSchema(p, itr->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,7 +312,7 @@ public:
|
|||||||
if (v->IsBool())
|
if (v->IsBool())
|
||||||
additionalProperties_ = v->GetBool();
|
additionalProperties_ = v->GetBool();
|
||||||
else if (v->IsObject())
|
else if (v->IsObject())
|
||||||
additionalPropertiesSchema_ = new Schema<Encoding>(*v);
|
additionalPropertiesSchema_ = document->CreateSchema(p, *v);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssignIfExist(minProperties_, value, "minProperties");
|
AssignIfExist(minProperties_, value, "minProperties");
|
||||||
@ -294,11 +321,11 @@ public:
|
|||||||
// Array
|
// Array
|
||||||
if (const ValueType* v = GetMember(value, "items")) {
|
if (const ValueType* v = GetMember(value, "items")) {
|
||||||
if (v->IsObject()) // List validation
|
if (v->IsObject()) // List validation
|
||||||
itemsList_ = new Schema<Encoding>(*v);
|
itemsList_ = document->CreateSchema(p, *v);
|
||||||
else if (v->IsArray()) { // Tuple validation
|
else if (v->IsArray()) { // Tuple validation
|
||||||
itemsTuple_ = new Schema<Encoding>*[v->Size()];
|
itemsTuple_ = new Schema*[v->Size()];
|
||||||
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
|
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
|
||||||
itemsTuple_[itemsTupleCount_++] = new Schema<Encoding>(*itr);
|
itemsTuple_[itemsTupleCount_++] = document->CreateSchema(p, *itr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +336,7 @@ public:
|
|||||||
if (v->IsBool())
|
if (v->IsBool())
|
||||||
additionalItems_ = v->GetBool();
|
additionalItems_ = v->GetBool();
|
||||||
else if (v->IsObject())
|
else if (v->IsObject())
|
||||||
additionalItemsSchema_ = new Schema<Encoding>(*v);
|
additionalItemsSchema_ = document->CreateSchema(p, *v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// String
|
// String
|
||||||
@ -521,9 +548,9 @@ public:
|
|||||||
|
|
||||||
if (patternProperties_) { // pre-allocate schema array
|
if (patternProperties_) { // pre-allocate schema array
|
||||||
SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType
|
SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType
|
||||||
context.patternPropertiesSchemas = new const Schema<Encoding>*[count];
|
context.patternPropertiesSchemas = new const SchemaType*[count];
|
||||||
context.patternPropertiesSchemaCount = 0;
|
context.patternPropertiesSchemaCount = 0;
|
||||||
std::memset(context.patternPropertiesSchemas, 0, sizeof(Schema<Encoding>*) * count);
|
std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -539,7 +566,7 @@ public:
|
|||||||
|
|
||||||
SizeType index;
|
SizeType index;
|
||||||
if (FindPropertyIndex(str, len, &index)) {
|
if (FindPropertyIndex(str, len, &index)) {
|
||||||
const Schema<Encoding>* propertySchema = properties_[index].typeless ? GetTypeless() : properties_[index].schema;
|
const SchemaType* propertySchema = properties_[index].typeless ? GetTypeless() : properties_[index].schema;
|
||||||
if (context.patternPropertiesSchemaCount > 0) {
|
if (context.patternPropertiesSchemaCount > 0) {
|
||||||
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = propertySchema;
|
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = propertySchema;
|
||||||
context.valueSchema = GetTypeless();
|
context.valueSchema = GetTypeless();
|
||||||
@ -619,8 +646,11 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef GenericSchemaValidator<Encoding, BaseReaderHandler<>, CrtAllocator> SchemaValidatorType;
|
typedef GenericSchemaValidator<Encoding, BaseReaderHandler<>, CrtAllocator> SchemaValidatorType;
|
||||||
static const Schema<Encoding>* GetTypeless() {
|
typedef SchemaArray<Encoding, Allocator> SchemaArrayType;
|
||||||
static Schema<Encoding> typeless(Value(kObjectType).Move());
|
typedef SchemaValidatorArray SchemaValidatorArrayType;
|
||||||
|
|
||||||
|
static const SchemaType* GetTypeless() {
|
||||||
|
static SchemaType typeless(0, PointerType(), Value(kObjectType).Move());
|
||||||
return &typeless;
|
return &typeless;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,15 +683,15 @@ private:
|
|||||||
out = static_cast<SizeType>(v->GetUint64());
|
out = static_cast<SizeType>(v->GetUint64());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ValueType>
|
template <typename DocumentType, typename ValueType>
|
||||||
static void AssigIfExist(SchemaArray<Encoding>& out, const ValueType& value, const char* name) {
|
static void AssigIfExist(SchemaArrayType& out, const DocumentType& document, const PointerType& p, const ValueType& value, const char* name) {
|
||||||
if (const ValueType* v = GetMember(value, name))
|
if (const ValueType* v = GetMember(value, name))
|
||||||
if (v->IsArray() && v->Size() > 0) {
|
if (v->IsArray() && v->Size() > 0) {
|
||||||
out.count = v->Size();
|
out.count = v->Size();
|
||||||
out.schemas = new Schema*[out.count];
|
out.schemas = new Schema*[out.count];
|
||||||
memset(out.schemas, 0, sizeof(Schema*)* out.count);
|
memset(out.schemas, 0, sizeof(Schema*)* out.count);
|
||||||
for (SizeType i = 0; i < out.count; i++)
|
for (SizeType i = 0; i < out.count; i++)
|
||||||
out.schemas[i] = new Schema<Encoding>((*v)[i]);
|
out.schemas[i] = document->CreateSchema(p, (*v)[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,26 +736,26 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CreateParallelValidator(Context& context) const {
|
void CreateParallelValidator(Context& context) const {
|
||||||
if (allOf_.schemas) CreateSchemaValidators(context.allOfValidators, allOf_);
|
if (allOf_.schemas) CreateSchemaValidators(context, context.allOfValidators, allOf_);
|
||||||
if (anyOf_.schemas) CreateSchemaValidators(context.anyOfValidators, anyOf_);
|
if (anyOf_.schemas) CreateSchemaValidators(context, context.anyOfValidators, anyOf_);
|
||||||
if (oneOf_.schemas) CreateSchemaValidators(context.oneOfValidators, oneOf_);
|
if (oneOf_.schemas) CreateSchemaValidators(context, context.oneOfValidators, oneOf_);
|
||||||
if (not_ && !context.notValidator)
|
if (not_ && !context.notValidator)
|
||||||
context.notValidator = new SchemaValidatorType(*not_);
|
context.notValidator = context.factory->CreateSchemaValidator(*not_);
|
||||||
|
|
||||||
if (hasSchemaDependencies_ && !context.dependencyValidators.validators) {
|
if (hasSchemaDependencies_ && !context.dependencyValidators.validators) {
|
||||||
context.dependencyValidators.validators = new SchemaValidatorType*[propertyCount_];
|
context.dependencyValidators.validators = new ISchemaValidator*[propertyCount_];
|
||||||
context.dependencyValidators.count = propertyCount_;
|
context.dependencyValidators.count = propertyCount_;
|
||||||
for (SizeType i = 0; i < propertyCount_; i++)
|
for (SizeType i = 0; i < propertyCount_; i++)
|
||||||
context.dependencyValidators.validators[i] = properties_[i].dependenciesSchema ? new SchemaValidatorType(*properties_[i].dependenciesSchema) : 0;
|
context.dependencyValidators.validators[i] = properties_[i].dependenciesSchema ? context.factory->CreateSchemaValidator(*properties_[i].dependenciesSchema) : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateSchemaValidators(SchemaValidatorArray<Encoding>& validators, const SchemaArray<Encoding>& schemas) const {
|
void CreateSchemaValidators(Context& context, SchemaValidatorArrayType& validators, const SchemaArrayType& schemas) const {
|
||||||
if (!validators.validators) {
|
if (!validators.validators) {
|
||||||
validators.validators = new SchemaValidatorType*[schemas.count];
|
validators.validators = new ISchemaValidator*[schemas.count];
|
||||||
validators.count = schemas.count;
|
validators.count = schemas.count;
|
||||||
for (SizeType i = 0; i < schemas.count; i++)
|
for (SizeType i = 0; i < schemas.count; i++)
|
||||||
validators.validators[i] = new SchemaValidatorType(*schemas.schemas[i]);
|
validators.validators[i] = context.factory->CreateSchemaValidator(*schemas.schemas[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,8 +802,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
GenericValue<Encoding> name;
|
GenericValue<Encoding> name;
|
||||||
const Schema<Encoding>* schema;
|
const SchemaType* schema;
|
||||||
const Schema<Encoding>* dependenciesSchema;
|
const SchemaType* dependenciesSchema;
|
||||||
bool* dependencies;
|
bool* dependencies;
|
||||||
bool required;
|
bool required;
|
||||||
bool typeless;
|
bool typeless;
|
||||||
@ -786,20 +816,20 @@ private:
|
|||||||
delete pattern;
|
delete pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
Schema<Encoding>* schema;
|
SchemaType* schema;
|
||||||
RegexType* pattern;
|
RegexType* pattern;
|
||||||
};
|
};
|
||||||
|
|
||||||
MemoryPoolAllocator<> allocator_;
|
Allocator allocator_;
|
||||||
GenericValue<Encoding> enum_;
|
GenericValue<Encoding> enum_;
|
||||||
SchemaArray<Encoding> allOf_;
|
SchemaArrayType allOf_;
|
||||||
SchemaArray<Encoding> anyOf_;
|
SchemaArrayType anyOf_;
|
||||||
SchemaArray<Encoding> oneOf_;
|
SchemaArrayType oneOf_;
|
||||||
Schema<Encoding>* not_;
|
SchemaType* not_;
|
||||||
unsigned type_; // bitmask of kSchemaType
|
unsigned type_; // bitmask of kSchemaType
|
||||||
|
|
||||||
Property* properties_;
|
Property* properties_;
|
||||||
Schema<Encoding>* additionalPropertiesSchema_;
|
SchemaType* additionalPropertiesSchema_;
|
||||||
PatternProperty* patternProperties_;
|
PatternProperty* patternProperties_;
|
||||||
SizeType patternPropertyCount_;
|
SizeType patternPropertyCount_;
|
||||||
SizeType propertyCount_;
|
SizeType propertyCount_;
|
||||||
@ -810,9 +840,9 @@ private:
|
|||||||
bool hasDependencies_;
|
bool hasDependencies_;
|
||||||
bool hasSchemaDependencies_;
|
bool hasSchemaDependencies_;
|
||||||
|
|
||||||
Schema<Encoding>* additionalItemsSchema_;
|
SchemaType* additionalItemsSchema_;
|
||||||
Schema<Encoding>* itemsList_;
|
SchemaType* itemsList_;
|
||||||
Schema<Encoding>** itemsTuple_;
|
SchemaType** itemsTuple_;
|
||||||
SizeType itemsTupleCount_;
|
SizeType itemsTupleCount_;
|
||||||
SizeType minItems_;
|
SizeType minItems_;
|
||||||
SizeType maxItems_;
|
SizeType maxItems_;
|
||||||
@ -836,35 +866,43 @@ public:
|
|||||||
template <typename T1, typename T2, typename T3>
|
template <typename T1, typename T2, typename T3>
|
||||||
friend class GenericSchemaValidator;
|
friend class GenericSchemaValidator;
|
||||||
|
|
||||||
|
typedef Schema<Encoding, Allocator> SchemaType;
|
||||||
|
|
||||||
template <typename DocumentType>
|
template <typename DocumentType>
|
||||||
GenericSchemaDocument(const DocumentType& document) : root_() {
|
GenericSchemaDocument(const DocumentType& document) : root_() {
|
||||||
root_ = new Schema<Encoding>(static_cast<const typename DocumentType::ValueType&>(document));
|
typedef typename DocumentType::ValueType ValueType;
|
||||||
|
root_ = CreateSchema(GenericPointer<ValueType>("#"), static_cast<const ValueType&>(document));
|
||||||
}
|
}
|
||||||
|
|
||||||
~GenericSchemaDocument() {
|
~GenericSchemaDocument() {
|
||||||
delete root_;
|
delete root_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ValueType>
|
||||||
|
SchemaType* CreateSchema(const GenericPointer<ValueType>& p, const ValueType& v) {
|
||||||
|
return new SchemaType(this, p, v);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Schema<Encoding>* root_;
|
SchemaType* root_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef GenericSchemaDocument<UTF8<> > SchemaDocument;
|
typedef GenericSchemaDocument<UTF8<> > SchemaDocument;
|
||||||
|
|
||||||
template <typename Encoding, typename OutputHandler = BaseReaderHandler<Encoding>, typename Allocator = CrtAllocator >
|
template <typename SchemaType, typename OutputHandler = BaseReaderHandler<typename SchemaType::EncodingType>, typename StateAllocator = CrtAllocator >
|
||||||
class GenericSchemaValidator {
|
class GenericSchemaValidator : public ISchemaValidatorFactory<SchemaType>, public ISchemaValidator {
|
||||||
public:
|
public:
|
||||||
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
typedef typename SchemaType::EncodingType EncodingType;
|
||||||
typedef GenericSchemaDocument<Encoding> SchemaDocumentType;
|
typedef typename EncodingType::Ch Ch;
|
||||||
friend class Schema<Encoding>;
|
typedef GenericSchemaDocument<EncodingType> SchemaDocumentType;
|
||||||
|
|
||||||
GenericSchemaValidator(
|
GenericSchemaValidator(
|
||||||
const SchemaDocumentType& schema,
|
const SchemaDocumentType& schemaDocument,
|
||||||
Allocator* allocator = 0,
|
StateAllocator* allocator = 0,
|
||||||
size_t schemaStackCapacity = kDefaultSchemaStackCapacity/*,
|
size_t schemaStackCapacity = kDefaultSchemaStackCapacity/*,
|
||||||
size_t documentStackCapacity = kDefaultDocumentStackCapacity*/)
|
size_t documentStackCapacity = kDefaultDocumentStackCapacity*/)
|
||||||
:
|
:
|
||||||
root_(*schema.root_),
|
root_(*schemaDocument.root_),
|
||||||
outputHandler_(nullOutputHandler_),
|
outputHandler_(nullOutputHandler_),
|
||||||
schemaStack_(allocator, schemaStackCapacity),
|
schemaStack_(allocator, schemaStackCapacity),
|
||||||
// documentStack_(allocator, documentStackCapacity),
|
// documentStack_(allocator, documentStackCapacity),
|
||||||
@ -873,13 +911,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
GenericSchemaValidator(
|
GenericSchemaValidator(
|
||||||
const SchemaDocumentType& schema,
|
const SchemaDocumentType& schemaDocument,
|
||||||
OutputHandler& outputHandler,
|
OutputHandler& outputHandler,
|
||||||
Allocator* allocator = 0,
|
StateAllocator* allocator = 0,
|
||||||
size_t schemaStackCapacity = kDefaultSchemaStackCapacity/*,
|
size_t schemaStackCapacity = kDefaultSchemaStackCapacity/*,
|
||||||
size_t documentStackCapacity = kDefaultDocumentStackCapacity*/)
|
size_t documentStackCapacity = kDefaultDocumentStackCapacity*/)
|
||||||
:
|
:
|
||||||
root_(*schema.root_),
|
root_(*schemaDocument.root_),
|
||||||
outputHandler_(outputHandler),
|
outputHandler_(outputHandler),
|
||||||
schemaStack_(allocator, schemaStackCapacity),
|
schemaStack_(allocator, schemaStackCapacity),
|
||||||
// documentStack_(allocator, documentStackCapacity),
|
// documentStack_(allocator, documentStackCapacity),
|
||||||
@ -898,7 +936,8 @@ public:
|
|||||||
valid_ = true;
|
valid_ = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool IsValid() { return valid_; }
|
// Implementation of ISchemaValidator
|
||||||
|
virtual bool IsValid() const { return valid_; }
|
||||||
|
|
||||||
#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\
|
#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\
|
||||||
if (!valid_) return false; \
|
if (!valid_) return false; \
|
||||||
@ -908,23 +947,23 @@ public:
|
|||||||
for (Context* context = schemaStack_.template Bottom<Context>(); context <= schemaStack_.template Top<Context>(); context++) {\
|
for (Context* context = schemaStack_.template Bottom<Context>(); context <= schemaStack_.template Top<Context>(); context++) {\
|
||||||
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_++)\
|
||||||
context->allOfValidators.validators[i_]->method arg2;\
|
static_cast<GenericSchemaValidator*>(context->allOfValidators.validators[i_])->method arg2;\
|
||||||
if (context->anyOfValidators.validators)\
|
if (context->anyOfValidators.validators)\
|
||||||
for (SizeType i_ = 0; i_ < context->anyOfValidators.count; i_++)\
|
for (SizeType i_ = 0; i_ < context->anyOfValidators.count; i_++)\
|
||||||
context->anyOfValidators.validators[i_]->method arg2;\
|
static_cast<GenericSchemaValidator*>(context->anyOfValidators.validators[i_])->method arg2;\
|
||||||
if (context->oneOfValidators.validators)\
|
if (context->oneOfValidators.validators)\
|
||||||
for (SizeType i_ = 0; i_ < context->oneOfValidators.count; i_++)\
|
for (SizeType i_ = 0; i_ < context->oneOfValidators.count; i_++)\
|
||||||
context->oneOfValidators.validators[i_]->method arg2;\
|
static_cast<GenericSchemaValidator*>(context->oneOfValidators.validators[i_])->method arg2;\
|
||||||
if (context->notValidator)\
|
if (context->notValidator)\
|
||||||
context->notValidator->method arg2;\
|
static_cast<GenericSchemaValidator*>(context->notValidator)->method arg2;\
|
||||||
if (context->dependencyValidators.validators)\
|
if (context->dependencyValidators.validators)\
|
||||||
for (SizeType i_ = 0; i_ < context->dependencyValidators.count; i_++)\
|
for (SizeType i_ = 0; i_ < context->dependencyValidators.count; i_++)\
|
||||||
if (context->dependencyValidators.validators[i_])\
|
if (context->dependencyValidators.validators[i_])\
|
||||||
context->dependencyValidators.validators[i_]->method arg2;\
|
static_cast<GenericSchemaValidator*>(context->dependencyValidators.validators[i_])->method arg2;\
|
||||||
if (context->patternPropertiesValidators.validators)\
|
if (context->patternPropertiesValidators.validators)\
|
||||||
for (SizeType i_ = 0; i_ < context->patternPropertiesValidators.count; i_++)\
|
for (SizeType i_ = 0; i_ < context->patternPropertiesValidators.count; i_++)\
|
||||||
if (context->patternPropertiesValidators.validators[i_])\
|
if (context->patternPropertiesValidators.validators[i_])\
|
||||||
context->patternPropertiesValidators.validators[i_]->method arg2; \
|
static_cast<GenericSchemaValidator*>(context->patternPropertiesValidators.validators[i_])->method arg2; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\
|
#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\
|
||||||
@ -982,18 +1021,17 @@ public:
|
|||||||
#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_
|
#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_
|
||||||
#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_
|
#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_
|
||||||
|
|
||||||
// Implementation of ISchemaValidatorFactory<Encoding>
|
// Implementation of ISchemaValidatorFactory<SchemaType>
|
||||||
GenericSchemaValidator<Encoding>* CreateSchemaValidator(const Schema<Encoding>& root) {
|
virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) const {
|
||||||
return new GenericSchemaValidator(root);
|
return new GenericSchemaValidator(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Schema<Encoding> BaseSchemaType;
|
typedef typename SchemaType::Context Context;
|
||||||
typedef typename BaseSchemaType::Context Context;
|
|
||||||
|
|
||||||
GenericSchemaValidator(
|
GenericSchemaValidator(
|
||||||
const BaseSchemaType& root,
|
const SchemaType& root,
|
||||||
Allocator* allocator = 0,
|
StateAllocator* allocator = 0,
|
||||||
size_t schemaStackCapacity = kDefaultSchemaStackCapacity/*,
|
size_t schemaStackCapacity = kDefaultSchemaStackCapacity/*,
|
||||||
size_t documentStackCapacity = kDefaultDocumentStackCapacity*/)
|
size_t documentStackCapacity = kDefaultDocumentStackCapacity*/)
|
||||||
:
|
:
|
||||||
@ -1013,7 +1051,7 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
SizeType count = CurrentContext().patternPropertiesSchemaCount;
|
SizeType count = CurrentContext().patternPropertiesSchemaCount;
|
||||||
const BaseSchemaType** sa = CurrentContext().patternPropertiesSchemas;
|
const SchemaType** sa = CurrentContext().patternPropertiesSchemas;
|
||||||
PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
|
PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
|
||||||
|
|
||||||
if (CurrentContext().valueSchema)
|
if (CurrentContext().valueSchema)
|
||||||
@ -1021,8 +1059,8 @@ private:
|
|||||||
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
CurrentContext().objectPatternValidatorType = patternValidatorType;
|
CurrentContext().objectPatternValidatorType = patternValidatorType;
|
||||||
SchemaValidatorArray<Encoding>& va = CurrentContext().patternPropertiesValidators;
|
SchemaValidatorArray& va = CurrentContext().patternPropertiesValidators;
|
||||||
va.validators = new GenericSchemaValidator*[count];
|
va.validators = new ISchemaValidator*[count];
|
||||||
for (SizeType i = 0; i < count; i++)
|
for (SizeType i = 0; i < count; i++)
|
||||||
va.validators[va.count++] = CreateSchemaValidator(*sa[i]);
|
va.validators[va.count++] = CreateSchemaValidator(*sa[i]);
|
||||||
}
|
}
|
||||||
@ -1038,22 +1076,22 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PushSchema(const BaseSchemaType& schema) { *schemaStack_.template Push<Context>() = Context(&schema); }
|
void PushSchema(const SchemaType& schema) { *schemaStack_.template Push<Context>() = Context(this, &schema); }
|
||||||
void PopSchema() { schemaStack_.template Pop<Context>(1)->~Context(); }
|
void PopSchema() { schemaStack_.template Pop<Context>(1)->~Context(); }
|
||||||
const BaseSchemaType& CurrentSchema() { return *schemaStack_.template Top<Context>()->schema; }
|
const SchemaType& CurrentSchema() { return *schemaStack_.template Top<Context>()->schema; }
|
||||||
Context& CurrentContext() { return *schemaStack_.template Top<Context>(); }
|
Context& CurrentContext() { return *schemaStack_.template Top<Context>(); }
|
||||||
|
|
||||||
static const size_t kDefaultSchemaStackCapacity = 1024;
|
static const size_t kDefaultSchemaStackCapacity = 1024;
|
||||||
//static const size_t kDefaultDocumentStackCapacity = 256;
|
//static const size_t kDefaultDocumentStackCapacity = 256;
|
||||||
const BaseSchemaType& root_;
|
const SchemaType& root_;
|
||||||
BaseReaderHandler<Encoding> nullOutputHandler_;
|
BaseReaderHandler<EncodingType> nullOutputHandler_;
|
||||||
OutputHandler& outputHandler_;
|
OutputHandler& outputHandler_;
|
||||||
internal::Stack<Allocator> schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *)
|
internal::Stack<StateAllocator> schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *)
|
||||||
//internal::Stack<Allocator> documentStack_; //!< stack to store the current path of validating document (Value *)
|
//internal::Stack<Allocator> documentStack_; //!< stack to store the current path of validating document (Value *)
|
||||||
bool valid_;
|
bool valid_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef GenericSchemaValidator<UTF8<> > SchemaValidator;
|
typedef GenericSchemaValidator<SchemaDocument::SchemaType> SchemaValidator;
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
@ -32,6 +32,12 @@ static const char kJson[] = "{\n"
|
|||||||
" \"m~n\" : 8\n"
|
" \"m~n\" : 8\n"
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
|
TEST(Pointer, DefaultConstructor) {
|
||||||
|
Pointer p;
|
||||||
|
EXPECT_TRUE(p.IsValid());
|
||||||
|
EXPECT_EQ(0u, p.GetTokenCount());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Pointer, Parse) {
|
TEST(Pointer, Parse) {
|
||||||
{
|
{
|
||||||
Pointer p("");
|
Pointer p("");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user