Commit bbbd1c6f authored by miloyip's avatar miloyip

Schema code simplification

parent 838e29f4
...@@ -89,8 +89,8 @@ struct BaseSchemaArray { ...@@ -89,8 +89,8 @@ struct BaseSchemaArray {
template <typename Encoding> template <typename Encoding>
struct SchemaValidationContext { struct SchemaValidationContext {
SchemaValidationContext(/*ISchemaValidatorFactory<Encoding>* factory, */const BaseSchema<Encoding>* s) : SchemaValidationContext(const BaseSchema<Encoding>* s) :
/*schemaValidatorFactory(factory), */schema(s), valueSchema(), multiTypeSchema(), notValidator(), objectDependencies(), inArray(false) schema(s), valueSchema(), multiTypeSchema(), notValidator(), objectDependencies(), inArray(false)
{ {
} }
...@@ -99,7 +99,6 @@ struct SchemaValidationContext { ...@@ -99,7 +99,6 @@ struct SchemaValidationContext {
delete[] objectDependencies; delete[] objectDependencies;
} }
//ISchemaValidatorFactory<Encoding>* schemaValidatorFactory;
const BaseSchema<Encoding>* schema; const BaseSchema<Encoding>* schema;
const BaseSchema<Encoding>* valueSchema; const BaseSchema<Encoding>* valueSchema;
const BaseSchema<Encoding>* multiTypeSchema; const BaseSchema<Encoding>* multiTypeSchema;
...@@ -122,6 +121,7 @@ public: ...@@ -122,6 +121,7 @@ public:
template <typename ValueType> template <typename ValueType>
BaseSchema(const ValueType& value) : BaseSchema(const ValueType& value) :
not_(), not_(),
type_((1 << kTotalSchemaType) - 1), // typeless
properties_(), properties_(),
additionalPropertySchema_(), additionalPropertySchema_(),
#if RAPIDJSON_SCHEMA_HAS_REGEX #if RAPIDJSON_SCHEMA_HAS_REGEX
...@@ -152,328 +152,158 @@ public: ...@@ -152,328 +152,158 @@ public:
exclusiveMinimum_(false), exclusiveMinimum_(false),
exclusiveMaximum_(false) exclusiveMaximum_(false)
{ {
type_ = (1 << kTotalSchemaType) - 1; // typeless typedef typename ValueType::ConstValueIterator ConstValueIterator;
typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
typename ValueType::ConstMemberIterator typeItr = value.FindMember("type");
if (typeItr != value.MemberEnd()) { if (!value.IsObject())
if (typeItr->value.IsString()) { return;
type_ = 0;
AddType(typeItr->value); if (const ValueType* v = GetMember(value, "type")) {
} type_ = 0;
else if (typeItr->value.IsArray()) { if (v->IsString())
type_ = 0; AddType(*v);
for (typename ValueType::ConstValueIterator itr = typeItr->value.Begin(); itr != typeItr->value.End(); ++itr) else if (v->IsArray())
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
AddType(*itr); AddType(*itr);
}
else {
// Error
}
} }
typename ValueType::ConstMemberIterator enumItr = value.FindMember("enum"); if (const ValueType* v = GetMember(value, "enum"))
if (enumItr != value.MemberEnd()) { if (v->IsArray() && v->Size() > 0)
if (enumItr->value.IsArray() && enumItr->value.Size() > 0) enum_.CopyFrom(*v, allocator_);
enum_.CopyFrom(enumItr->value, allocator_);
else {
// Error
}
}
typename ValueType::ConstMemberIterator allOfItr = value.FindMember("allOf");
if (allOfItr != value.MemberEnd())
CreateLogicalSchemas(allOfItr->value, allOf_);
typename ValueType::ConstMemberIterator anyOfItr = value.FindMember("anyOf");
if (anyOfItr != value.MemberEnd())
CreateLogicalSchemas(anyOfItr->value, anyOf_);
typename ValueType::ConstMemberIterator oneOfItr = value.FindMember("oneOf"); AssigIfExist(allOf_, value, "allOf");
if (oneOfItr != value.MemberEnd()) AssigIfExist(anyOf_, value, "anyOf");
CreateLogicalSchemas(oneOfItr->value, oneOf_); AssigIfExist(oneOf_, value, "oneOf");
typename ValueType::ConstMemberIterator notItr = value.FindMember("not"); if (const ValueType* v = GetMember(value, "not"))
if (notItr != value.MemberEnd()) { not_ = new BaseSchema<Encoding>(*v);
if (notItr->value.IsObject())
not_ = new BaseSchema<Encoding>(notItr->value);
}
// Object // Object
typename ValueType::ConstMemberIterator propretiesItr = value.FindMember("properties"); if (const ValueType* v = GetMember(value, "properties"))
if (propretiesItr != value.MemberEnd()) { if (v->IsObject()) {
const ValueType& properties = propretiesItr->value; properties_ = new Property[v->MemberCount()];
properties_ = new Property[properties.MemberCount()]; propertyCount_ = 0;
propertyCount_ = 0; for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {
properties_[propertyCount_].name.SetString(itr->name.GetString(), itr->name.GetStringLength(), allocator_);
for (typename ValueType::ConstMemberIterator propertyItr = properties.MemberBegin(); propertyItr != properties.MemberEnd(); ++propertyItr) { properties_[propertyCount_].schema = new BaseSchema(itr->value);
properties_[propertyCount_].name.SetString(propertyItr->name.GetString(), propertyItr->name.GetStringLength(), BaseSchema<Encoding>::allocator_); propertyCount_++;
properties_[propertyCount_].schema = new BaseSchema(propertyItr->value); // TODO: Check error }
propertyCount_++;
} }
}
#if RAPIDJSON_SCHEMA_HAS_REGEX #if RAPIDJSON_SCHEMA_HAS_REGEX
typename ValueType::ConstMemberIterator patternPropretiesItr = value.FindMember("patternProperties"); if (const ValueType* v = GetMember(value, "patternProperties")) {
if (patternPropretiesItr != value.MemberEnd()) { patternProperties_ = new PatternProperty[v->MemberCount()];
const ValueType& patternProperties = patternPropretiesItr->value;
patternProperties_ = new PatternProperty[patternProperties.MemberCount()];
patternPropertyCount_ = 0; patternPropertyCount_ = 0;
for (typename ValueType::ConstMemberIterator propertyItr = patternProperties.MemberBegin(); propertyItr != patternProperties.MemberEnd(); ++propertyItr) { for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {
#if RAPIDJSON_SCHEMA_USE_STDREGEX patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name);
try { patternProperties_[patternPropertyCount_].schema = new BaseSchema<Encoding>(itr->value); // TODO: Check error
patternProperties_[patternPropertyCount_].pattern = new std::basic_regex<Ch>(
propertyItr->name.GetString(),
std::size_t(propertyItr->name.GetStringLength()),
std::regex_constants::ECMAScript);
}
catch (const std::regex_error&) {
// Error
}
#endif
patternProperties_[patternPropertyCount_].schema = new BaseSchema<Encoding>(propertyItr->value); // TODO: Check error
patternPropertyCount_++; patternPropertyCount_++;
} }
} }
#endif #endif
// Establish required after properties if (const ValueType* v = GetMember(value, "required"))
typename ValueType::ConstMemberIterator requiredItr = value.FindMember("required"); if (v->IsArray())
if (requiredItr != value.MemberEnd()) { for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
if (requiredItr->value.IsArray()) {
for (typename ValueType::ConstValueIterator itr = requiredItr->value.Begin(); itr != requiredItr->value.End(); ++itr) {
if (itr->IsString()) { if (itr->IsString()) {
SizeType index; SizeType index;
if (FindPropertyIndex(*itr, &index)) { if (FindPropertyIndex(*itr, &index)) {
properties_[index].required = true; properties_[index].required = true;
requiredCount_++; requiredCount_++;
} }
else {
// Error
}
} }
else {
// Error
}
}
}
else {
// Error
}
}
// Establish dependencies after properties if (const ValueType* v = GetMember(value, "dependencies"))
typename ValueType::ConstMemberIterator dependenciesItr = value.FindMember("dependencies"); if (v->IsObject()) {
if (dependenciesItr != value.MemberEnd()) {
if (dependenciesItr->value.IsObject()) {
hasDependencies_ = true; hasDependencies_ = true;
for (typename ValueType::ConstMemberIterator itr = dependenciesItr->value.MemberBegin(); itr != dependenciesItr->value.MemberEnd(); ++itr) { for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {
SizeType sourceIndex; SizeType sourceIndex;
if (FindPropertyIndex(itr->name, &sourceIndex)) { if (FindPropertyIndex(itr->name, &sourceIndex)) {
properties_[sourceIndex].dependencies = new bool[propertyCount_];
std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool) * propertyCount_);
if (itr->value.IsArray()) { if (itr->value.IsArray()) {
for (typename ValueType::ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) { properties_[sourceIndex].dependencies = new bool[propertyCount_];
std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_);
for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) {
SizeType targetIndex; SizeType targetIndex;
if (FindPropertyIndex(*targetItr, &targetIndex)) { if (FindPropertyIndex(*targetItr, &targetIndex))
properties_[sourceIndex].dependencies[targetIndex] = true; properties_[sourceIndex].dependencies[targetIndex] = true;
}
else {
// Error
}
} }
} }
else { else if (itr->value.IsObject()) {
// Error // TODO
} }
} }
else {
// Error
}
} }
} }
else {
// Error
}
}
typename ValueType::ConstMemberIterator additionalPropretiesItr = value.FindMember("additionalProperties"); if (const ValueType* v = GetMember(value, "additionalProperties")) {
if (additionalPropretiesItr != value.MemberEnd()) { if (v->IsBool())
if (additionalPropretiesItr->value.IsBool()) additionalProperty_ = v->GetBool();
additionalProperty_ = additionalPropretiesItr->value.GetBool(); else if (v->IsObject())
else if (additionalPropretiesItr->value.IsObject()) additionalPropertySchema_ = new BaseSchema<Encoding>(*v);
additionalPropertySchema_ = new BaseSchema<Encoding>(additionalPropretiesItr->value);
else {
// Error
}
} }
typename ValueType::ConstMemberIterator minPropertiesItr = value.FindMember("minProperties"); AssignIfExist(minProperties_, value, "minProperties");
if (minPropertiesItr != value.MemberEnd()) { AssignIfExist(maxProperties_, value, "maxProperties");
if (minPropertiesItr->value.IsUint64() && minPropertiesItr->value.GetUint64() <= SizeType(~0))
minProperties_ = static_cast<SizeType>(minPropertiesItr->value.GetUint64());
else {
// Error
}
}
typename ValueType::ConstMemberIterator maxPropertiesItr = value.FindMember("maxProperties");
if (maxPropertiesItr != value.MemberEnd()) {
if (maxPropertiesItr->value.IsUint64() && maxPropertiesItr->value.GetUint64() <= SizeType(~0))
maxProperties_ = static_cast<SizeType>(maxPropertiesItr->value.GetUint64());
else {
// Error
}
}
// Array // Array
typename ValueType::ConstMemberIterator itemsItr = value.FindMember("items"); if (const ValueType* v = GetMember(value, "items")) {
if (itemsItr != value.MemberEnd()) { if (v->IsObject()) // List validation
if (itemsItr->value.IsObject()) itemsList_ = new BaseSchema<Encoding>(*v);
itemsList_ = new BaseSchema<Encoding>(itemsItr->value); // List validation else if (v->IsArray()) { // Tuple validation
else if (itemsItr->value.IsArray()) { itemsTuple_ = new BaseSchema<Encoding>*[v->Size()];
// Tuple validation for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
itemsTuple_ = new BaseSchema<Encoding>*[itemsItr->value.Size()]; itemsTuple_[itemsTupleCount_++] = new BaseSchema<Encoding>(*itr);
for (typename ValueType::ConstValueIterator itr = itemsItr->value.Begin(); itr != itemsItr->value.End(); ++itr) {
itemsTuple_[itemsTupleCount_] = new BaseSchema<Encoding>(*itr);
itemsTupleCount_++;
}
}
else {
// Error
}
}
typename ValueType::ConstMemberIterator minItemsItr = value.FindMember("minItems");
if (minItemsItr != value.MemberEnd()) {
if (minItemsItr->value.IsUint64() && minItemsItr->value.GetUint64() <= SizeType(~0))
minItems_ = static_cast<SizeType>(minItemsItr->value.GetUint64());
else {
// Error
} }
} }
typename ValueType::ConstMemberIterator maxItemsItr = value.FindMember("maxItems"); AssignIfExist(minItems_, value, "minItems");
if (maxItemsItr != value.MemberEnd()) { AssignIfExist(maxItems_, value, "maxItems");
if (maxItemsItr->value.IsUint64() && maxItemsItr->value.GetUint64() <= SizeType(~0)) AssignIfExist(additionalItems_, value, "additionalItems");
maxItems_ = static_cast<SizeType>(maxItemsItr->value.GetUint64());
else {
// Error
}
}
typename ValueType::ConstMemberIterator additionalItemsItr = value.FindMember("additionalItems");
if (additionalItemsItr != value.MemberEnd()) {
if (additionalItemsItr->value.IsBool())
additionalItems_ = additionalItemsItr->value.GetBool();
else {
// Error
}
}
// String // String
typename ValueType::ConstMemberIterator minLengthItr = value.FindMember("minLength"); AssignIfExist(minLength_, value, "minLength");
if (minLengthItr != value.MemberEnd()) { AssignIfExist(maxLength_, value, "maxLength");
if (minLengthItr->value.IsUint64() && minLengthItr->value.GetUint64() <= ~SizeType(0))
minLength_ = static_cast<SizeType>(minLengthItr->value.GetUint64());
else {
// Error
}
}
typename ValueType::ConstMemberIterator maxLengthItr = value.FindMember("maxLength");
if (maxLengthItr != value.MemberEnd()) {
if (maxLengthItr->value.IsUint64() && maxLengthItr->value.GetUint64() <= ~SizeType(0))
maxLength_ = static_cast<SizeType>(maxLengthItr->value.GetUint64());
else {
// Error
}
}
#if RAPIDJSON_SCHEMA_HAS_REGEX #if RAPIDJSON_SCHEMA_HAS_REGEX
typename ValueType::ConstMemberIterator patternItr = value.FindMember("pattern"); if (const ValueType* v = GetMember(value, "pattern"))
if (patternItr != value.MemberEnd()) { pattern_ = CreatePattern(*v);
if (patternItr->value.IsString()) {
#if RAPIDJSON_SCHEMA_USE_STDREGEX
try {
pattern_ = new std::basic_regex<Ch>(
patternItr->value.GetString(),
std::size_t(patternItr->value.GetStringLength()),
std::regex_constants::ECMAScript);
}
catch (const std::regex_error&) {
// Error
}
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
}
else {
// Error
}
}
#endif // RAPIDJSON_SCHEMA_HAS_REGEX #endif // RAPIDJSON_SCHEMA_HAS_REGEX
// Number // Number
typename ValueType::ConstMemberIterator minimumItr = value.FindMember("minimum"); ConstMemberIterator minimumItr = value.FindMember("minimum");
if (minimumItr != value.MemberEnd()) { if (minimumItr != value.MemberEnd())
if (minimumItr->value.IsNumber()) if (minimumItr->value.IsNumber())
minimum_ = minimumItr->value.GetDouble(); minimum_ = minimumItr->value.GetDouble();
else {
// Error
}
}
typename ValueType::ConstMemberIterator maximumItr = value.FindMember("maximum"); ConstMemberIterator maximumItr = value.FindMember("maximum");
if (maximumItr != value.MemberEnd()) { if (maximumItr != value.MemberEnd())
if (maximumItr->value.IsNumber()) if (maximumItr->value.IsNumber())
maximum_ = maximumItr->value.GetDouble(); maximum_ = maximumItr->value.GetDouble();
else {
// Error
}
}
typename ValueType::ConstMemberIterator exclusiveMinimumItr = value.FindMember("exclusiveMinimum"); AssignIfExist(exclusiveMinimum_, value, "exclusiveMinimum");
if (exclusiveMinimumItr != value.MemberEnd()) { AssignIfExist(exclusiveMaximum_, value, "exclusiveMaximum");
if (exclusiveMinimumItr->value.IsBool())
exclusiveMinimum_ = exclusiveMinimumItr->value.GetBool();
else {
// Error
}
}
typename ValueType::ConstMemberIterator exclusiveMaximumItr = value.FindMember("exclusiveMaximum");
if (exclusiveMaximumItr != value.MemberEnd()) {
if (exclusiveMaximumItr->value.IsBool())
exclusiveMaximum_ = exclusiveMaximumItr->value.GetBool();
else {
// Error
}
}
typename ValueType::ConstMemberIterator multipleOfItr = value.FindMember("multipleOf"); ConstMemberIterator multipleOfItr = value.FindMember("multipleOf");
if (multipleOfItr != value.MemberEnd()) { if (multipleOfItr != value.MemberEnd()) {
if (multipleOfItr->value.IsNumber()) { if (multipleOfItr->value.IsNumber()) {
multipleOf_ = multipleOfItr->value.GetDouble(); multipleOf_ = multipleOfItr->value.GetDouble();
hasMultipleOf_ = true; hasMultipleOf_ = true;
} }
else {
// Error
}
} }
} }
~BaseSchema() { ~BaseSchema() {
delete not_; delete not_;
delete [] properties_; delete [] properties_;
delete additionalPropertySchema_; delete additionalPropertySchema_;
#if RAPIDJSON_SCHEMA_HAS_REGEX #if RAPIDJSON_SCHEMA_HAS_REGEX
delete [] patternProperties_; delete [] patternProperties_;
#endif #endif
delete itemsList_; delete itemsList_;
for (SizeType i = 0; i < itemsTupleCount_; i++) for (SizeType i = 0; i < itemsTupleCount_; i++)
delete itemsTuple_[i]; delete itemsTuple_[i];
delete [] itemsTuple_; delete [] itemsTuple_;
#if RAPIDJSON_SCHEMA_USE_STDREGEX #if RAPIDJSON_SCHEMA_USE_STDREGEX
delete pattern_; delete pattern_;
#endif #endif
...@@ -500,21 +330,19 @@ public: ...@@ -500,21 +330,19 @@ public:
} }
bool EndValue(Context& context) const { bool EndValue(Context& context) const {
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())
return false; return false;
}
if (anyOf_.schemas) { if (anyOf_.schemas) {
bool anyValid = false;
for (SizeType i_ = 0; i_ < anyOf_.count; i_++) for (SizeType i_ = 0; i_ < anyOf_.count; i_++)
if (context.anyOfValidators.validators[i_]->IsValid()) { if (context.anyOfValidators.validators[i_]->IsValid())
anyValid = true; goto foundAny;
break; return false;
} foundAny:;
if (!anyValid)
return false;
} }
if (oneOf_.schemas) { if (oneOf_.schemas) {
CreateSchemaValidators(context, context.oneOfValidators, oneOf_); CreateSchemaValidators(context, context.oneOfValidators, oneOf_);
bool oneValid = false; bool oneValid = false;
...@@ -528,11 +356,8 @@ public: ...@@ -528,11 +356,8 @@ public:
if (!oneValid) if (!oneValid)
return false; return false;
} }
if (not_) {
if (context.notValidator->IsValid()) return !not_ || !context.notValidator->IsValid();
return false;
}
return true;
} }
bool Null(Context& context) const { bool Null(Context& context) const {
...@@ -599,14 +424,9 @@ public: ...@@ -599,14 +424,9 @@ public:
return false; return false;
#if RAPIDJSON_SCHEMA_HAS_REGEX #if RAPIDJSON_SCHEMA_HAS_REGEX
if (pattern_) { if (pattern_ && !IsPatternMatch(*pattern_, str, length))
#if RAPIDJSON_SCHEMA_USE_STDREGEX return false;
std::match_results<const Ch*> r; #endif
if (!std::regex_search(str, str + length, r, *pattern_))
return false;
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
}
#endif // RAPIDJSON_SCHEMA_HAS_REGEX
return !enum_.IsArray() || CheckEnum(GenericValue<Encoding>(str, length).Move()); return !enum_.IsArray() || CheckEnum(GenericValue<Encoding>(str, length).Move());
} }
...@@ -643,19 +463,12 @@ public: ...@@ -643,19 +463,12 @@ public:
} }
#if RAPIDJSON_SCHEMA_HAS_REGEX #if RAPIDJSON_SCHEMA_HAS_REGEX
if (patternProperties_) { if (patternProperties_)
for (SizeType i = 0; i < patternPropertyCount_; i++) { for (SizeType i = 0; i < patternPropertyCount_; i++)
#if RAPIDJSON_SCHEMA_USE_STDREGEX if (patternProperties_[i].pattern && IsPatternMatch(*patternProperties_[i].pattern, str, len)) {
if (patternProperties_[i].pattern) { context.valueSchema = patternProperties_[i].schema;
std::match_results<const Ch*> r; return true;
if (std::regex_search(str, str + len, r, *patternProperties_[i].pattern)) {
context.valueSchema = patternProperties_[i].schema;
return true;
}
} }
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
}
}
#endif #endif
if (additionalPropertySchema_) { if (additionalPropertySchema_) {
...@@ -678,13 +491,12 @@ public: ...@@ -678,13 +491,12 @@ public:
if (context.objectRequiredCount != requiredCount_ || memberCount < minProperties_ || memberCount > maxProperties_) if (context.objectRequiredCount != requiredCount_ || memberCount < minProperties_ || memberCount > maxProperties_)
return false; return false;
if (hasDependencies_) { if (hasDependencies_)
for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++)
if (context.objectDependencies[sourceIndex] && properties_[sourceIndex].dependencies) if (context.objectDependencies[sourceIndex] && properties_[sourceIndex].dependencies)
for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++) for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++)
if (properties_[sourceIndex].dependencies[targetIndex] && !context.objectDependencies[targetIndex]) if (properties_[sourceIndex].dependencies[targetIndex] && !context.objectDependencies[targetIndex])
return false; return false;
}
return true; return true;
} }
...@@ -708,39 +520,70 @@ public: ...@@ -708,39 +520,70 @@ public:
return elementCount >= minItems_ && elementCount <= maxItems_; return elementCount >= minItems_ && elementCount <= maxItems_;
} }
#undef RAPIDJSON_BASESCHEMA_HANDLER_LGOICAL_ private:
#undef RAPIDJSON_BASESCHEMA_HANDLER_
protected:
static const BaseSchema<Encoding>* GetTypeless() { static const BaseSchema<Encoding>* GetTypeless() {
static BaseSchema<Encoding> typeless(Value(kObjectType).Move()); static BaseSchema<Encoding> typeless(Value(kObjectType).Move());
return &typeless; return &typeless;
} }
void AddType(const Value& type) { template <typename ValueType>
if (type == Value("null" ).Move()) type_ |= 1 << kNullSchemaType; static const ValueType* GetMember(const ValueType& value, const char* name) {
else if (type == Value("boolean").Move()) type_ |= 1 << kBooleanSchemaType; typename ValueType::ConstMemberIterator itr = value.FindMember(name);
else if (type == Value("object" ).Move()) type_ |= 1 << kObjectSchemaType; return itr != value.MemberEnd() ? &(itr->value) : 0;
else if (type == Value("array" ).Move()) type_ |= 1 << kArraySchemaType;
else if (type == Value("string" ).Move()) type_ |= 1 << kStringSchemaType;
else if (type == Value("integer").Move()) type_ |= 1 << kIntegerSchemaType;
else if (type == Value("number" ).Move()) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
else {
// Error
}
} }
void CreateLogicalSchemas(const Value& logic, BaseSchemaArray<Encoding>& logicSchemas) { template <typename ValueType>
if (logic.IsArray() && logic.Size() > 0) { static void AssignIfExist(bool& out, const ValueType& value, const char* name) {
logicSchemas.count = logic.Size(); if (const ValueType* v = GetMember(value, name))
logicSchemas.schemas = new BaseSchema*[logicSchemas.count]; if (v->IsBool())
memset(logicSchemas.schemas, 0, sizeof(BaseSchema*) * logicSchemas.count); out = v->GetBool();
for (SizeType i = 0; i < logicSchemas.count; i++) }
logicSchemas.schemas[i] = new BaseSchema<Encoding>(logic[i]);
} template <typename ValueType>
else { static void AssignIfExist(SizeType& out, const ValueType& value, const char* name) {
// Error if (const ValueType* v = GetMember(value, name))
} if (v->IsUint64() && v->GetUint64() <= SizeType(~0))
out = static_cast<SizeType>(v->GetUint64());
}
template <typename ValueType>
static void AssigIfExist(BaseSchemaArray<Encoding>& out, const ValueType& value, const char* name) {
if (const ValueType* v = GetMember(value, name))
if (v->IsArray() && v->Size() > 0) {
out.count = v->Size();
out.schemas = new BaseSchema*[out.count];
memset(out.schemas, 0, sizeof(BaseSchema*)* out.count);
for (SizeType i = 0; i < out.count; i++)
out.schemas[i] = new BaseSchema<Encoding>((*v)[i]);
}
}
#if RAPIDJSON_SCHEMA_USE_STDREGEX
template <typename ValueType>
static std::basic_regex<Ch>* CreatePattern(const ValueType& value) {
if (value.IsString())
try {
return new std::basic_regex<Ch>(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);
}
catch (const std::regex_error&) {
}
return 0;
}
static bool IsPatternMatch(const std::basic_regex<Ch>& pattern, const Ch *str, SizeType length) {
std::match_results<const Ch*> r;
return std::regex_search(str, str + length, r, pattern);
}
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
void AddType(const Value& type) {
if (type == "null" ) type_ |= 1 << kNullSchemaType;
else if (type == "boolean") type_ |= 1 << kBooleanSchemaType;
else if (type == "object" ) type_ |= 1 << kObjectSchemaType;
else if (type == "array" ) type_ |= 1 << kArraySchemaType;
else if (type == "string" ) type_ |= 1 << kStringSchemaType;
else if (type == "integer") type_ |= 1 << kIntegerSchemaType;
else if (type == "number" ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
} }
bool CheckEnum(const GenericValue<Encoding>& v) const { bool CheckEnum(const GenericValue<Encoding>& v) const {
...@@ -755,7 +598,7 @@ protected: ...@@ -755,7 +598,7 @@ protected:
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_);
if (not_ && !context.notValidator) if (not_ && !context.notValidator)
context.notValidator = new GenericSchemaValidator<Encoding>(*not_);//context.schemaValidatorFactory->CreateSchemaValidator(*not_); context.notValidator = new GenericSchemaValidator<Encoding>(*not_);
} }
void CreateSchemaValidators(Context& context, SchemaValidatorArray<Encoding>& validators, const BaseSchemaArray<Encoding>& schemas) const { void CreateSchemaValidators(Context& context, SchemaValidatorArray<Encoding>& validators, const BaseSchemaArray<Encoding>& schemas) const {
...@@ -770,25 +613,21 @@ protected: ...@@ -770,25 +613,21 @@ protected:
// O(n) // O(n)
template <typename ValueType> template <typename ValueType>
bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const { bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const {
for (SizeType index = 0; index < propertyCount_; index++) { for (SizeType index = 0; index < propertyCount_; index++)
if (properties_[index].name == name) { if (properties_[index].name == name) {
*outIndex = index; *outIndex = index;
return true; return true;
} }
}
return false; return false;
} }
// O(n) // O(n)
bool FindPropertyIndex(const Ch* str, SizeType length, SizeType* outIndex) const { bool FindPropertyIndex(const Ch* str, SizeType length, SizeType* outIndex) const {
for (SizeType index = 0; index < propertyCount_; index++) { for (SizeType index = 0; index < propertyCount_; index++)
if (properties_[index].name.GetStringLength() == length && if (properties_[index].name.GetStringLength() == length && std::memcmp(properties_[index].name.GetString(), str, length) == 0) {
std::memcmp(properties_[index].name.GetString(), str, length) == 0)
{
*outIndex = index; *outIndex = index;
return true; return true;
} }
}
return false; return false;
} }
...@@ -884,8 +723,6 @@ public: ...@@ -884,8 +723,6 @@ public:
delete root_; delete root_;
} }
bool IsValid() const { return root_ != 0; }
private: private:
BaseSchema<Encoding>* root_; BaseSchema<Encoding>* root_;
}; };
......
...@@ -21,7 +21,6 @@ using namespace rapidjson; ...@@ -21,7 +21,6 @@ using namespace rapidjson;
#define VALIDATE(schema, json, expected) \ #define VALIDATE(schema, json, expected) \
{\ {\
ASSERT_TRUE(schema.IsValid());\
SchemaValidator validator(schema);\ SchemaValidator validator(schema);\
Document d;\ Document d;\
/*printf("\n%s\n", json);*/\ /*printf("\n%s\n", json);*/\
......
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