source: trunk/examples/script/customclass/bytearrayclass.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 8.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 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 examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include <QtScript/QScriptClassPropertyIterator>
42#include <QtScript/QScriptEngine>
43#include "bytearrayclass.h"
44#include "bytearrayprototype.h"
45
46#include <stdlib.h>
47
48Q_DECLARE_METATYPE(QByteArray*)
49Q_DECLARE_METATYPE(ByteArrayClass*)
50
51class ByteArrayClassPropertyIterator : public QScriptClassPropertyIterator
52{
53public:
54 ByteArrayClassPropertyIterator(const QScriptValue &object);
55 ~ByteArrayClassPropertyIterator();
56
57 bool hasNext() const;
58 void next();
59
60 bool hasPrevious() const;
61 void previous();
62
63 void toFront();
64 void toBack();
65
66 QScriptString name() const;
67 uint id() const;
68
69private:
70 int m_index;
71 int m_last;
72};
73
74//! [0]
75ByteArrayClass::ByteArrayClass(QScriptEngine *engine)
76 : QObject(engine), QScriptClass(engine)
77{
78 qScriptRegisterMetaType<QByteArray>(engine, toScriptValue, fromScriptValue);
79
80 length = engine->toStringHandle(QLatin1String("length"));
81
82 proto = engine->newQObject(new ByteArrayPrototype(this),
83 QScriptEngine::QtOwnership,
84 QScriptEngine::SkipMethodsInEnumeration
85 | QScriptEngine::ExcludeSuperClassMethods
86 | QScriptEngine::ExcludeSuperClassProperties);
87 QScriptValue global = engine->globalObject();
88 proto.setPrototype(global.property("Object").property("prototype"));
89
90 ctor = engine->newFunction(construct, proto);
91 ctor.setData(qScriptValueFromValue(engine, this));
92}
93//! [0]
94
95ByteArrayClass::~ByteArrayClass()
96{
97}
98
99//! [3]
100QScriptClass::QueryFlags ByteArrayClass::queryProperty(const QScriptValue &object,
101 const QScriptString &name,
102 QueryFlags flags, uint *id)
103{
104 QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data());
105 if (!ba)
106 return 0;
107 if (name == length) {
108 return flags;
109 } else {
110 bool isArrayIndex;
111 qint32 pos = name.toArrayIndex(&isArrayIndex);
112 if (!isArrayIndex)
113 return 0;
114 *id = pos;
115 if ((flags & HandlesReadAccess) && (pos >= ba->size()))
116 flags &= ~HandlesReadAccess;
117 return flags;
118 }
119}
120//! [3]
121
122//! [4]
123QScriptValue ByteArrayClass::property(const QScriptValue &object,
124 const QScriptString &name, uint id)
125{
126 QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data());
127 if (!ba)
128 return QScriptValue();
129 if (name == length) {
130 return ba->length();
131 } else {
132 qint32 pos = id;
133 if ((pos < 0) || (pos >= ba->size()))
134 return QScriptValue();
135 return uint(ba->at(pos)) & 255;
136 }
137 return QScriptValue();
138}
139//! [4]
140
141//! [5]
142void ByteArrayClass::setProperty(QScriptValue &object,
143 const QScriptString &name,
144 uint id, const QScriptValue &value)
145{
146 QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data());
147 if (!ba)
148 return;
149 if (name == length) {
150 resize(*ba, value.toInt32());
151 } else {
152 qint32 pos = id;
153 if (pos < 0)
154 return;
155 if (ba->size() <= pos)
156 resize(*ba, pos + 1);
157 (*ba)[pos] = char(value.toInt32());
158 }
159}
160//! [5]
161
162//! [6]
163QScriptValue::PropertyFlags ByteArrayClass::propertyFlags(
164 const QScriptValue &/*object*/, const QScriptString &name, uint /*id*/)
165{
166 if (name == length) {
167 return QScriptValue::Undeletable
168 | QScriptValue::SkipInEnumeration;
169 }
170 return QScriptValue::Undeletable;
171}
172//! [6]
173
174//! [7]
175QScriptClassPropertyIterator *ByteArrayClass::newIterator(const QScriptValue &object)
176{
177 return new ByteArrayClassPropertyIterator(object);
178}
179//! [7]
180
181QString ByteArrayClass::name() const
182{
183 return QLatin1String("ByteArray");
184}
185
186QScriptValue ByteArrayClass::prototype() const
187{
188 return proto;
189}
190
191QScriptValue ByteArrayClass::constructor()
192{
193 return ctor;
194}
195
196//! [10]
197QScriptValue ByteArrayClass::newInstance(int size)
198{
199 engine()->reportAdditionalMemoryCost(size);
200 return newInstance(QByteArray(size, /*ch=*/0));
201}
202//! [10]
203
204//! [1]
205QScriptValue ByteArrayClass::newInstance(const QByteArray &ba)
206{
207 QScriptValue data = engine()->newVariant(qVariantFromValue(ba));
208 return engine()->newObject(this, data);
209}
210//! [1]
211
212//! [2]
213QScriptValue ByteArrayClass::construct(QScriptContext *ctx, QScriptEngine *)
214{
215 ByteArrayClass *cls = qscriptvalue_cast<ByteArrayClass*>(ctx->callee().data());
216 if (!cls)
217 return QScriptValue();
218 QScriptValue arg = ctx->argument(0);
219 if (arg.instanceOf(ctx->callee()))
220 return cls->newInstance(qscriptvalue_cast<QByteArray>(arg));
221 int size = arg.toInt32();
222 return cls->newInstance(size);
223}
224//! [2]
225
226QScriptValue ByteArrayClass::toScriptValue(QScriptEngine *eng, const QByteArray &ba)
227{
228 QScriptValue ctor = eng->globalObject().property("ByteArray");
229 ByteArrayClass *cls = qscriptvalue_cast<ByteArrayClass*>(ctor.data());
230 if (!cls)
231 return eng->newVariant(qVariantFromValue(ba));
232 return cls->newInstance(ba);
233}
234
235void ByteArrayClass::fromScriptValue(const QScriptValue &obj, QByteArray &ba)
236{
237 ba = qvariant_cast<QByteArray>(obj.data().toVariant());
238}
239
240//! [9]
241void ByteArrayClass::resize(QByteArray &ba, int newSize)
242{
243 int oldSize = ba.size();
244 ba.resize(newSize);
245 if (newSize > oldSize)
246 engine()->reportAdditionalMemoryCost(newSize - oldSize);
247}
248//! [9]
249
250
251
252ByteArrayClassPropertyIterator::ByteArrayClassPropertyIterator(const QScriptValue &object)
253 : QScriptClassPropertyIterator(object)
254{
255 toFront();
256}
257
258ByteArrayClassPropertyIterator::~ByteArrayClassPropertyIterator()
259{
260}
261
262//! [8]
263bool ByteArrayClassPropertyIterator::hasNext() const
264{
265 QByteArray *ba = qscriptvalue_cast<QByteArray*>(object().data());
266 return m_index < ba->size();
267}
268
269void ByteArrayClassPropertyIterator::next()
270{
271 m_last = m_index;
272 ++m_index;
273}
274
275bool ByteArrayClassPropertyIterator::hasPrevious() const
276{
277 return (m_index > 0);
278}
279
280void ByteArrayClassPropertyIterator::previous()
281{
282 --m_index;
283 m_last = m_index;
284}
285
286void ByteArrayClassPropertyIterator::toFront()
287{
288 m_index = 0;
289 m_last = -1;
290}
291
292void ByteArrayClassPropertyIterator::toBack()
293{
294 QByteArray *ba = qscriptvalue_cast<QByteArray*>(object().data());
295 m_index = ba->size();
296 m_last = -1;
297}
298
299QScriptString ByteArrayClassPropertyIterator::name() const
300{
301 return object().engine()->toStringHandle(QString::number(m_last));
302}
303
304uint ByteArrayClassPropertyIterator::id() const
305{
306 return m_last;
307}
308//! [8]
Note: See TracBrowser for help on using the repository browser.