Clean up schema

This commit is contained in:
miloyip 2015-05-09 14:22:04 +08:00
parent f0c3fa84fc
commit 422aebf3ac

View File

@ -42,16 +42,8 @@ RAPIDJSON_DIAG_OFF(effc++)
RAPIDJSON_NAMESPACE_BEGIN
enum SchemaValueType {
kNullSchemaType,
kBooleanSchemaType,
kObjectSchemaType,
kArraySchemaType,
kStringSchemaType,
kNumberSchemaType,
kIntegerSchemaType,
kTotalSchemaType
};
///////////////////////////////////////////////////////////////////////////////
// Forward declarations
template <typename Encoding, typename Allocator>
class Schema;
@ -59,8 +51,8 @@ class Schema;
template <typename Encoding, typename Allocator>
class GenericSchemaDocument;
template <typename Encoding, typename OutputHandler, typename StateAllocator>
class GenericSchemaValidator;
///////////////////////////////////////////////////////////////////////////////
// ISchemaValidator
class ISchemaValidator {
public:
@ -68,6 +60,9 @@ public:
virtual bool IsValid() const = 0;
};
///////////////////////////////////////////////////////////////////////////////
// ISchemaValidatorFactory
template <typename SchemaType>
class ISchemaValidatorFactory {
public:
@ -75,6 +70,9 @@ public:
virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) const = 0;
};
///////////////////////////////////////////////////////////////////////////////
// SchemaValidatorArray
struct SchemaValidatorArray {
SchemaValidatorArray() : validators(), count() {}
~SchemaValidatorArray() {
@ -87,6 +85,9 @@ struct SchemaValidatorArray {
SizeType count;
};
///////////////////////////////////////////////////////////////////////////////
// SchemaArray
template <typename Encoding, typename Allocator>
struct SchemaArray {
SchemaArray() : schemas(), count() {}
@ -94,22 +95,24 @@ struct SchemaArray {
delete[] schemas;
}
Schema<Encoding, Allocator>** schemas;
const Schema<Encoding, Allocator>** schemas;
SizeType count;
};
///////////////////////////////////////////////////////////////////////////////
// SchemaValidationContext
template <typename Encoding, typename Allocator>
struct SchemaValidationContext {
typedef Schema<Encoding, Allocator> SchemaType;
typedef ISchemaValidatorFactory<SchemaType> SchemaValidatorFactoryType;
enum PatternValidatorType {
kPatternValidatorOnly,
kPatternValidatorWithProperty,
kPatternValidatorWithAdditionalProperty
};
template <typename Encoding, typename Allocator>
struct SchemaValidationContext {
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),
@ -151,6 +154,9 @@ struct SchemaValidationContext {
bool inArray;
};
///////////////////////////////////////////////////////////////////////////////
// Schema
template <typename Encoding, typename Allocator>
class Schema {
public:
@ -160,10 +166,10 @@ public:
typedef GenericSchemaDocument<Encoding, Allocator> SchemaDocumentType;
typedef Schema<Encoding, Allocator> SchemaType;
typedef GenericValue<Encoding, Allocator> ValueType;
typedef GenericPointer<ValueType> PointerType;
// typedef GenericPointer<ValueType> PointerType;
friend class GenericSchemaDocument<Encoding, Allocator>;
template <typename ValueType>
template <typename ValueType, typename PointerType>
Schema(SchemaDocumentType* document, const PointerType& p, const ValueType& value) :
not_(),
ref_(),
@ -334,7 +340,7 @@ public:
itemsList_ = document->CreateSchema(p, *v);
else if (v->IsArray()) { // Tuple validation
PointerType q = p.Append("items");
itemsTuple_ = new Schema*[v->Size()];
itemsTuple_ = new const Schema*[v->Size()];
SizeType index = 0;
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++)
itemsTuple_[itemsTupleCount_++] = document->CreateSchema(q.Append(index), *itr);
@ -416,7 +422,7 @@ public:
if (context.patternPropertiesValidators.count > 0) {
bool otherValid = false;
SizeType count = context.patternPropertiesValidators.count;
if (context.objectPatternValidatorType != kPatternValidatorOnly)
if (context.objectPatternValidatorType != Context::kPatternValidatorOnly)
otherValid = context.patternPropertiesValidators.validators[--count]->IsValid();
bool patternValid = true;
@ -426,11 +432,11 @@ public:
break;
}
if (context.objectPatternValidatorType == kPatternValidatorOnly) {
if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) {
if (!patternValid)
return false;
}
else if (context.objectPatternValidatorType == kPatternValidatorWithProperty) {
else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) {
if (!patternValid || !otherValid)
return false;
}
@ -579,7 +585,7 @@ public:
if (context.patternPropertiesSchemaCount > 0) {
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = propertySchema;
context.valueSchema = GetTypeless();
context.valuePatternValidatorType = kPatternValidatorWithProperty;
context.valuePatternValidatorType = Context::kPatternValidatorWithProperty;
}
else
context.valueSchema = propertySchema;
@ -597,7 +603,7 @@ public:
if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) {
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_;
context.valueSchema = GetTypeless();
context.valuePatternValidatorType = kPatternValidatorWithAdditionalProperty;
context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty;
}
else
context.valueSchema = additionalPropertiesSchema_;
@ -648,18 +654,27 @@ public:
}
private:
enum SchemaValueType {
kNullSchemaType,
kBooleanSchemaType,
kObjectSchemaType,
kArraySchemaType,
kStringSchemaType,
kNumberSchemaType,
kIntegerSchemaType,
kTotalSchemaType
};
#if RAPIDJSON_SCHEMA_USE_STDREGEX
typedef std::basic_regex<Ch> RegexType;
#else
typedef char RegexType;
#endif
typedef GenericSchemaValidator<Encoding, BaseReaderHandler<>, CrtAllocator> SchemaValidatorType;
typedef SchemaArray<Encoding, Allocator> SchemaArrayType;
typedef SchemaValidatorArray SchemaValidatorArrayType;
static const SchemaType* GetTypeless() {
static SchemaType typeless(0, PointerType(), Value(kObjectType).Move());
static SchemaType typeless(0, Pointer(), Value(kObjectType).Move());
return &typeless;
}
@ -692,13 +707,13 @@ private:
out = static_cast<SizeType>(v->GetUint64());
}
template <typename DocumentType, typename ValueType>
template <typename DocumentType, typename ValueType, typename PointerType>
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 (v->IsArray() && v->Size() > 0) {
PointerType q = p.Append(name);
out.count = v->Size();
out.schemas = new Schema*[out.count];
out.schemas = new const Schema*[out.count];
memset(out.schemas, 0, sizeof(Schema*)* out.count);
for (SizeType i = 0; i < out.count; i++)
out.schemas[i] = document->CreateSchema(q.Append(i), (*v)[i]);
@ -763,7 +778,7 @@ private:
}
}
void CreateSchemaValidators(Context& context, SchemaValidatorArrayType& validators, const SchemaArrayType& schemas) const {
void CreateSchemaValidators(Context& context, SchemaValidatorArray& validators, const SchemaArrayType& schemas) const {
if (!validators.validators) {
validators.validators = new ISchemaValidator*[schemas.count];
validators.count = schemas.count;
@ -820,8 +835,8 @@ private:
struct PatternProperty {
PatternProperty() : schema(), pattern() {}
~PatternProperty() { delete pattern; }
SchemaType* schema;
RegexType* pattern;
const SchemaType* schema;
const RegexType* pattern;
};
Allocator allocator_;
@ -829,12 +844,12 @@ private:
SchemaArrayType allOf_;
SchemaArrayType anyOf_;
SchemaArrayType oneOf_;
SchemaType* not_;
SchemaType* ref_;
const SchemaType* not_;
const SchemaType* ref_;
unsigned type_; // bitmask of kSchemaType
Property* properties_;
SchemaType* additionalPropertiesSchema_;
const SchemaType* additionalPropertiesSchema_;
PatternProperty* patternProperties_;
SizeType patternPropertyCount_;
SizeType propertyCount_;
@ -845,15 +860,15 @@ private:
bool hasDependencies_;
bool hasSchemaDependencies_;
SchemaType* additionalItemsSchema_;
SchemaType* itemsList_;
SchemaType** itemsTuple_;
const SchemaType* additionalItemsSchema_;
const SchemaType* itemsList_;
const SchemaType** itemsTuple_;
SizeType itemsTupleCount_;
SizeType minItems_;
SizeType maxItems_;
bool additionalItems_;
RegexType* pattern_;
const RegexType* pattern_;
SizeType minLength_;
SizeType maxLength_;
@ -865,6 +880,9 @@ private:
bool exclusiveMaximum_;
};
///////////////////////////////////////////////////////////////////////////////
// GenericSchemaDocument
template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
class GenericSchemaDocument {
public:
@ -930,7 +948,7 @@ private:
};
template <typename ValueType>
SchemaType* CreateSchema(const GenericPointer<ValueType>& pointer, const ValueType& v) {
const SchemaType* CreateSchema(const GenericPointer<ValueType>& pointer, const ValueType& v) {
RAPIDJSON_ASSERT(pointer.IsValid());
SchemaType* schema = new SchemaType(this, pointer, v);
new (schemaMap_.template Push<SchemaEntry<ValueType> >()) SchemaEntry<ValueType>(pointer, schema);
@ -950,7 +968,7 @@ private:
static const size_t kInitialSchemaMapSize = 1024;
static const size_t kInitialSchemaRefSize = 1024;
SchemaType* root_; //!< Root schema.
const SchemaType* root_; //!< Root schema.
SchemaType** schemas_; //!< ALl schemas are owned by SchemaDocument
size_t schemaCount_; //!< Number of schemas owned
internal::Stack<Allocator> schemaMap_; // Stores created Pointer -> Schemas
@ -959,6 +977,9 @@ private:
typedef GenericSchemaDocument<UTF8<> > SchemaDocument;
///////////////////////////////////////////////////////////////////////////////
// GenericSchemaValidator
template <typename SchemaType, typename OutputHandler = BaseReaderHandler<typename SchemaType::EncodingType>, typename StateAllocator = CrtAllocator >
class GenericSchemaValidator : public ISchemaValidatorFactory<SchemaType>, public ISchemaValidator {
public:
@ -1124,7 +1145,7 @@ private:
SizeType count = CurrentContext().patternPropertiesSchemaCount;
const SchemaType** sa = CurrentContext().patternPropertiesSchemas;
PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
if (CurrentContext().valueSchema)
PushSchema(*CurrentContext().valueSchema);