mirror of
https://github.com/Tencent/rapidjson.git
synced 2025-03-06 13:41:35 +01:00
Fix some remote ref issues
This commit is contained in:
parent
42f1194a8d
commit
3873bcb714
@ -121,9 +121,24 @@ public:
|
||||
return reinterpret_cast<T*>(stackTop_ - sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T* Top() const {
|
||||
RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
|
||||
return reinterpret_cast<T*>(stackTop_ - sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* End() { return reinterpret_cast<T*>(stackTop_); }
|
||||
|
||||
template<typename T>
|
||||
const T* End() const { return reinterpret_cast<T*>(stackTop_); }
|
||||
|
||||
template<typename T>
|
||||
T* Bottom() { return (T*)stack_; }
|
||||
|
||||
template<typename T>
|
||||
const T* Bottom() const { return (T*)stack_; }
|
||||
|
||||
Allocator& GetAllocator() { return *allocator_; }
|
||||
bool Empty() const { return stackTop_ == stack_; }
|
||||
size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
|
||||
|
@ -882,7 +882,7 @@ public:
|
||||
typedef typename ValueType::Ch Ch;
|
||||
|
||||
virtual ~IGenericRemoteSchemaDocumentProvider() {}
|
||||
virtual SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0;
|
||||
virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0;
|
||||
};
|
||||
|
||||
typedef IGenericRemoteSchemaDocumentProvider<Value> IRemoteSchemaDocumentProvider;
|
||||
@ -909,10 +909,10 @@ public:
|
||||
schemaMap_(allocator, kInitialSchemaMapSize),
|
||||
schemaRef_(allocator, kInitialSchemaRefSize)
|
||||
{
|
||||
|
||||
// Generate root schema, it will call CreateSchema() to create sub-schemas,
|
||||
// And call AddRefSchema() if there are $ref.
|
||||
root_ = CreateSchema(PointerType(), static_cast<const ValueType&>(document));
|
||||
//root_ = CreateSchema(PointerType(), static_cast<const ValueType&>(document));
|
||||
root_ = CreateSchemaRecursive(Pointer(), static_cast<const ValueType&>(document));
|
||||
|
||||
// Resolve $ref
|
||||
while (!schemaRef_.Empty()) {
|
||||
@ -936,12 +936,27 @@ public:
|
||||
|
||||
private:
|
||||
struct SchemaEntry {
|
||||
SchemaEntry(const GenericPointer<ValueType>& p, SchemaType* s) : pointer(p), schema(s) {}
|
||||
GenericPointer<ValueType> pointer;
|
||||
SchemaEntry(const PointerType& p, SchemaType* s) : pointer(p), schema(s) {}
|
||||
PointerType pointer;
|
||||
SchemaType* schema;
|
||||
};
|
||||
|
||||
const SchemaType* CreateSchema(const GenericPointer<ValueType>& pointer, const ValueType& v) {
|
||||
const SchemaType* CreateSchemaRecursive(const PointerType& pointer, const ValueType& v) {
|
||||
if (v.GetType() == kObjectType) {
|
||||
const SchemaType* s = GetSchema(pointer);
|
||||
if (!s)
|
||||
s = CreateSchema(pointer, v);
|
||||
for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
|
||||
CreateSchemaRecursive(pointer.Append(itr->name), itr->value);
|
||||
return s;
|
||||
}
|
||||
else if (v.GetType() == kArrayType)
|
||||
for (SizeType i = 0; i < v.Size(); i++)
|
||||
CreateSchemaRecursive(pointer.Append(i), v[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const SchemaType* CreateSchema(const PointerType& pointer, const ValueType& v) {
|
||||
RAPIDJSON_ASSERT(pointer.IsValid());
|
||||
SchemaType* schema = new SchemaType(this, pointer, v);
|
||||
new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(pointer, schema);
|
||||
@ -959,8 +974,7 @@ private:
|
||||
|
||||
if (i > 0) { // Remote reference, resolve immediately
|
||||
if (remoteProvider_) {
|
||||
if (GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i - 1)) {
|
||||
printf("remote fragment: %*s\n", len - i, &s[i]);
|
||||
if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i - 1)) {
|
||||
GenericPointer<ValueType> pointer(&s[i], len - i);
|
||||
if (pointer.IsValid())
|
||||
schema->ref_ = remoteDocument->GetSchema(pointer);
|
||||
@ -968,7 +982,6 @@ private:
|
||||
}
|
||||
}
|
||||
else if (s[i] == '#') { // Local reference, defer resolution
|
||||
printf("local fragment: %*s\n", len - i, &s[i]);
|
||||
GenericPointer<ValueType> pointer(&s[i], len - i);
|
||||
if (pointer.IsValid())
|
||||
new (schemaRef_.template Push<SchemaEntry>()) SchemaEntry(pointer, schema);
|
||||
@ -977,15 +990,11 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
const SchemaType* GetSchema(const GenericPointer<ValueType>& pointer) {
|
||||
for (SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target <= schemaMap_.template Top<SchemaEntry>(); ++target)
|
||||
const SchemaType* GetSchema(const PointerType& pointer) const {
|
||||
for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
|
||||
if (pointer == target->pointer)
|
||||
return target->schema;
|
||||
|
||||
if (const ValueType* v = pointer.Get(document_))
|
||||
return CreateSchema(pointer, *v);
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const size_t kInitialSchemaMapSize = 1024;
|
||||
@ -1061,7 +1070,7 @@ public:
|
||||
if (!BeginValue() || !CurrentSchema().method arg1) return valid_ = false;
|
||||
|
||||
#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\
|
||||
for (Context* context = schemaStack_.template Bottom<Context>(); context <= schemaStack_.template Top<Context>(); context++) {\
|
||||
for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\
|
||||
if (context->allOfValidators.validators)\
|
||||
for (SizeType i_ = 0; i_ < context->allOfValidators.count; i_++)\
|
||||
static_cast<GenericSchemaValidator*>(context->allOfValidators.validators[i_])->method arg2;\
|
||||
|
@ -763,17 +763,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual SchemaDocument* GetRemoteDocument(const char* uri, SizeType length) {
|
||||
virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeType length) {
|
||||
const char* uris[kCount] = {
|
||||
"http://localhost:1234/integer.json",
|
||||
"http://localhost:1234/subSchemas.json",
|
||||
"http://localhost:1234/folder/folderInteger.json"
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < kCount; i++) {
|
||||
for (size_t i = 0; i < kCount; i++)
|
||||
if (strncmp(uri, uris[i], length) == 0)
|
||||
return sd_[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -809,7 +808,7 @@ TEST(SchemaValidator, TestSuite) {
|
||||
"patternProperties.json",
|
||||
"properties.json",
|
||||
"ref.json",
|
||||
//"refRemote.json",
|
||||
"refRemote.json",
|
||||
"required.json",
|
||||
"type.json",
|
||||
//"uniqueItems.json"
|
||||
@ -854,7 +853,7 @@ TEST(SchemaValidator, TestSuite) {
|
||||
validator.Reset();
|
||||
bool actual = data.Accept(validator);
|
||||
if (expected != actual)
|
||||
printf("Fail: %30s \"%s, %s\"\n", filename, description1, description2);
|
||||
printf("Fail: %30s \"%s\" \"%s\"\n", filename, description1, description2);
|
||||
else
|
||||
passCount++;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user