Add schema map in SchemaDocument
This commit is contained in:
parent
0e4c368952
commit
74f1bc582b
@ -217,7 +217,7 @@ public:
|
|||||||
AssigIfExist(oneOf_, document, p, value, "oneOf");
|
AssigIfExist(oneOf_, document, p, value, "oneOf");
|
||||||
|
|
||||||
if (const ValueType* v = GetMember(value, "not"))
|
if (const ValueType* v = GetMember(value, "not"))
|
||||||
not_ = document->CreateSchema(p, *v);
|
not_ = document->CreateSchema(p.Append("not"), *v);
|
||||||
|
|
||||||
// Object
|
// Object
|
||||||
|
|
||||||
@ -256,22 +256,25 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties && properties->IsObject())
|
if (properties && properties->IsObject()) {
|
||||||
|
PointerType q = p.Append("properties");
|
||||||
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 = document->CreateSchema(p, itr->value);
|
properties_[index].schema = document->CreateSchema(q.Append(itr->name), itr->value);
|
||||||
properties_[index].typeless = false;
|
properties_[index].typeless = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (const ValueType* v = GetMember(value, "patternProperties")) {
|
if (const ValueType* v = GetMember(value, "patternProperties")) {
|
||||||
|
PointerType q = p.Append("patternProperties");
|
||||||
patternProperties_ = new PatternProperty[v->MemberCount()];
|
patternProperties_ = new PatternProperty[v->MemberCount()];
|
||||||
patternPropertyCount_ = 0;
|
patternPropertyCount_ = 0;
|
||||||
|
|
||||||
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 = document->CreateSchema(p, itr->value);
|
patternProperties_[patternPropertyCount_].schema = document->CreateSchema(q.Append(itr->name), itr->value);
|
||||||
patternPropertyCount_++;
|
patternPropertyCount_++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -287,6 +290,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dependencies && dependencies->IsObject()) {
|
if (dependencies && dependencies->IsObject()) {
|
||||||
|
PointerType q = p.Append("dependencies");
|
||||||
hasDependencies_ = true;
|
hasDependencies_ = true;
|
||||||
for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {
|
for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {
|
||||||
SizeType sourceIndex;
|
SizeType sourceIndex;
|
||||||
@ -302,7 +306,7 @@ public:
|
|||||||
}
|
}
|
||||||
else if (itr->value.IsObject()) {
|
else if (itr->value.IsObject()) {
|
||||||
hasSchemaDependencies_ = true;
|
hasSchemaDependencies_ = true;
|
||||||
properties_[sourceIndex].dependenciesSchema = document->CreateSchema(p, itr->value);
|
properties_[sourceIndex].dependenciesSchema = document->CreateSchema(q.Append(itr->name), itr->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,7 +316,7 @@ public:
|
|||||||
if (v->IsBool())
|
if (v->IsBool())
|
||||||
additionalProperties_ = v->GetBool();
|
additionalProperties_ = v->GetBool();
|
||||||
else if (v->IsObject())
|
else if (v->IsObject())
|
||||||
additionalPropertiesSchema_ = document->CreateSchema(p, *v);
|
additionalPropertiesSchema_ = document->CreateSchema(p.Append("additionalProperties"), *v);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssignIfExist(minProperties_, value, "minProperties");
|
AssignIfExist(minProperties_, value, "minProperties");
|
||||||
@ -323,9 +327,11 @@ public:
|
|||||||
if (v->IsObject()) // List validation
|
if (v->IsObject()) // List validation
|
||||||
itemsList_ = document->CreateSchema(p, *v);
|
itemsList_ = document->CreateSchema(p, *v);
|
||||||
else if (v->IsArray()) { // Tuple validation
|
else if (v->IsArray()) { // Tuple validation
|
||||||
|
PointerType q = p.Append("items");
|
||||||
itemsTuple_ = new Schema*[v->Size()];
|
itemsTuple_ = new Schema*[v->Size()];
|
||||||
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
|
SizeType index = 0;
|
||||||
itemsTuple_[itemsTupleCount_++] = document->CreateSchema(p, *itr);
|
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++)
|
||||||
|
itemsTuple_[itemsTupleCount_++] = document->CreateSchema(q.Append(index), *itr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +342,7 @@ public:
|
|||||||
if (v->IsBool())
|
if (v->IsBool())
|
||||||
additionalItems_ = v->GetBool();
|
additionalItems_ = v->GetBool();
|
||||||
else if (v->IsObject())
|
else if (v->IsObject())
|
||||||
additionalItemsSchema_ = document->CreateSchema(p, *v);
|
additionalItemsSchema_ = document->CreateSchema(p.Append("additionalItems"), *v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// String
|
// String
|
||||||
@ -685,14 +691,16 @@ private:
|
|||||||
|
|
||||||
template <typename DocumentType, typename ValueType>
|
template <typename DocumentType, typename ValueType>
|
||||||
static void AssigIfExist(SchemaArrayType& out, const DocumentType& document, const PointerType& p, 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) {
|
||||||
|
PointerType q = p.Append(name);
|
||||||
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] = document->CreateSchema(p, (*v)[i]);
|
out.schemas[i] = document->CreateSchema(q.Append(i), (*v)[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if RAPIDJSON_SCHEMA_USE_STDREGEX
|
#if RAPIDJSON_SCHEMA_USE_STDREGEX
|
||||||
@ -863,28 +871,44 @@ private:
|
|||||||
template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
|
template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
|
||||||
class GenericSchemaDocument {
|
class GenericSchemaDocument {
|
||||||
public:
|
public:
|
||||||
template <typename T1, typename T2, typename T3>
|
|
||||||
friend class GenericSchemaValidator;
|
|
||||||
|
|
||||||
typedef Schema<Encoding, Allocator> SchemaType;
|
typedef Schema<Encoding, Allocator> SchemaType;
|
||||||
|
friend class Schema<Encoding, Allocator>;
|
||||||
|
|
||||||
template <typename DocumentType>
|
template <typename DocumentType>
|
||||||
GenericSchemaDocument(const DocumentType& document) : root_() {
|
GenericSchemaDocument(const DocumentType& document, Allocator* allocator = 0) : root_(), schemaMap(allocator, kInitialSchemaMapSize) {
|
||||||
typedef typename DocumentType::ValueType ValueType;
|
typedef typename DocumentType::ValueType ValueType;
|
||||||
root_ = CreateSchema(GenericPointer<ValueType>("#"), static_cast<const ValueType&>(document));
|
|
||||||
|
root_ = CreateSchema(GenericPointer<ValueType>(), static_cast<const ValueType&>(document));
|
||||||
|
|
||||||
|
while (!schemaMap.Empty())
|
||||||
|
schemaMap.template Pop<SchemaEntry<ValueType> > (1)->~SchemaEntry<ValueType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
~GenericSchemaDocument() {
|
~GenericSchemaDocument() {
|
||||||
delete root_;
|
delete root_;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ValueType>
|
const SchemaType& GetRoot() const { return *root_; }
|
||||||
SchemaType* CreateSchema(const GenericPointer<ValueType>& p, const ValueType& v) {
|
|
||||||
return new SchemaType(this, p, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template <typename ValueType>
|
||||||
|
struct SchemaEntry {
|
||||||
|
SchemaEntry(const GenericPointer<ValueType>& p, SchemaType* s) : pointer(p), schema(s) {}
|
||||||
|
GenericPointer<ValueType> pointer;
|
||||||
|
SchemaType* schema;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ValueType>
|
||||||
|
SchemaType* CreateSchema(const GenericPointer<ValueType>& pointer, const ValueType& v) {
|
||||||
|
SchemaType* schema = new SchemaType(this, pointer, v);
|
||||||
|
new (schemaMap.template Push<SchemaEntry<ValueType> >()) SchemaEntry<ValueType>(pointer, schema);
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const size_t kInitialSchemaMapSize = 1024;
|
||||||
|
|
||||||
SchemaType* root_;
|
SchemaType* root_;
|
||||||
|
internal::Stack<Allocator> schemaMap; // Stores SchemaEntry<ValueType>
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef GenericSchemaDocument<UTF8<> > SchemaDocument;
|
typedef GenericSchemaDocument<UTF8<> > SchemaDocument;
|
||||||
@ -902,7 +926,7 @@ public:
|
|||||||
size_t schemaStackCapacity = kDefaultSchemaStackCapacity/*,
|
size_t schemaStackCapacity = kDefaultSchemaStackCapacity/*,
|
||||||
size_t documentStackCapacity = kDefaultDocumentStackCapacity*/)
|
size_t documentStackCapacity = kDefaultDocumentStackCapacity*/)
|
||||||
:
|
:
|
||||||
root_(*schemaDocument.root_),
|
root_(schemaDocument.GetRoot()),
|
||||||
outputHandler_(nullOutputHandler_),
|
outputHandler_(nullOutputHandler_),
|
||||||
schemaStack_(allocator, schemaStackCapacity),
|
schemaStack_(allocator, schemaStackCapacity),
|
||||||
// documentStack_(allocator, documentStackCapacity),
|
// documentStack_(allocator, documentStackCapacity),
|
||||||
@ -917,7 +941,7 @@ public:
|
|||||||
size_t schemaStackCapacity = kDefaultSchemaStackCapacity/*,
|
size_t schemaStackCapacity = kDefaultSchemaStackCapacity/*,
|
||||||
size_t documentStackCapacity = kDefaultDocumentStackCapacity*/)
|
size_t documentStackCapacity = kDefaultDocumentStackCapacity*/)
|
||||||
:
|
:
|
||||||
root_(*schemaDocument.root_),
|
root_(schemaDocument.GetRoot()),
|
||||||
outputHandler_(outputHandler),
|
outputHandler_(outputHandler),
|
||||||
schemaStack_(allocator, schemaStackCapacity),
|
schemaStack_(allocator, schemaStackCapacity),
|
||||||
// documentStack_(allocator, documentStackCapacity),
|
// documentStack_(allocator, documentStackCapacity),
|
||||||
@ -1076,7 +1100,7 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PushSchema(const SchemaType& schema) { *schemaStack_.template Push<Context>() = Context(this, &schema); }
|
void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push<Context>()) Context(this, &schema); }
|
||||||
void PopSchema() { schemaStack_.template Pop<Context>(1)->~Context(); }
|
void PopSchema() { schemaStack_.template Pop<Context>(1)->~Context(); }
|
||||||
const SchemaType& 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>(); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user