Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qjsvalueiterator.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
7#include "qjsvalue_p.h"
8#include "private/qv4string_p.h"
9#include "private/qv4object_p.h"
10#include "private/qv4context_p.h"
11
13
14QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValue &v)
15{
16 init(v);
17}
18
19void QJSValueIteratorPrivate::init(const QJSValue &v)
20{
21 engine = nullptr;
22
23 QV4::ExecutionEngine *e = QJSValuePrivate::engine(&v);
24 if (!e)
25 return;
26 const QV4::Object *o = QJSValuePrivate::asManagedType<QV4::Object>(&v);
27 if (!o)
28 return;
29
30 engine = e;
31 object.set(e, o->asReturnedValue());
32 iterator.reset(o->ownPropertyKeys(object.valueRef()));
33 next();
34}
35
36void QJSValueIteratorPrivate::next()
37{
38 QV4::Object *o = object.as<QV4::Object>();
39 if (!o || !iterator)
40 return;
41
42 QV4::PropertyKey key;
43 while (1) {
44 key = iterator->next(o);
45 if (!key.isSymbol())
46 break;
47 }
48 currentKey = nextKey;
49 nextKey.set(engine, key.id());
50}
51
52bool QJSValueIteratorPrivate::isValid() const
53{
54 if (!engine || !iterator)
55 return false;
56 QV4::Value *val = object.valueRef();
57 return (val && val->isObject());
58}
59
60/*!
61 \class QJSValueIterator
62
63 \brief The QJSValueIterator class provides a Java-style iterator for QJSValue.
64
65 \ingroup qtjavascript
66 \inmodule QtQml
67
68
69 The QJSValueIterator constructor takes a QJSValue as
70 argument. After construction, the iterator is located at the very
71 beginning of the sequence of properties. Here's how to iterate over
72 all the properties of a QJSValue:
73
74 \snippet code/src_script_qjsvalueiterator.cpp 0
75
76 The next() advances the iterator. The name() and value()
77 functions return the name and value of the last item that was
78 jumped over.
79
80 Note that QJSValueIterator only iterates over the QJSValue's
81 own properties; i.e. it does not follow the prototype chain. You can
82 use a loop like this to follow the prototype chain:
83
84 \snippet code/src_script_qjsvalueiterator.cpp 1
85
86 \sa QJSValue::property()
87*/
88
89/*!
90 Constructs an iterator for traversing \a object. The iterator is
91 set to be at the front of the sequence of properties (before the
92 first property).
93*/
94QJSValueIterator::QJSValueIterator(const QJSValue& object)
95 : d_ptr(new QJSValueIteratorPrivate(object))
96{
97}
98
99/*!
100 Destroys the iterator.
101*/
102QJSValueIterator::~QJSValueIterator()
103{
104}
105
106/*!
107 Returns true if there is at least one item ahead of the iterator
108 (i.e. the iterator is \e not at the back of the property sequence);
109 otherwise returns false.
110
111 \sa next()
112*/
113bool QJSValueIterator::hasNext() const
114{
115 if (!d_ptr->isValid())
116 return false;
117 return QV4::PropertyKey::fromId(d_ptr->nextKey.value()).isValid();
118}
119
120/*!
121 Advances the iterator by one position.
122 Returns true if there was at least one item ahead of the iterator
123 (i.e. the iterator was \e not already at the back of the property sequence);
124 otherwise returns false.
125
126 \sa hasNext(), name()
127*/
128bool QJSValueIterator::next()
129{
130 if (!d_ptr->isValid())
131 return false;
132 d_ptr->next();
133 return QV4::PropertyKey::fromId(d_ptr->currentKey.value()).isValid();
134}
135
136/*!
137 Returns the name of the last property that was jumped over using
138 next().
139
140 \sa value()
141*/
142QString QJSValueIterator::name() const
143{
144 if (!d_ptr->isValid())
145 return QString();
146 QV4::Scope scope(d_ptr->engine);
147 QV4::ScopedPropertyKey key(scope, QV4::PropertyKey::fromId(d_ptr->currentKey.value()));
148 if (!key->isValid())
149 return QString();
150 Q_ASSERT(!key->isSymbol());
151 return key->toStringOrSymbol(d_ptr->engine)->toQString();
152}
153
154
155/*!
156 Returns the value of the last property that was jumped over using
157 next().
158
159 \sa name()
160*/
161QJSValue QJSValueIterator::value() const
162{
163 if (!d_ptr->isValid())
164 return QJSValue();
165 QV4::Scope scope(d_ptr->engine);
166 QV4::ScopedPropertyKey key(scope, QV4::PropertyKey::fromId(d_ptr->currentKey.value()));
167 if (!key->isValid())
168 return QJSValue();
169
170 QV4::ScopedObject obj(scope, d_ptr->object.asManaged());
171 QV4::ScopedValue val(scope, obj->get(key));
172
173 if (scope.hasException()) {
174 scope.engine->catchException();
175 return QJSValue();
176 }
177 return QJSValuePrivate::fromReturnedValue(val->asReturnedValue());
178}
179
180
181/*!
182 Makes the iterator operate on \a object. The iterator is set to be
183 at the front of the sequence of properties (before the first
184 property).
185*/
186QJSValueIterator& QJSValueIterator::operator=(QJSValue& object)
187{
188 d_ptr->init(object);
189 return *this;
190}
191
192QT_END_NAMESPACE
Combined button and popup list for selecting options.