diff options
author | Kent Hansen <kent.hansen@nokia.com> | 2012-03-23 18:14:29 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-16 09:25:06 +0200 |
commit | e5f45d9b57bb0542ec47e5a8a4e57388b6d59d35 (patch) | |
tree | 039622ca4f22c5be93cd491d506fe49427ae9672 /src/qml/qml/v8/qv8jsonwrapper.cpp | |
parent | 31c5b237c4f0eb6848c7d2e3ae84232c6f8f6d26 (diff) |
Add QJson support to QV8Engine
Make QV8Engine perform direct conversion between JavaScript values
and QJson{Value,Object,Array}.
This implementation always makes a deep clone of the
QJson{Object,Array} when converting to JS; it might make sense to add
a lazy conversion scheme for dealing with large objects.
Change-Id: Id0b65891a19515ce22f1e51fa8a28d9f3e595271
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Reviewed-by: Jamey Hicks <jamey.hicks@nokia.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'src/qml/qml/v8/qv8jsonwrapper.cpp')
-rw-r--r-- | src/qml/qml/v8/qv8jsonwrapper.cpp | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/src/qml/qml/v8/qv8jsonwrapper.cpp b/src/qml/qml/v8/qv8jsonwrapper.cpp new file mode 100644 index 0000000000..ff8cc4faba --- /dev/null +++ b/src/qml/qml/v8/qv8jsonwrapper.cpp @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qv8jsonwrapper_p.h" +#include "qv8engine_p.h" +#include "qjsconverter_impl_p.h" + +#include <QtCore/qjsonarray.h> +#include <QtCore/qjsonobject.h> +#include <QtCore/qjsonvalue.h> + +QT_BEGIN_NAMESPACE + +QV8JsonWrapper::QV8JsonWrapper() +: m_engine(0) +{ +} + +QV8JsonWrapper::~QV8JsonWrapper() +{ +} + +void QV8JsonWrapper::init(QV8Engine *engine) +{ + m_engine = engine; +} + +void QV8JsonWrapper::destroy() +{ +} + +v8::Handle<v8::Value> QV8JsonWrapper::fromJsonValue(const QJsonValue &value) +{ + if (value.isString()) + return QJSConverter::toString(value.toString()); + else if (value.isDouble()) + return v8::Number::New(value.toDouble()); + else if (value.isBool()) + return value.toBool() ? v8::True() : v8::False(); + else if (value.isArray()) + return fromJsonArray(value.toArray()); + else if (value.isObject()) + return fromJsonObject(value.toObject()); + else if (value.isNull()) + return v8::Null(); + else + return v8::Undefined(); +} + +QJsonValue QV8JsonWrapper::toJsonValue(v8::Handle<v8::Value> value) +{ + if (value->IsString()) + return QJsonValue(QJSConverter::toString(value.As<v8::String>())); + else if (value->IsNumber()) + return QJsonValue(value->NumberValue()); + else if (value->IsBoolean()) + return QJsonValue(value->BooleanValue()); + else if (value->IsArray()) + return toJsonArray(value.As<v8::Array>()); + else if (value->IsObject()) + return toJsonObject(value.As<v8::Object>()); + else if (value->IsNull()) + return QJsonValue(QJsonValue::Null); + else + return QJsonValue(QJsonValue::Undefined); +} + +v8::Local<v8::Object> QV8JsonWrapper::fromJsonObject(const QJsonObject &object) +{ + v8::Local<v8::Object> v8object = v8::Object::New(); + for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it) + v8object->Set(QJSConverter::toString(it.key()), fromJsonValue(it.value())); + return v8object; +} + +QJsonObject QV8JsonWrapper::toJsonObject(v8::Handle<v8::Value> value) +{ + QJsonObject result; + if (!value->IsObject() || value->IsArray() || value->IsFunction()) + return result; + + v8::Handle<v8::Object> v8object(value.As<v8::Object>()); + int hash = v8object->GetIdentityHash(); + if (m_visitedConversionObjects.contains(hash)) { + // Avoid recursion. + // For compatibility with QVariant{List,Map} conversion, we return an + // empty object (and no error is thrown). + return result; + } + + m_visitedConversionObjects.insert(hash); + + v8::Local<v8::Array> propertyNames = m_engine->getOwnPropertyNames(v8object); + uint32_t length = propertyNames->Length(); + for (uint32_t i = 0; i < length; ++i) { + v8::Local<v8::Value> name = propertyNames->Get(i); + v8::Local<v8::Value> propertyValue = v8object->Get(name); + if (!propertyValue->IsFunction()) + result.insert(QJSConverter::toString(name->ToString()), toJsonValue(propertyValue)); + } + + m_visitedConversionObjects.remove(hash); + + return result; +} + +v8::Local<v8::Array> QV8JsonWrapper::fromJsonArray(const QJsonArray &array) +{ + int size = array.size(); + v8::Local<v8::Array> v8array = v8::Array::New(size); + for (int i = 0; i < size; i++) + v8array->Set(i, fromJsonValue(array.at(i))); + return v8array; +} + +QJsonArray QV8JsonWrapper::toJsonArray(v8::Handle<v8::Value> value) +{ + QJsonArray result; + if (!value->IsArray()) + return result; + + v8::Handle<v8::Array> v8array(value.As<v8::Array>()); + int hash = v8array->GetIdentityHash(); + if (m_visitedConversionObjects.contains(hash)) { + // Avoid recursion. + // For compatibility with QVariant{List,Map} conversion, we return an + // empty array (and no error is thrown). + return result; + } + + m_visitedConversionObjects.insert(hash); + + uint32_t length = v8array->Length(); + for (uint32_t i = 0; i < length; ++i) { + v8::Local<v8::Value> element = v8array->Get(i); + if (!element->IsFunction()) + result.append(toJsonValue(element)); + } + + m_visitedConversionObjects.remove(hash); + + return result; +} + +QT_END_NAMESPACE |