source: trunk/src/script/api/qscriptvalueiterator.cpp@ 651

Last change on this file since 651 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

  • Property svn:eol-style set to native
File size: 8.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtScript module of the Qt Toolkit.
8**
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.
17**
18** If you have questions regarding the use of this file, please contact
19** Nokia at [email protected].
20** $QT_END_LICENSE$
21**
22****************************************************************************/
23
24#include "config.h"
25#include "qscriptvalueiterator.h"
26
27#include "qscriptstring.h"
28#include "qscriptengine.h"
29#include "qscriptengine_p.h"
30#include "qscriptvalue_p.h"
31#include "qlinkedlist.h"
32
33
34#include "JSObject.h"
35#include "PropertyNameArray.h"
36#include "JSArray.h"
37#include "JSFunction.h"
38
39QT_BEGIN_NAMESPACE
40
41/*!
42 \since 4.3
43 \class QScriptValueIterator
44
45 \brief The QScriptValueIterator class provides a Java-style iterator for QScriptValue.
46
47 \ingroup script
48
49
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:
54
55 \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 0
56
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
59 jumped over.
60
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().
64
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:
68
69 \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 1
70
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:
75
76 \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 2
77
78 \sa QScriptValue::property()
79*/
80
81class QScriptValueIteratorPrivate
82{
83public:
84 QScriptValueIteratorPrivate()
85 : initialized(false)
86 {}
87 void ensureInitialized()
88 {
89 if (initialized)
90 return;
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);
96
97 JSC::PropertyNameArray::const_iterator propertyNamesIt = propertyNamesArray.begin();
98 for(; propertyNamesIt != propertyNamesArray.end(); ++propertyNamesIt) {
99 propertyNames.append(propertyNamesIt->ustring());
100 }
101 it = propertyNames.begin();
102 initialized = true;
103 }
104
105 QScriptValue object;
106 QLinkedList<JSC::UString> propertyNames;
107 QLinkedList<JSC::UString>::iterator it;
108 QLinkedList<JSC::UString>::iterator current;
109 bool initialized;
110};
111
112/*!
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
115 first property).
116*/
117QScriptValueIterator::QScriptValueIterator(const QScriptValue &object)
118 : d_ptr(0)
119{
120 if (object.isObject()) {
121 d_ptr.reset(new QScriptValueIteratorPrivate());
122 d_ptr->object = object;
123 }
124}
125
126/*!
127 Destroys the iterator.
128*/
129QScriptValueIterator::~QScriptValueIterator()
130{
131}
132
133/*!
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.
137
138 \sa next(), hasPrevious()
139*/
140bool QScriptValueIterator::hasNext() const
141{
142 Q_D(const QScriptValueIterator);
143 if (!d)
144 return false;
145
146 const_cast<QScriptValueIteratorPrivate*>(d)->ensureInitialized();
147 return d->it != d->propertyNames.end();
148}
149
150/*!
151 Advances the iterator by one position.
152
153 Calling this function on an iterator located at the back of the
154 container leads to undefined results.
155
156 \sa hasNext(), previous(), name()
157*/
158void QScriptValueIterator::next()
159{
160 Q_D(QScriptValueIterator);
161 if (!d)
162 return;
163 d->ensureInitialized();
164
165 d->current = d->it;
166 ++(d->it);
167}
168
169/*!
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.
173
174 \sa previous(), hasNext()
175*/
176bool QScriptValueIterator::hasPrevious() const
177{
178 Q_D(const QScriptValueIterator);
179 if (!d)
180 return false;
181
182 const_cast<QScriptValueIteratorPrivate*>(d)->ensureInitialized();
183 return d->it != d->propertyNames.begin();
184}
185
186/*!
187 Moves the iterator back by one position.
188
189 Calling this function on an iterator located at the front of the
190 container leads to undefined results.
191
192 \sa hasPrevious(), next(), name()
193*/
194void QScriptValueIterator::previous()
195{
196 Q_D(QScriptValueIterator);
197 if (!d)
198 return;
199 d->ensureInitialized();
200 --(d->it);
201 d->current = d->it;
202}
203
204/*!
205 Moves the iterator to the front of the QScriptValue (before the
206 first property).
207
208 \sa toBack(), next()
209*/
210void QScriptValueIterator::toFront()
211{
212 Q_D(QScriptValueIterator);
213 if (!d)
214 return;
215 d->ensureInitialized();
216 d->it = d->propertyNames.begin();
217}
218
219/*!
220 Moves the iterator to the back of the QScriptValue (after the
221 last property).
222
223 \sa toFront(), previous()
224*/
225void QScriptValueIterator::toBack()
226{
227 Q_D(QScriptValueIterator);
228 if (!d)
229 return;
230 d->ensureInitialized();
231 d->it = d->propertyNames.end();
232}
233
234/*!
235 Returns the name of the last property that was jumped over using
236 next() or previous().
237
238 \sa value(), flags()
239*/
240QString QScriptValueIterator::name() const
241{
242 Q_D(const QScriptValueIterator);
243 if (!d || !d->initialized)
244 return QString();
245 return *d->current;
246}
247
248/*!
249 \since 4.4
250
251 Returns the name of the last property that was jumped over using
252 next() or previous().
253*/
254QScriptString QScriptValueIterator::scriptName() const
255{
256 Q_D(const QScriptValueIterator);
257 if (!d || !d->initialized)
258 return QScriptString();
259 return d->object.engine()->toStringHandle(name());
260}
261
262/*!
263 Returns the value of the last property that was jumped over using
264 next() or previous().
265
266 \sa setValue(), name()
267*/
268QScriptValue QScriptValueIterator::value() const
269{
270 Q_D(const QScriptValueIterator);
271 if (!d || !d->initialized)
272 return QScriptValue();
273 return d->object.property(name());
274}
275
276/*!
277 Sets the \a value of the last property that was jumped over using
278 next() or previous().
279
280 \sa value(), name()
281*/
282void QScriptValueIterator::setValue(const QScriptValue &value)
283{
284 Q_D(QScriptValueIterator);
285 if (!d || !d->initialized)
286 return;
287 d->object.setProperty(name(), value);
288}
289
290/*!
291 Returns the flags of the last property that was jumped over using
292 next() or previous().
293
294 \sa value()
295*/
296QScriptValue::PropertyFlags QScriptValueIterator::flags() const
297{
298 Q_D(const QScriptValueIterator);
299 if (!d || !d->initialized)
300 return 0;
301 return d->object.propertyFlags(name());
302}
303
304/*!
305 Removes the last property that was jumped over using next()
306 or previous().
307
308 \sa setValue()
309*/
310void QScriptValueIterator::remove()
311{
312 Q_D(QScriptValueIterator);
313 if (!d || !d->initialized)
314 return;
315 d->object.setProperty(name(), QScriptValue());
316 d->propertyNames.erase(d->current);
317}
318
319/*!
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
322 property).
323*/
324QScriptValueIterator& QScriptValueIterator::operator=(QScriptValue &object)
325{
326 d_ptr.reset();
327 if (object.isObject()) {
328 d_ptr.reset(new QScriptValueIteratorPrivate());
329 d_ptr->object = object;
330 }
331 return *this;
332}
333
334QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.