Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / v8 / qv8sequencewrapper.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtDeclarative/qdeclarative.h>
43
44 #include "qv8sequencewrapper_p.h"
45 #include "qv8sequencewrapper_p_p.h"
46 #include "qv8engine_p.h"
47
48 QT_BEGIN_NAMESPACE
49
50 QV8SequenceWrapper::QV8SequenceWrapper()
51     : m_engine(0)
52 {
53 }
54
55 QV8SequenceWrapper::~QV8SequenceWrapper()
56 {
57 }
58
59 #define REGISTER_QML_SEQUENCE_METATYPE(unused, unused2, SequenceType, unused3) qRegisterMetaType<SequenceType>();
60 void QV8SequenceWrapper::init(QV8Engine *engine)
61 {
62     FOREACH_QML_SEQUENCE_TYPE(REGISTER_QML_SEQUENCE_METATYPE)
63
64     m_engine = engine;
65     m_toString = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ToString)->GetFunction());
66     m_valueOf = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ValueOf)->GetFunction());
67     v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
68     ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter);
69     ft->InstanceTemplate()->SetIndexedPropertyHandler(IndexedGetter, IndexedSetter, 0, IndexedDeleter, IndexedEnumerator);
70     ft->InstanceTemplate()->SetAccessor(v8::String::New("length"), LengthGetter, LengthSetter,
71                                         v8::Handle<v8::Value>(), v8::DEFAULT,
72                                         v8::PropertyAttribute(v8::DontDelete | v8::DontEnum));
73     ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0,
74                                         m_toString, v8::DEFAULT,
75                                         v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete | v8::DontEnum));
76     ft->InstanceTemplate()->SetAccessor(v8::String::New("valueOf"), ValueOfGetter, 0,
77                                         m_valueOf, v8::DEFAULT,
78                                         v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete | v8::DontEnum));
79     ft->InstanceTemplate()->SetHasExternalResource(true);
80     ft->InstanceTemplate()->MarkAsUseUserObjectComparison();
81     m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
82 }
83 #undef REGISTER_QML_SEQUENCE_METATYPE
84
85 void QV8SequenceWrapper::destroy()
86 {
87     qPersistentDispose(m_toString);
88     qPersistentDispose(m_valueOf);
89     qPersistentDispose(m_constructor);
90 }
91
92 bool QV8SequenceWrapper::isEqual(QV8ObjectResource *lhs, QV8ObjectResource *rhs)
93 {
94     Q_ASSERT(lhs && rhs && lhs->resourceType() == QV8ObjectResource::SequenceType && rhs->resourceType() == QV8ObjectResource::SequenceType);
95     QV8SequenceResource *lr = static_cast<QV8SequenceResource *>(lhs);
96     QV8SequenceResource *rr = static_cast<QV8SequenceResource *>(rhs);
97     return lr->isEqual(rr);
98 }
99
100 quint32 QV8SequenceWrapper::sequenceLength(QV8ObjectResource *r)
101 {
102     Q_ASSERT(r->resourceType() == QV8ObjectResource::SequenceType);
103     QV8SequenceResource *sr = static_cast<QV8SequenceResource *>(r);
104     Q_ASSERT(sr);
105     return sr->lengthGetter();
106 }
107
108 #define NEW_REFERENCE_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
109     if (sequenceType == qMetaTypeId<SequenceType>()) { \
110         r = new QV8##ElementTypeName##SequenceResource(m_engine, object, propertyIndex); \
111     } else
112
113 v8::Local<v8::Object> QV8SequenceWrapper::newSequence(int sequenceType, QObject *object, int propertyIndex, bool *succeeded)
114 {
115     // This function is called when the property is a QObject Q_PROPERTY of
116     // the given sequence type.  Internally we store a typed-sequence
117     // (as well as object ptr + property index for updated-read and write-back)
118     // and so access/mutate avoids variant conversion.
119     *succeeded = true;
120     QV8SequenceResource *r = 0;
121     FOREACH_QML_SEQUENCE_TYPE(NEW_REFERENCE_SEQUENCE) { /* else */ *succeeded = false; return v8::Local<v8::Object>(); }
122
123     v8::Local<v8::Object> rv = m_constructor->NewInstance();
124     rv->SetExternalResource(r);
125     rv->SetPrototype(v8::Array::New(1)->GetPrototype());
126     return rv;
127 }
128 #undef NEW_REFERENCE_SEQUENCE
129
130 #define NEW_COPY_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
131     if (sequenceType == qMetaTypeId<SequenceType>()) { \
132         r = new QV8##ElementTypeName##SequenceResource(m_engine, v.value<SequenceType>()); \
133     } else
134
135 v8::Local<v8::Object> QV8SequenceWrapper::fromVariant(const QVariant& v, bool *succeeded)
136 {
137     // This function is called when assigning a sequence value to a normal JS var
138     // in a JS block.  Internally, we store a sequence of the specified type.
139     // Access and mutation is extremely fast since it will not need to modify any
140     // QObject property.
141     int sequenceType = v.userType();
142     *succeeded = true;
143     QV8SequenceResource *r = 0;
144     FOREACH_QML_SEQUENCE_TYPE(NEW_COPY_SEQUENCE) { /* else */ *succeeded = false; return v8::Local<v8::Object>(); }
145
146     v8::Local<v8::Object> rv = m_constructor->NewInstance();
147     rv->SetExternalResource(r);
148     rv->SetPrototype(v8::Array::New(1)->GetPrototype());
149     return rv;
150 }
151 #undef NEW_COPY_SEQUENCE
152
153 QVariant QV8SequenceWrapper::toVariant(QV8ObjectResource *r)
154 {
155     Q_ASSERT(r->resourceType() == QV8ObjectResource::SequenceType);
156     QV8SequenceResource *resource = static_cast<QV8SequenceResource *>(r);
157     return resource->toVariant();
158 }
159
160 #define SEQUENCE_TO_VARIANT(ElementType, ElementTypeName, SequenceType, unused) \
161     if (typeHint == qMetaTypeId<SequenceType>()) { \
162         return QV8##ElementTypeName##SequenceResource::toVariant(m_engine, array, length, succeeded); \
163     } else
164
165 QVariant QV8SequenceWrapper::toVariant(v8::Handle<v8::Array> array, int typeHint, bool *succeeded)
166 {
167     *succeeded = true;
168     uint32_t length = array->Length();
169     FOREACH_QML_SEQUENCE_TYPE(SEQUENCE_TO_VARIANT) { /* else */ *succeeded = false; return QVariant(); }
170 }
171 #undef SEQUENCE_TO_VARIANT
172
173 v8::Handle<v8::Value> QV8SequenceWrapper::IndexedSetter(quint32 index, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
174 {
175     QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
176     Q_ASSERT(sr);
177     return sr->indexedSetter(index, value);
178 }
179
180 v8::Handle<v8::Value> QV8SequenceWrapper::IndexedGetter(quint32 index, const v8::AccessorInfo &info)
181 {
182     QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
183     Q_ASSERT(sr);
184     return sr->indexedGetter(index);
185 }
186
187 v8::Handle<v8::Boolean> QV8SequenceWrapper::IndexedDeleter(quint32 index, const v8::AccessorInfo &info)
188 {
189     QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
190     Q_ASSERT(sr);
191     return sr->indexedDeleter(index);
192 }
193
194 v8::Handle<v8::Array> QV8SequenceWrapper::IndexedEnumerator(const v8::AccessorInfo &info)
195 {
196     QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
197     Q_ASSERT(sr);
198     return sr->indexedEnumerator();
199 }
200
201 v8::Handle<v8::Value> QV8SequenceWrapper::LengthGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info)
202 {
203     Q_UNUSED(property);
204     QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
205     Q_ASSERT(sr);
206     return v8::Integer::NewFromUnsigned(sr->lengthGetter());
207 }
208
209 void QV8SequenceWrapper::LengthSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
210 {
211     Q_UNUSED(property);
212     QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
213     Q_ASSERT(sr);
214     sr->lengthSetter(value);
215 }
216
217 v8::Handle<v8::Value> QV8SequenceWrapper::ToStringGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info)
218 {
219     Q_UNUSED(property);
220     return info.Data();
221 }
222
223 v8::Handle<v8::Value> QV8SequenceWrapper::ValueOfGetter(v8::Local<v8::String> property,
224                                                                const v8::AccessorInfo &info)
225 {
226     Q_UNUSED(property);
227     return info.Data();
228 }
229
230 v8::Handle<v8::Value> QV8SequenceWrapper::ToString(const v8::Arguments &args)
231 {
232     QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(args.This());
233     Q_ASSERT(sr);
234     return sr->toString();
235 }
236
237 v8::Handle<v8::Value> QV8SequenceWrapper::ValueOf(const v8::Arguments &args)
238 {
239     QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(args.This());
240     Q_ASSERT(sr);
241     v8::Handle<v8::Value> tostringValue = sr->toString();
242     if (!tostringValue.IsEmpty())
243         return tostringValue;
244     return v8::Integer::NewFromUnsigned(sr->lengthGetter());
245 }
246
247 v8::Handle<v8::Value> QV8SequenceWrapper::Getter(v8::Local<v8::String> property,
248                                                     const v8::AccessorInfo &info)
249 {
250     Q_UNUSED(property);
251     Q_UNUSED(info);
252     return v8::Handle<v8::Value>();
253 }
254
255 v8::Handle<v8::Value> QV8SequenceWrapper::Setter(v8::Local<v8::String> property,
256                                                     v8::Local<v8::Value> value,
257                                                     const v8::AccessorInfo &info)
258 {
259     Q_UNUSED(property);
260     Q_UNUSED(info);
261     return value;
262 }
263
264 QT_END_NAMESPACE