forked from qt-creator/qt-creator
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: Fawzi Mohamed <fawzi.mohamed@digia.com>
This commit is contained in:
@@ -250,6 +250,8 @@ QStringList QmlBundle::maybeReadTrie(Trie &trie, Utils::JsonObjectValue *config,
|
||||
|
||||
bool QmlBundle::readFrom(QString path, QStringList *errors)
|
||||
{
|
||||
Utils::JsonMemoryPool pool;
|
||||
|
||||
using namespace Utils;
|
||||
QFile f(path);
|
||||
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
@@ -257,7 +259,7 @@ bool QmlBundle::readFrom(QString path, QStringList *errors)
|
||||
(*errors) << QString::fromLatin1("Could not open file at %1 .").arg(path);
|
||||
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 (errors)
|
||||
(*errors) << QString::fromLatin1("Could not parse json object in file at %1 .").arg(path);
|
||||
|
@@ -39,6 +39,11 @@
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
JsonMemoryPool::~JsonMemoryPool()
|
||||
{
|
||||
foreach (char *obj, _objs)
|
||||
delete[] obj;
|
||||
}
|
||||
|
||||
JsonValue::JsonValue(Kind kind)
|
||||
: m_kind(kind)
|
||||
@@ -47,7 +52,7 @@ JsonValue::JsonValue(Kind kind)
|
||||
JsonValue::~JsonValue()
|
||||
{}
|
||||
|
||||
JsonValue *JsonValue::create(const QString &s)
|
||||
JsonValue *JsonValue::create(const QString &s, JsonMemoryPool *pool)
|
||||
{
|
||||
QScriptEngine engine;
|
||||
QScriptValue jsonParser = engine.evaluate(QLatin1String("JSON.parse"));
|
||||
@@ -55,9 +60,18 @@ JsonValue *JsonValue::create(const QString &s)
|
||||
if (engine.hasUncaughtException() || !value.isValid())
|
||||
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)
|
||||
{
|
||||
if (kind == String)
|
||||
@@ -78,39 +92,39 @@ QString JsonValue::kindToString(JsonValue::Kind kind)
|
||||
return QLatin1String("unkown");
|
||||
}
|
||||
|
||||
JsonValue *JsonValue::build(const QVariant &variant)
|
||||
JsonValue *JsonValue::build(const QVariant &variant, JsonMemoryPool *pool)
|
||||
{
|
||||
switch (variant.type()) {
|
||||
|
||||
case QVariant::List: {
|
||||
JsonArrayValue *newValue = new JsonArrayValue;
|
||||
JsonArrayValue *newValue = new (pool) JsonArrayValue;
|
||||
foreach (const QVariant &element, variant.toList())
|
||||
newValue->addElement(build(element));
|
||||
newValue->addElement(build(element, pool));
|
||||
return newValue;
|
||||
}
|
||||
|
||||
case QVariant::Map: {
|
||||
JsonObjectValue *newValue = new JsonObjectValue;
|
||||
JsonObjectValue *newValue = new (pool) JsonObjectValue;
|
||||
const QVariantMap variantMap = variant.toMap();
|
||||
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;
|
||||
}
|
||||
|
||||
case QVariant::String:
|
||||
return new JsonStringValue(variant.toString());
|
||||
return new (pool) JsonStringValue(variant.toString());
|
||||
|
||||
case QVariant::Int:
|
||||
return new JsonIntValue(variant.toInt());
|
||||
return new (pool) JsonIntValue(variant.toInt());
|
||||
|
||||
case QVariant::Double:
|
||||
return new JsonDoubleValue(variant.toDouble());
|
||||
return new (pool) JsonDoubleValue(variant.toDouble());
|
||||
|
||||
case QVariant::Bool:
|
||||
return new JsonBooleanValue(variant.toBool());
|
||||
return new (pool) JsonBooleanValue(variant.toBool());
|
||||
|
||||
case QVariant::Invalid:
|
||||
return new JsonNullValue;
|
||||
return new (pool) JsonNullValue;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -727,7 +741,7 @@ JsonSchema *JsonSchemaManager::parseSchema(const QString &schemaFileName) const
|
||||
FileReader reader;
|
||||
if (reader.fetch(schemaFileName, QIODevice::Text)) {
|
||||
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)
|
||||
return new JsonSchema(json->toObject(), this);
|
||||
}
|
||||
|
@@ -49,6 +49,22 @@ class JsonArrayValue;
|
||||
class JsonBooleanValue;
|
||||
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
|
||||
*/
|
||||
@@ -79,13 +95,16 @@ public:
|
||||
virtual JsonBooleanValue *toBoolean() { 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:
|
||||
JsonValue(Kind kind);
|
||||
|
||||
private:
|
||||
static JsonValue *build(const QVariant &varixant);
|
||||
static JsonValue *build(const QVariant &varixant, JsonMemoryPool *pool);
|
||||
|
||||
Kind m_kind;
|
||||
};
|
||||
@@ -398,6 +417,7 @@ private:
|
||||
|
||||
QStringList m_searchPaths;
|
||||
mutable QHash<QString, JsonSchemaData> m_schemas;
|
||||
mutable JsonMemoryPool m_pool;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
|
Reference in New Issue
Block a user