diff --git a/include/rapidjson/schema.h b/include/rapidjson/schema.h index cfdcb62..00dfe11 100644 --- a/include/rapidjson/schema.h +++ b/include/rapidjson/schema.h @@ -42,16 +42,8 @@ RAPIDJSON_DIAG_OFF(effc++) RAPIDJSON_NAMESPACE_BEGIN -enum SchemaValueType { - kNullSchemaType, - kBooleanSchemaType, - kObjectSchemaType, - kArraySchemaType, - kStringSchemaType, - kNumberSchemaType, - kIntegerSchemaType, - kTotalSchemaType -}; +/////////////////////////////////////////////////////////////////////////////// +// Forward declarations template class Schema; @@ -59,8 +51,8 @@ class Schema; template class GenericSchemaDocument; -template -class GenericSchemaValidator; +/////////////////////////////////////////////////////////////////////////////// +// ISchemaValidator class ISchemaValidator { public: @@ -68,6 +60,9 @@ public: virtual bool IsValid() const = 0; }; +/////////////////////////////////////////////////////////////////////////////// +// ISchemaValidatorFactory + template 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 struct SchemaArray { SchemaArray() : schemas(), count() {} @@ -94,22 +95,24 @@ struct SchemaArray { delete[] schemas; } - Schema** schemas; + const Schema** schemas; SizeType count; }; -enum PatternValidatorType { - kPatternValidatorOnly, - kPatternValidatorWithProperty, - kPatternValidatorWithAdditionalProperty -}; +/////////////////////////////////////////////////////////////////////////////// +// SchemaValidationContext template struct SchemaValidationContext { typedef Schema SchemaType; - typedef GenericSchemaValidator, CrtAllocator> SchemaValidatorType; typedef ISchemaValidatorFactory SchemaValidatorFactoryType; + enum PatternValidatorType { + kPatternValidatorOnly, + kPatternValidatorWithProperty, + kPatternValidatorWithAdditionalProperty + }; + SchemaValidationContext(const SchemaValidatorFactoryType* f, const SchemaType* s) : factory(f), schema(s), @@ -151,6 +154,9 @@ struct SchemaValidationContext { bool inArray; }; +/////////////////////////////////////////////////////////////////////////////// +// Schema + template class Schema { public: @@ -160,10 +166,10 @@ public: typedef GenericSchemaDocument SchemaDocumentType; typedef Schema SchemaType; typedef GenericValue ValueType; - typedef GenericPointer PointerType; + // typedef GenericPointer PointerType; friend class GenericSchemaDocument; - template + template 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 RegexType; #else typedef char RegexType; #endif - typedef GenericSchemaValidator, CrtAllocator> SchemaValidatorType; typedef SchemaArray 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(v->GetUint64()); } - template + template 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 > class GenericSchemaDocument { public: @@ -930,7 +948,7 @@ private: }; template - SchemaType* CreateSchema(const GenericPointer& pointer, const ValueType& v) { + const SchemaType* CreateSchema(const GenericPointer& pointer, const ValueType& v) { RAPIDJSON_ASSERT(pointer.IsValid()); SchemaType* schema = new SchemaType(this, pointer, v); new (schemaMap_.template Push >()) SchemaEntry(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 schemaMap_; // Stores created Pointer -> Schemas @@ -959,6 +977,9 @@ private: typedef GenericSchemaDocument > SchemaDocument; +/////////////////////////////////////////////////////////////////////////////// +// GenericSchemaValidator + template , typename StateAllocator = CrtAllocator > class GenericSchemaValidator : public ISchemaValidatorFactory, 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);