Commit 85c8b657 authored by miloyip's avatar miloyip

Achieve zero heap allocation for SchemaValidator.TestSuite

parent e20645f0
...@@ -131,6 +131,7 @@ public: ...@@ -131,6 +131,7 @@ public:
virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0; virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0;
virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0; virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0;
virtual void* CreateHasher() = 0; virtual void* CreateHasher() = 0;
virtual uint64_t GetHashCode(void* hasher) = 0;
virtual void DestroryHasher(void* hasher) = 0; virtual void DestroryHasher(void* hasher) = 0;
virtual void* MallocState(size_t size) = 0; virtual void* MallocState(size_t size) = 0;
virtual void* ReallocState(void* originalPtr, size_t originalSize, size_t newSize) = 0; virtual void* ReallocState(void* originalPtr, size_t originalSize, size_t newSize) = 0;
...@@ -146,7 +147,7 @@ class Hasher { ...@@ -146,7 +147,7 @@ class Hasher {
public: public:
typedef typename Encoding::Ch Ch; typedef typename Encoding::Ch Ch;
Hasher(Allocator* allocator = 0) : stack_(allocator, kDefaultSize) {} Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {}
bool Null() { return WriteType(kNullType); } bool Null() { return WriteType(kNullType); }
bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); } bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); }
...@@ -318,7 +319,6 @@ public: ...@@ -318,7 +319,6 @@ public:
typedef typename EncodingType::Ch Ch; typedef typename EncodingType::Ch Ch;
typedef SchemaValidationContext<SchemaDocumentType> Context; typedef SchemaValidationContext<SchemaDocumentType> Context;
typedef Schema<SchemaDocumentType> SchemaType; typedef Schema<SchemaDocumentType> SchemaType;
typedef Hasher<EncodingType, AllocatorType> HasherType;
typedef GenericValue<EncodingType, AllocatorType> SValue; typedef GenericValue<EncodingType, AllocatorType> SValue;
friend class GenericSchemaDocument<ValueType, AllocatorType>; friend class GenericSchemaDocument<ValueType, AllocatorType>;
...@@ -374,7 +374,10 @@ public: ...@@ -374,7 +374,10 @@ public:
if (v->IsArray() && v->Size() > 0) { if (v->IsArray() && v->Size() > 0) {
enum_ = static_cast<uint64_t*>(allocator_->Malloc(sizeof(uint64_t) * v->Size())); enum_ = static_cast<uint64_t*>(allocator_->Malloc(sizeof(uint64_t) * v->Size()));
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) { for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) {
HasherType h; typedef Hasher<EncodingType, MemoryPoolAllocator<> > EnumHasherType;
char buffer[256 + 24];
MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer));
EnumHasherType h(&hasherAllocator, 256);
itr->Accept(h); itr->Accept(h);
enum_[enumCount_++] = h.GetHashCode(); enum_[enumCount_++] = h.GetHashCode();
} }
...@@ -385,7 +388,7 @@ public: ...@@ -385,7 +388,7 @@ public:
AssignIfExist(oneOf_, document, p, value, GetOneOfString()); AssignIfExist(oneOf_, document, p, value, GetOneOfString());
if (const ValueType* v = GetMember(value, GetNotString())) { if (const ValueType* v = GetMember(value, GetNotString())) {
document->CreateSchema(&not_, p.Append(GetNotString()), *v); document->CreateSchema(&not_, p.Append(GetNotString(), allocator_), *v);
notValidatorIndex_ = validatorCount_; notValidatorIndex_ = validatorCount_;
validatorCount_++; validatorCount_++;
} }
...@@ -429,23 +432,23 @@ public: ...@@ -429,23 +432,23 @@ public:
} }
if (properties && properties->IsObject()) { if (properties && properties->IsObject()) {
PointerType q = p.Append(GetPropertiesString()); PointerType q = p.Append(GetPropertiesString(), allocator_);
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))
document->CreateSchema(&properties_[index].schema, q.Append(itr->name), itr->value); document->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value);
} }
} }
if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) { if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) {
PointerType q = p.Append(GetPatternPropertiesString()); PointerType q = p.Append(GetPatternPropertiesString(), allocator_);
patternProperties_ = static_cast<PatternProperty*>(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount())); patternProperties_ = static_cast<PatternProperty*>(allocator_->Malloc(sizeof(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) {
new (&patternProperties_[patternPropertyCount_]) PatternProperty(); new (&patternProperties_[patternPropertyCount_]) PatternProperty();
patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name); patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name);
document->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name), itr->value); document->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value);
patternPropertyCount_++; patternPropertyCount_++;
} }
} }
...@@ -461,7 +464,7 @@ public: ...@@ -461,7 +464,7 @@ public:
} }
if (dependencies && dependencies->IsObject()) { if (dependencies && dependencies->IsObject()) {
PointerType q = p.Append(GetDependenciesString()); PointerType q = p.Append(GetDependenciesString(), allocator_);
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;
...@@ -477,7 +480,7 @@ public: ...@@ -477,7 +480,7 @@ public:
} }
else if (itr->value.IsObject()) { else if (itr->value.IsObject()) {
hasSchemaDependencies_ = true; hasSchemaDependencies_ = true;
document->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name), itr->value); document->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value);
properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_; properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_;
validatorCount_++; validatorCount_++;
} }
...@@ -489,7 +492,7 @@ public: ...@@ -489,7 +492,7 @@ public:
if (v->IsBool()) if (v->IsBool())
additionalProperties_ = v->GetBool(); additionalProperties_ = v->GetBool();
else if (v->IsObject()) else if (v->IsObject())
document->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString()), *v); document->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v);
} }
AssignIfExist(minProperties_, value, GetMinPropertiesString()); AssignIfExist(minProperties_, value, GetMinPropertiesString());
...@@ -497,14 +500,14 @@ public: ...@@ -497,14 +500,14 @@ public:
// Array // Array
if (const ValueType* v = GetMember(value, GetItemsString())) { if (const ValueType* v = GetMember(value, GetItemsString())) {
PointerType q = p.Append(GetItemsString()); PointerType q = p.Append(GetItemsString(), allocator_);
if (v->IsObject()) // List validation if (v->IsObject()) // List validation
document->CreateSchema(&itemsList_, q, *v); document->CreateSchema(&itemsList_, q, *v);
else if (v->IsArray()) { // Tuple validation else if (v->IsArray()) { // Tuple validation
itemsTuple_ = static_cast<const Schema**>(allocator_->Malloc(sizeof(const Schema*) * v->Size())); itemsTuple_ = static_cast<const Schema**>(allocator_->Malloc(sizeof(const Schema*) * v->Size()));
SizeType index = 0; SizeType index = 0;
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++) for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++)
document->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index), *itr); document->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr);
} }
} }
...@@ -515,7 +518,7 @@ public: ...@@ -515,7 +518,7 @@ public:
if (v->IsBool()) if (v->IsBool())
additionalItems_ = v->GetBool(); additionalItems_ = v->GetBool();
else if (v->IsObject()) else if (v->IsObject())
document->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString()), *v); document->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v);
} }
AssignIfExist(uniqueItems_, value, GetUniqueItemsString()); AssignIfExist(uniqueItems_, value, GetUniqueItemsString());
...@@ -617,7 +620,7 @@ public: ...@@ -617,7 +620,7 @@ public:
} }
if (enum_) { if (enum_) {
const uint64_t h = static_cast<HasherType*>(context.hasher)->GetHashCode(); const uint64_t h = context.factory.GetHashCode(context.hasher);
for (SizeType i = 0; i < enumCount_; i++) for (SizeType i = 0; i < enumCount_; i++)
if (enum_[i] == h) if (enum_[i] == h)
goto foundEnum; goto foundEnum;
...@@ -954,12 +957,12 @@ private: ...@@ -954,12 +957,12 @@ private:
void AssignIfExist(SchemaArray& out, const DocumentType& document, const PointerType& p, const ValueType& value, const ValueType& name) { void AssignIfExist(SchemaArray& out, const DocumentType& document, const PointerType& p, const ValueType& value, const ValueType& 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); PointerType q = p.Append(name, allocator_);
out.count = v->Size(); out.count = v->Size();
out.schemas = static_cast<const Schema**>(allocator_->Malloc(out.count * sizeof(const Schema*))); out.schemas = static_cast<const Schema**>(allocator_->Malloc(out.count * sizeof(const Schema*)));
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++)
document->CreateSchema(&out.schemas[i], q.Append(i), (*v)[i]); document->CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i]);
out.begin = validatorCount_; out.begin = validatorCount_;
validatorCount_ += out.count; validatorCount_ += out.count;
} }
...@@ -1227,7 +1230,7 @@ public: ...@@ -1227,7 +1230,7 @@ public:
typedef typename ValueType::EncodingType EncodingType; typedef typename ValueType::EncodingType EncodingType;
typedef typename EncodingType::Ch Ch; typedef typename EncodingType::Ch Ch;
typedef internal::Schema<GenericSchemaDocument> SchemaType; typedef internal::Schema<GenericSchemaDocument> SchemaType;
typedef GenericPointer<ValueType, CrtAllocator> PointerType; typedef GenericPointer<ValueType, Allocator> PointerType;
friend class internal::Schema<GenericSchemaDocument>; friend class internal::Schema<GenericSchemaDocument>;
template <typename, typename, typename> template <typename, typename, typename>
friend class GenericSchemaValidator; friend class GenericSchemaValidator;
...@@ -1257,7 +1260,7 @@ public: ...@@ -1257,7 +1260,7 @@ public:
// Create entry in map if not exist // Create entry in map if not exist
if (!GetSchema(refEntry->source)) { if (!GetSchema(refEntry->source)) {
new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(refEntry->source, const_cast<SchemaType*>(s), false); new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(refEntry->source, const_cast<SchemaType*>(s), false, allocator_);
} }
} }
refEntry->~SchemaRefEntry(); refEntry->~SchemaRefEntry();
...@@ -1279,14 +1282,14 @@ public: ...@@ -1279,14 +1282,14 @@ public:
private: private:
struct SchemaRefEntry { struct SchemaRefEntry {
SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema) : source(s), target(t), schema(outSchema) {} SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {}
PointerType source; PointerType source;
PointerType target; PointerType target;
const SchemaType** schema; const SchemaType** schema;
}; };
struct SchemaEntry { struct SchemaEntry {
SchemaEntry(const PointerType& p, SchemaType* s, bool o) : pointer(p), schema(s), owned(o) {} SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {}
~SchemaEntry() { ~SchemaEntry() {
if (owned) { if (owned) {
schema->~SchemaType(); schema->~SchemaType();
...@@ -1310,11 +1313,11 @@ private: ...@@ -1310,11 +1313,11 @@ private:
*schema = s; *schema = s;
for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
CreateSchemaRecursive(0, pointer.Append(itr->name), itr->value); CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value);
} }
else if (v.GetType() == kArrayType) else if (v.GetType() == kArrayType)
for (SizeType i = 0; i < v.Size(); i++) for (SizeType i = 0; i < v.Size(); i++)
CreateSchemaRecursive(0, pointer.Append(i), v[i]); CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i]);
} }
void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v) { void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v) {
...@@ -1322,7 +1325,7 @@ private: ...@@ -1322,7 +1325,7 @@ private:
if (v.IsObject()) { if (v.IsObject()) {
if (!HandleRefSchema(pointer, schema, v)) { if (!HandleRefSchema(pointer, schema, v)) {
SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, allocator_); SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, allocator_);
new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(pointer, s, true); new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(pointer, s, true, allocator_);
if (schema) if (schema)
*schema = s; *schema = s;
} }
...@@ -1348,7 +1351,7 @@ private: ...@@ -1348,7 +1351,7 @@ private:
if (i > 0) { // Remote reference, resolve immediately if (i > 0) { // Remote reference, resolve immediately
if (remoteProvider_) { if (remoteProvider_) {
if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i - 1)) { if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i - 1)) {
PointerType pointer(&s[i], len - i); PointerType pointer(&s[i], len - i, allocator_);
if (pointer.IsValid()) { if (pointer.IsValid()) {
if (const SchemaType* s = remoteDocument->GetSchema(pointer)) { if (const SchemaType* s = remoteDocument->GetSchema(pointer)) {
if (schema) if (schema)
...@@ -1360,13 +1363,13 @@ private: ...@@ -1360,13 +1363,13 @@ private:
} }
} }
else if (s[i] == '#') { // Local reference, defer resolution else if (s[i] == '#') { // Local reference, defer resolution
PointerType pointer(&s[i], len - i); PointerType pointer(&s[i], len - i, allocator_);
if (pointer.IsValid()) { if (pointer.IsValid()) {
if (const ValueType* nv = pointer.Get(*document_)) if (const ValueType* nv = pointer.Get(*document_))
if (HandleRefSchema(source, schema, *nv)) if (HandleRefSchema(source, schema, *nv))
return true; return true;
new (schemaRef_.template Push<SchemaRefEntry>()) SchemaRefEntry(source, pointer, schema); new (schemaRef_.template Push<SchemaRefEntry>()) SchemaRefEntry(source, pointer, schema, allocator_);
return true; return true;
} }
} }
...@@ -1555,11 +1558,11 @@ RAPIDJSON_MULTILINEMACRO_END ...@@ -1555,11 +1558,11 @@ RAPIDJSON_MULTILINEMACRO_END
// Implementation of ISchemaStateFactory<SchemaType> // Implementation of ISchemaStateFactory<SchemaType>
virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) { virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) {
return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root,
#if RAPIDJSON_SCHEMA_VERBOSE #if RAPIDJSON_SCHEMA_VERBOSE
, depth_ + 1 depth_ + 1,
#endif #endif
); &GetStateAllocator());
} }
virtual void DestroySchemaValidator(ISchemaValidator* validator) { virtual void DestroySchemaValidator(ISchemaValidator* validator) {
...@@ -1572,6 +1575,10 @@ RAPIDJSON_MULTILINEMACRO_END ...@@ -1572,6 +1575,10 @@ RAPIDJSON_MULTILINEMACRO_END
return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator()); return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator());
} }
virtual uint64_t GetHashCode(void* hasher) {
return static_cast<HasherType*>(hasher)->GetHashCode();
}
virtual void DestroryHasher(void* hasher) { virtual void DestroryHasher(void* hasher) {
HasherType* h = static_cast<HasherType*>(hasher); HasherType* h = static_cast<HasherType*>(hasher);
h->~HasherType(); h->~HasherType();
......
...@@ -837,7 +837,8 @@ TEST(SchemaValidator, AllOf_Nested) { ...@@ -837,7 +837,8 @@ TEST(SchemaValidator, AllOf_Nested) {
INVALIDATE(s, "123", "", "allOf", ""); INVALIDATE(s, "123", "", "allOf", "");
} }
static char* ReadFile(const char* filename) { template <typename Allocator = CrtAllocator>
static char* ReadFile(const char* filename, Allocator& allocator) {
const char *paths[] = { const char *paths[] = {
"%s", "%s",
"bin/%s", "bin/%s",
...@@ -860,7 +861,7 @@ static char* ReadFile(const char* filename) { ...@@ -860,7 +861,7 @@ static char* ReadFile(const char* filename) {
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
size_t length = (size_t)ftell(fp); size_t length = (size_t)ftell(fp);
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_SET);
char* json = (char*)malloc(length + 1); char* json = (char*)allocator.Malloc(length + 1);
size_t readLength = fread(json, 1, length, fp); size_t readLength = fread(json, 1, length, fp);
json[readLength] = '\0'; json[readLength] = '\0';
fclose(fp); fclose(fp);
...@@ -868,7 +869,8 @@ static char* ReadFile(const char* filename) { ...@@ -868,7 +869,8 @@ static char* ReadFile(const char* filename) {
} }
TEST(SchemaValidator, ValidateMetaSchema) { TEST(SchemaValidator, ValidateMetaSchema) {
char* json = ReadFile("draft-04/schema"); CrtAllocator allocator;
char* json = ReadFile("draft-04/schema", allocator);
Document d; Document d;
d.Parse(json); d.Parse(json);
ASSERT_FALSE(d.HasParseError()); ASSERT_FALSE(d.HasParseError());
...@@ -884,7 +886,7 @@ TEST(SchemaValidator, ValidateMetaSchema) { ...@@ -884,7 +886,7 @@ TEST(SchemaValidator, ValidateMetaSchema) {
printf("Invalid document: %s\n", sb.GetString()); printf("Invalid document: %s\n", sb.GetString());
ADD_FAILURE(); ADD_FAILURE();
} }
free(json); CrtAllocator::Free(json);
} }
TEST(SchemaValidator, ValidateMetaSchema_UTF16) { TEST(SchemaValidator, ValidateMetaSchema_UTF16) {
...@@ -892,7 +894,8 @@ TEST(SchemaValidator, ValidateMetaSchema_UTF16) { ...@@ -892,7 +894,8 @@ TEST(SchemaValidator, ValidateMetaSchema_UTF16) {
typedef GenericSchemaDocument<D::ValueType> SD; typedef GenericSchemaDocument<D::ValueType> SD;
typedef GenericSchemaValidator<SD> SV; typedef GenericSchemaValidator<SD> SV;
char* json = ReadFile("draft-04/schema"); CrtAllocator allocator;
char* json = ReadFile("draft-04/schema", allocator);
D d; D d;
StringStream ss(json); StringStream ss(json);
...@@ -910,13 +913,16 @@ TEST(SchemaValidator, ValidateMetaSchema_UTF16) { ...@@ -910,13 +913,16 @@ TEST(SchemaValidator, ValidateMetaSchema_UTF16) {
wprintf(L"Invalid document: %ls\n", sb.GetString()); wprintf(L"Invalid document: %ls\n", sb.GetString());
ADD_FAILURE(); ADD_FAILURE();
} }
free(json); CrtAllocator::Free(json);
} }
template <typename SchemaDocumentType = SchemaDocument> template <typename SchemaDocumentType = SchemaDocument>
class RemoteSchemaDocumentProvider : public IGenericRemoteSchemaDocumentProvider<SchemaDocumentType> { class RemoteSchemaDocumentProvider : public IGenericRemoteSchemaDocumentProvider<SchemaDocumentType> {
public: public:
RemoteSchemaDocumentProvider() : documentAllocator_(), schemaAllocator_() { RemoteSchemaDocumentProvider() :
documentAllocator_(documentBuffer_, sizeof(documentBuffer_)),
schemaAllocator_(schemaBuffer_, sizeof(schemaBuffer_))
{
const char* filenames[kCount] = { const char* filenames[kCount] = {
"jsonschema/remotes/integer.json", "jsonschema/remotes/integer.json",
"jsonschema/remotes/subSchemas.json", "jsonschema/remotes/subSchemas.json",
...@@ -927,16 +933,20 @@ public: ...@@ -927,16 +933,20 @@ public:
for (size_t i = 0; i < kCount; i++) { for (size_t i = 0; i < kCount; i++) {
sd_[i] = 0; sd_[i] = 0;
char* json = ReadFile(filenames[i]); char jsonBuffer[8192];
MemoryPoolAllocator<> jsonAllocator(jsonBuffer, sizeof(jsonBuffer));
char* json = ReadFile(filenames[i], jsonAllocator);
if (!json) { if (!json) {
printf("json remote file %s not found", filenames[i]); printf("json remote file %s not found", filenames[i]);
ADD_FAILURE(); ADD_FAILURE();
} }
else { else {
DocumentType d(&documentAllocator_); char stackBuffer[4096];
MemoryPoolAllocator<> stackAllocator(stackBuffer, sizeof(stackBuffer));
DocumentType d(&documentAllocator_, 1024, &stackAllocator);
d.Parse(json); d.Parse(json);
sd_[i] = new SchemaDocumentType(d, 0, &schemaAllocator_); sd_[i] = new SchemaDocumentType(d, 0, &schemaAllocator_);
free(json); MemoryPoolAllocator<>::Free(json);
} }
}; };
} }
...@@ -961,7 +971,7 @@ public: ...@@ -961,7 +971,7 @@ public:
} }
private: private:
typedef GenericDocument<typename SchemaDocumentType::EncodingType, MemoryPoolAllocator<> > DocumentType; typedef GenericDocument<typename SchemaDocumentType::EncodingType, MemoryPoolAllocator<>, MemoryPoolAllocator<> > DocumentType;
RemoteSchemaDocumentProvider(const RemoteSchemaDocumentProvider&); RemoteSchemaDocumentProvider(const RemoteSchemaDocumentProvider&);
RemoteSchemaDocumentProvider& operator=(const RemoteSchemaDocumentProvider&); RemoteSchemaDocumentProvider& operator=(const RemoteSchemaDocumentProvider&);
...@@ -970,6 +980,8 @@ private: ...@@ -970,6 +980,8 @@ private:
SchemaDocumentType* sd_[kCount]; SchemaDocumentType* sd_[kCount];
typename DocumentType::AllocatorType documentAllocator_; typename DocumentType::AllocatorType documentAllocator_;
typename SchemaDocumentType::AllocatorType schemaAllocator_; typename SchemaDocumentType::AllocatorType schemaAllocator_;
char documentBuffer_[16384];
char schemaBuffer_[128 * 1024];
}; };
TEST(SchemaValidator, TestSuite) { TEST(SchemaValidator, TestSuite) {
...@@ -1013,10 +1025,12 @@ TEST(SchemaValidator, TestSuite) { ...@@ -1013,10 +1025,12 @@ TEST(SchemaValidator, TestSuite) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider; RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
char jsonBuffer[65536];
char documentBuffer[65536]; char documentBuffer[65536];
char documentStackBuffer[65536]; char documentStackBuffer[65536];
char schemaBuffer[65536]; char schemaBuffer[65536];
char validatorBuffer[65536]; char validatorBuffer[65536];
MemoryPoolAllocator<> jsonAllocator(jsonBuffer, sizeof(jsonBuffer));
MemoryPoolAllocator<> documentAllocator(documentBuffer, sizeof(documentBuffer)); MemoryPoolAllocator<> documentAllocator(documentBuffer, sizeof(documentBuffer));
MemoryPoolAllocator<> documentStackAllocator(documentStackBuffer, sizeof(documentStackBuffer)); MemoryPoolAllocator<> documentStackAllocator(documentStackBuffer, sizeof(documentStackBuffer));
MemoryPoolAllocator<> schemaAllocator(schemaBuffer, sizeof(schemaBuffer)); MemoryPoolAllocator<> schemaAllocator(schemaBuffer, sizeof(schemaBuffer));
...@@ -1025,7 +1039,7 @@ TEST(SchemaValidator, TestSuite) { ...@@ -1025,7 +1039,7 @@ TEST(SchemaValidator, TestSuite) {
for (size_t i = 0; i < sizeof(filenames) / sizeof(filenames[0]); i++) { for (size_t i = 0; i < sizeof(filenames) / sizeof(filenames[0]); i++) {
char filename[FILENAME_MAX]; char filename[FILENAME_MAX];
sprintf(filename, "jsonschema/tests/draft4/%s", filenames[i]); sprintf(filename, "jsonschema/tests/draft4/%s", filenames[i]);
char* json = ReadFile(filename); char* json = ReadFile(filename, jsonAllocator);
if (!json) { if (!json) {
printf("json test suite file %s not found", filename); printf("json test suite file %s not found", filename);
ADD_FAILURE(); ADD_FAILURE();
...@@ -1066,7 +1080,8 @@ TEST(SchemaValidator, TestSuite) { ...@@ -1066,7 +1080,8 @@ TEST(SchemaValidator, TestSuite) {
} }
} }
documentAllocator.Clear(); documentAllocator.Clear();
free(json); MemoryPoolAllocator<>::Free(json);
jsonAllocator.Clear();
} }
printf("%d / %d passed (%2d%%)\n", passCount, testCount, passCount * 100 / testCount); printf("%d / %d passed (%2d%%)\n", passCount, testCount, passCount * 100 / testCount);
// if (passCount != testCount) // if (passCount != testCount)
......
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