1 /****************************************************************************
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtScript module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL-ONLY$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser
12 ** General Public License version 2.1 as published by the Free Software
13 ** Foundation and appearing in the file LICENSE.LGPL included in the
14 ** packaging of this file. Please review the following information to
15 ** ensure the GNU Lesser General Public License version 2.1 requirements
16 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** If you have questions regarding the use of this file, please contact
19 ** Nokia at qt-info@nokia.com.
22 ****************************************************************************/
25 #include "qscriptvalueiterator.h"
27 #include "qscriptstring.h"
28 #include "qscriptengine.h"
29 #include "qscriptengine_p.h"
30 #include "qscriptvalue_p.h"
31 #include "qlinkedlist.h"
35 #include "PropertyNameArray.h"
37 #include "JSFunction.h"
43 \class QScriptValueIterator
45 \brief The QScriptValueIterator class provides a Java-style iterator for QScriptValue.
50 The QScriptValueIterator constructor takes a QScriptValue as
51 argument. After construction, the iterator is located at the very
52 beginning of the sequence of properties. Here's how to iterate over
53 all the properties of a QScriptValue:
55 \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 0
57 The next() advances the iterator. The name(), value() and flags()
58 functions return the name, value and flags of the last item that was
61 If you want to remove properties as you iterate over the
62 QScriptValue, use remove(). If you want to modify the value of a
63 property, use setValue().
65 Note that QScriptValueIterator only iterates over the QScriptValue's
66 own properties; i.e. it does not follow the prototype chain. You can
67 use a loop like this to follow the prototype chain:
69 \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 1
71 Note that QScriptValueIterator will not automatically skip over
72 properties that have the QScriptValue::SkipInEnumeration flag set;
73 that flag only affects iteration in script code. If you want, you
74 can skip over such properties with code like the following:
76 \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 2
78 \sa QScriptValue::property()
81 class QScriptValueIteratorPrivate
84 QScriptValueIteratorPrivate()
87 void ensureInitialized()
91 QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(object.engine());
92 JSC::ExecState *exec = eng_p->globalExec();
93 JSC::PropertyNameArray propertyNamesArray(exec);
94 propertyNamesArray.setShouldCache(false);
95 JSC::asObject(QScriptValuePrivate::get(object)->jscValue)->getOwnPropertyNames(exec, propertyNamesArray, /*includeNonEnumerable=*/true);
97 JSC::PropertyNameArray::const_iterator propertyNamesIt = propertyNamesArray.begin();
98 for(; propertyNamesIt != propertyNamesArray.end(); ++propertyNamesIt) {
99 propertyNames.append(propertyNamesIt->ustring());
101 it = propertyNames.begin();
106 QLinkedList<JSC::UString> propertyNames;
107 QLinkedList<JSC::UString>::iterator it;
108 QLinkedList<JSC::UString>::iterator current;
113 Constructs an iterator for traversing \a object. The iterator is
114 set to be at the front of the sequence of properties (before the
117 QScriptValueIterator::QScriptValueIterator(const QScriptValue &object)
120 if (object.isObject()) {
121 d_ptr.reset(new QScriptValueIteratorPrivate());
122 d_ptr->object = object;
127 Destroys the iterator.
129 QScriptValueIterator::~QScriptValueIterator()
134 Returns true if there is at least one item ahead of the iterator
135 (i.e. the iterator is \e not at the back of the property sequence);
136 otherwise returns false.
138 \sa next(), hasPrevious()
140 bool QScriptValueIterator::hasNext() const
142 Q_D(const QScriptValueIterator);
146 const_cast<QScriptValueIteratorPrivate*>(d)->ensureInitialized();
147 return d->it != d->propertyNames.end();
151 Advances the iterator by one position.
153 Calling this function on an iterator located at the back of the
154 container leads to undefined results.
156 \sa hasNext(), previous(), name()
158 void QScriptValueIterator::next()
160 Q_D(QScriptValueIterator);
163 d->ensureInitialized();
170 Returns true if there is at least one item behind the iterator
171 (i.e. the iterator is \e not at the front of the property sequence);
172 otherwise returns false.
174 \sa previous(), hasNext()
176 bool QScriptValueIterator::hasPrevious() const
178 Q_D(const QScriptValueIterator);
182 const_cast<QScriptValueIteratorPrivate*>(d)->ensureInitialized();
183 return d->it != d->propertyNames.begin();
187 Moves the iterator back by one position.
189 Calling this function on an iterator located at the front of the
190 container leads to undefined results.
192 \sa hasPrevious(), next(), name()
194 void QScriptValueIterator::previous()
196 Q_D(QScriptValueIterator);
199 d->ensureInitialized();
205 Moves the iterator to the front of the QScriptValue (before the
210 void QScriptValueIterator::toFront()
212 Q_D(QScriptValueIterator);
215 d->ensureInitialized();
216 d->it = d->propertyNames.begin();
220 Moves the iterator to the back of the QScriptValue (after the
223 \sa toFront(), previous()
225 void QScriptValueIterator::toBack()
227 Q_D(QScriptValueIterator);
230 d->ensureInitialized();
231 d->it = d->propertyNames.end();
235 Returns the name of the last property that was jumped over using
236 next() or previous().
240 QString QScriptValueIterator::name() const
242 Q_D(const QScriptValueIterator);
243 if (!d || !d->initialized)
251 Returns the name of the last property that was jumped over using
252 next() or previous().
254 QScriptString QScriptValueIterator::scriptName() const
256 Q_D(const QScriptValueIterator);
257 if (!d || !d->initialized)
258 return QScriptString();
259 return d->object.engine()->toStringHandle(name());
263 Returns the value of the last property that was jumped over using
264 next() or previous().
266 \sa setValue(), name()
268 QScriptValue QScriptValueIterator::value() const
270 Q_D(const QScriptValueIterator);
271 if (!d || !d->initialized)
272 return QScriptValue();
273 return d->object.property(name());
277 Sets the \a value of the last property that was jumped over using
278 next() or previous().
282 void QScriptValueIterator::setValue(const QScriptValue &value)
284 Q_D(QScriptValueIterator);
285 if (!d || !d->initialized)
287 d->object.setProperty(name(), value);
291 Returns the flags of the last property that was jumped over using
292 next() or previous().
296 QScriptValue::PropertyFlags QScriptValueIterator::flags() const
298 Q_D(const QScriptValueIterator);
299 if (!d || !d->initialized)
301 return d->object.propertyFlags(name());
305 Removes the last property that was jumped over using next()
310 void QScriptValueIterator::remove()
312 Q_D(QScriptValueIterator);
313 if (!d || !d->initialized)
315 d->object.setProperty(name(), QScriptValue());
316 d->propertyNames.erase(d->current);
320 Makes the iterator operate on \a object. The iterator is set to be
321 at the front of the sequence of properties (before the first
324 QScriptValueIterator& QScriptValueIterator::operator=(QScriptValue &object)
327 if (object.isObject()) {
328 d_ptr.reset(new QScriptValueIteratorPrivate());
329 d_ptr->object = object;