Commit 76209948 authored by Erik Verbruggen's avatar Erik Verbruggen

QML: add a memory pool to the Json* classes.

The memory pool is not too efficient, but will keep objects from
leaking.

Change-Id: I68a55bc7a6ea56463652245abeea8954b693c1d7
Reviewed-by: default avatarFawzi Mohamed <fawzi.mohamed@digia.com>
parent 7702ad52
...@@ -250,6 +250,8 @@ QStringList QmlBundle::maybeReadTrie(Trie &trie, Utils::JsonObjectValue *config, ...@@ -250,6 +250,8 @@ QStringList QmlBundle::maybeReadTrie(Trie &trie, Utils::JsonObjectValue *config,
bool QmlBundle::readFrom(QString path, QStringList *errors) bool QmlBundle::readFrom(QString path, QStringList *errors)
{ {
Utils::JsonMemoryPool pool;
using namespace Utils; using namespace Utils;
QFile f(path); QFile f(path);
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
...@@ -257,7 +259,7 @@ bool QmlBundle::readFrom(QString path, QStringList *errors) ...@@ -257,7 +259,7 @@ bool QmlBundle::readFrom(QString path, QStringList *errors)
(*errors) << QString::fromLatin1("Could not open file at %1 .").arg(path); (*errors) << QString::fromLatin1("Could not open file at %1 .").arg(path);
return false; return false;
} }
JsonObjectValue *config = JsonValue::create(QString::fromUtf8(f.readAll()))->toObject(); JsonObjectValue *config = JsonValue::create(QString::fromUtf8(f.readAll()), &pool)->toObject();
if (config == 0) { if (config == 0) {
if (errors) if (errors)
(*errors) << QString::fromLatin1("Could not parse json object in file at %1 .").arg(path); (*errors) << QString::fromLatin1("Could not parse json object in file at %1 .").arg(path);
......
...@@ -39,6 +39,11 @@ ...@@ -39,6 +39,11 @@
using namespace Utils; using namespace Utils;
JsonMemoryPool::~JsonMemoryPool()
{
foreach (char *obj, _objs)
delete[] obj;
}
JsonValue::JsonValue(Kind kind) JsonValue::JsonValue(Kind kind)
: m_kind(kind) : m_kind(kind)
...@@ -47,7 +52,7 @@ JsonValue::JsonValue(Kind kind) ...@@ -47,7 +52,7 @@ JsonValue::JsonValue(Kind kind)
JsonValue::~JsonValue() JsonValue::~JsonValue()
{} {}
JsonValue *JsonValue::create(const QString &s) JsonValue *JsonValue::create(const QString &s, JsonMemoryPool *pool)
{ {
QScriptEngine engine; QScriptEngine engine;
QScriptValue jsonParser = engine.evaluate(QLatin1String("JSON.parse")); QScriptValue jsonParser = engine.evaluate(QLatin1String("JSON.parse"));
...@@ -55,9 +60,18 @@ JsonValue *JsonValue::create(const QString &s) ...@@ -55,9 +60,18 @@ JsonValue *JsonValue::create(const QString &s)
if (engine.hasUncaughtException() || !value.isValid()) if (engine.hasUncaughtException() || !value.isValid())
return 0; return 0;
return build(value.toVariant()); return build(value.toVariant(), pool);
} }
void *JsonValue::operator new(size_t size, JsonMemoryPool *pool)
{ return pool->allocate(size); }
void JsonValue::operator delete(void *)
{ }
void JsonValue::operator delete(void *, JsonMemoryPool *)
{ }
QString JsonValue::kindToString(JsonValue::Kind kind) QString JsonValue::kindToString(JsonValue::Kind kind)
{ {
if (kind == String) if (kind == String)
...@@ -78,39 +92,39 @@ QString JsonValue::kindToString(JsonValue::Kind kind) ...@@ -78,39 +92,39 @@ QString JsonValue::kindToString(JsonValue::Kind kind)
return QLatin1String("unkown"); return QLatin1String("unkown");
} }
JsonValue *JsonValue::build(const QVariant &variant) JsonValue *JsonValue::build(const QVariant &variant, JsonMemoryPool *pool)
{ {
switch (variant.type()) { switch (variant.type()) {
case QVariant::List: { case QVariant::List: {
JsonArrayValue *newValue = new JsonArrayValue; JsonArrayValue *newValue = new (pool) JsonArrayValue;
foreach (const QVariant &element, variant.toList()) foreach (const QVariant &element, variant.toList())
newValue->addElement(build(element)); newValue->addElement(build(element, pool));
return newValue; return newValue;
} }
case QVariant::Map: { case QVariant::Map: {
JsonObjectValue *newValue = new JsonObjectValue; JsonObjectValue *newValue = new (pool) JsonObjectValue;
const QVariantMap variantMap = variant.toMap(); const QVariantMap variantMap = variant.toMap();
for (QVariantMap::const_iterator it = variantMap.begin(); it != variantMap.end(); ++it) for (QVariantMap::const_iterator it = variantMap.begin(); it != variantMap.end(); ++it)
newValue->addMember(it.key(), build(it.value())); newValue->addMember(it.key(), build(it.value(), pool));
return newValue; return newValue;
} }
case QVariant::String: case QVariant::String:
return new JsonStringValue(variant.toString()); return new (pool) JsonStringValue(variant.toString());
case QVariant::Int: case QVariant::Int:
return new JsonIntValue(variant.toInt()); return new (pool) JsonIntValue(variant.toInt());
case QVariant::Double: case QVariant::Double:
return new JsonDoubleValue(variant.toDouble()); return new (pool) JsonDoubleValue(variant.toDouble());
case QVariant::Bool: case QVariant::Bool:
return new JsonBooleanValue(variant.toBool()); return new (pool) JsonBooleanValue(variant.toBool());
case QVariant::Invalid: case QVariant::Invalid:
return new JsonNullValue; return new (pool) JsonNullValue;
default: default:
break; break;
...@@ -727,7 +741,7 @@ JsonSchema *JsonSchemaManager::parseSchema(const QString &schemaFileName) const ...@@ -727,7 +741,7 @@ JsonSchema *JsonSchemaManager::parseSchema(const QString &schemaFileName) const
FileReader reader; FileReader reader;
if (reader.fetch(schemaFileName, QIODevice::Text)) { if (reader.fetch(schemaFileName, QIODevice::Text)) {
const QString &contents = QString::fromUtf8(reader.data()); const QString &contents = QString::fromUtf8(reader.data());
JsonValue *json = JsonValue::create(contents); JsonValue *json = JsonValue::create(contents, &m_pool);
if (json && json->kind() == JsonValue::Object) if (json && json->kind() == JsonValue::Object)
return new JsonSchema(json->toObject(), this); return new JsonSchema(json->toObject(), this);
} }
......
...@@ -49,6 +49,22 @@ class JsonArrayValue; ...@@ -49,6 +49,22 @@ class JsonArrayValue;
class JsonBooleanValue; class JsonBooleanValue;
class JsonNullValue; class JsonNullValue;
class QTCREATOR_UTILS_EXPORT JsonMemoryPool
{
public:
~JsonMemoryPool();
inline void *allocate(size_t size)
{
char *obj = new char[size];
_objs.append(obj);
return obj;
}
private:
QVector<char *> _objs;
};
/*! /*!
* \brief The JsonValue class * \brief The JsonValue class
*/ */
...@@ -79,13 +95,16 @@ public: ...@@ -79,13 +95,16 @@ public:
virtual JsonBooleanValue *toBoolean() { return 0; } virtual JsonBooleanValue *toBoolean() { return 0; }
virtual JsonNullValue *toNull() { return 0; } virtual JsonNullValue *toNull() { return 0; }
static JsonValue *create(const QString &s); static JsonValue *create(const QString &s, JsonMemoryPool *pool);
void *operator new(size_t size, JsonMemoryPool *pool);
void operator delete(void *);
void operator delete(void *, JsonMemoryPool *);
protected: protected:
JsonValue(Kind kind); JsonValue(Kind kind);
private: private:
static JsonValue *build(const QVariant &varixant); static JsonValue *build(const QVariant &varixant, JsonMemoryPool *pool);
Kind m_kind; Kind m_kind;
}; };
...@@ -398,6 +417,7 @@ private: ...@@ -398,6 +417,7 @@ private:
QStringList m_searchPaths; QStringList m_searchPaths;
mutable QHash<QString, JsonSchemaData> m_schemas; mutable QHash<QString, JsonSchemaData> m_schemas;
mutable JsonMemoryPool m_pool;
}; };
} // namespace Utils } // namespace Utils
......
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