1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qmetaobjectbuilder_p.h"
41 
42 #include "qobject_p.h"
43 #include "qmetaobject_p.h"
44 
45 #include <vector>
46 #include <stdlib.h>
47 
48 QT_BEGIN_NAMESPACE
49 
50 /*!
51     \class QMetaObjectBuilder
52     \inmodule QtCore
53     \internal
54     \brief The QMetaObjectBuilder class supports building QMetaObject objects at runtime.
55 
56 */
57 
58 /*!
59     \enum QMetaObjectBuilder::AddMember
60     This enum defines which members of QMetaObject should be copied by QMetaObjectBuilder::addMetaObject()
61 
62     \value ClassName Add the class name.
63     \value SuperClass Add the super class.
64     \value Methods Add methods that aren't signals or slots.
65     \value Signals Add signals.
66     \value Slots Add slots.
67     \value Constructors Add constructors.
68     \value Properties Add properties.
69     \value Enumerators Add enumerators.
70     \value ClassInfos Add items of class information.
71     \value RelatedMetaObjects Add related meta objects.
72     \value StaticMetacall Add the static metacall function.
73     \value PublicMethods Add public methods (ignored for signals).
74     \value ProtectedMethods Add protected methods (ignored for signals).
75     \value PrivateMethods All private methods (ignored for signals).
76     \value AllMembers Add all members.
77     \value AllPrimaryMembers Add everything except the class name, super class, and static metacall function.
78 */
79 
80 // copied from moc's generator.cpp
81 namespace QtPrivate {
isBuiltinType(const QByteArray & type)82 Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type)
83 {
84     int id = QMetaType::type(type);
85     if (!id && !type.isEmpty() && type != "void")
86         return false;
87     return (id < QMetaType::User);
88 }
89 } // namespace QtPrivate
90 
91 // copied from qmetaobject.cpp
priv(const uint * data)92 static inline Q_DECL_UNUSED const QMetaObjectPrivate *priv(const uint* data)
93 { return reinterpret_cast<const QMetaObjectPrivate*>(data); }
94 
95 class QMetaMethodBuilderPrivate
96 {
97 public:
QMetaMethodBuilderPrivate(QMetaMethod::MethodType _methodType,const QByteArray & _signature,const QByteArray & _returnType=QByteArray ("void"),QMetaMethod::Access _access=QMetaMethod::Public,int _revision=0)98     QMetaMethodBuilderPrivate
99             (QMetaMethod::MethodType _methodType,
100              const QByteArray& _signature,
101              const QByteArray& _returnType = QByteArray("void"),
102              QMetaMethod::Access _access = QMetaMethod::Public,
103              int _revision = 0)
104         : signature(QMetaObject::normalizedSignature(_signature.constData())),
105           returnType(QMetaObject::normalizedType(_returnType)),
106           attributes(((int)_access) | (((int)_methodType) << 2)),
107           revision(_revision)
108     {
109         Q_ASSERT((_methodType == QMetaMethod::Constructor) == returnType.isNull());
110     }
111 
112     QByteArray signature;
113     QByteArray returnType;
114     QList<QByteArray> parameterNames;
115     QByteArray tag;
116     int attributes;
117     int revision;
118 
methodType() const119     QMetaMethod::MethodType methodType() const
120     {
121         return (QMetaMethod::MethodType)((attributes & MethodTypeMask) >> 2);
122     }
123 
access() const124     QMetaMethod::Access access() const
125     {
126         return (QMetaMethod::Access)(attributes & AccessMask);
127     }
128 
setAccess(QMetaMethod::Access value)129     void setAccess(QMetaMethod::Access value)
130     {
131         attributes = ((attributes & ~AccessMask) | (int)value);
132     }
133 
parameterTypes() const134     QList<QByteArray> parameterTypes() const
135     {
136         return QMetaObjectPrivate::parameterTypeNamesFromSignature(signature);
137     }
138 
parameterCount() const139     int parameterCount() const
140     {
141         return parameterTypes().size();
142     }
143 
name() const144     QByteArray name() const
145     {
146         return signature.left(qMax(signature.indexOf('('), 0));
147     }
148 };
149 Q_DECLARE_TYPEINFO(QMetaMethodBuilderPrivate, Q_MOVABLE_TYPE);
150 
151 class QMetaPropertyBuilderPrivate
152 {
153 public:
QMetaPropertyBuilderPrivate(const QByteArray & _name,const QByteArray & _type,int notifierIdx=-1,int _revision=0)154     QMetaPropertyBuilderPrivate
155             (const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1,
156              int _revision = 0)
157         : name(_name),
158           type(QMetaObject::normalizedType(_type.constData())),
159           flags(Readable | Writable | Scriptable), notifySignal(-1),
160           revision(_revision)
161     {
162         if (notifierIdx >= 0) {
163             flags |= Notify;
164             notifySignal = notifierIdx;
165         }
166     }
167 
168     QByteArray name;
169     QByteArray type;
170     int flags;
171     int notifySignal;
172     int revision;
173 
flag(int f) const174     bool flag(int f) const
175     {
176         return ((flags & f) != 0);
177     }
178 
setFlag(int f,bool value)179     void setFlag(int f, bool value)
180     {
181         if (value)
182             flags |= f;
183         else
184             flags &= ~f;
185     }
186 };
187 Q_DECLARE_TYPEINFO(QMetaPropertyBuilderPrivate, Q_MOVABLE_TYPE);
188 
189 class QMetaEnumBuilderPrivate
190 {
191 public:
QMetaEnumBuilderPrivate(const QByteArray & _name)192     QMetaEnumBuilderPrivate(const QByteArray& _name)
193         : name(_name), enumName(_name), isFlag(false), isScoped(false)
194     {
195     }
196 
197     QByteArray name;
198     QByteArray enumName;
199     bool isFlag;
200     bool isScoped;
201     QList<QByteArray> keys;
202     QVector<int> values;
203 };
204 Q_DECLARE_TYPEINFO(QMetaEnumBuilderPrivate, Q_MOVABLE_TYPE);
205 
206 class QMetaObjectBuilderPrivate
207 {
208 public:
QMetaObjectBuilderPrivate()209     QMetaObjectBuilderPrivate()
210         : flags(0)
211     {
212         superClass = &QObject::staticMetaObject;
213         staticMetacallFunction = nullptr;
214     }
215 
216     bool hasRevisionedProperties() const;
217     bool hasRevisionedMethods() const;
218 
219     QByteArray className;
220     const QMetaObject *superClass;
221     QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction;
222     std::vector<QMetaMethodBuilderPrivate> methods;
223     std::vector<QMetaMethodBuilderPrivate> constructors;
224     std::vector<QMetaPropertyBuilderPrivate> properties;
225     QList<QByteArray> classInfoNames;
226     QList<QByteArray> classInfoValues;
227     std::vector<QMetaEnumBuilderPrivate> enumerators;
228     QList<const QMetaObject *> relatedMetaObjects;
229     int flags;
230 };
231 
hasRevisionedProperties() const232 bool QMetaObjectBuilderPrivate::hasRevisionedProperties() const
233 {
234     for (const auto &property : properties) {
235         if (property.revision)
236             return true;
237     }
238     return false;
239 }
240 
hasRevisionedMethods() const241 bool QMetaObjectBuilderPrivate::hasRevisionedMethods() const
242 {
243     for (const auto &method : methods) {
244         if (method.revision)
245             return true;
246     }
247     return false;
248 }
249 
250 /*!
251     Constructs a new QMetaObjectBuilder.
252 */
QMetaObjectBuilder()253 QMetaObjectBuilder::QMetaObjectBuilder()
254 {
255     d = new QMetaObjectBuilderPrivate();
256 }
257 
258 /*!
259     Constructs a new QMetaObjectBuilder which is a copy of the
260     meta object information in \a prototype.  Note: the super class
261     contents for \a prototype are not copied, only the immediate
262     class that is defined by \a prototype.
263 
264     The \a members parameter indicates which members of \a prototype
265     should be added.  The default is AllMembers.
266 
267     \sa addMetaObject()
268 */
QMetaObjectBuilder(const QMetaObject * prototype,QMetaObjectBuilder::AddMembers members)269 QMetaObjectBuilder::QMetaObjectBuilder
270     (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members)
271 {
272     d = new QMetaObjectBuilderPrivate();
273     addMetaObject(prototype, members);
274 }
275 
276 /*!
277     Destroys this meta object builder.
278 */
~QMetaObjectBuilder()279 QMetaObjectBuilder::~QMetaObjectBuilder()
280 {
281     delete d;
282 }
283 
284 /*!
285     Returns the name of the class being constructed by this
286     meta object builder.  The default value is an empty QByteArray.
287 
288     \sa setClassName(), superClass()
289 */
className() const290 QByteArray QMetaObjectBuilder::className() const
291 {
292     return d->className;
293 }
294 
295 /*!
296     Sets the \a name of the class being constructed by this
297     meta object builder.
298 
299     \sa className(), setSuperClass()
300 */
setClassName(const QByteArray & name)301 void QMetaObjectBuilder::setClassName(const QByteArray& name)
302 {
303     d->className = name;
304 }
305 
306 /*!
307     Returns the superclass meta object of the class being constructed
308     by this meta object builder.  The default value is the meta object
309     for QObject.
310 
311     \sa setSuperClass(), className()
312 */
superClass() const313 const QMetaObject *QMetaObjectBuilder::superClass() const
314 {
315     return d->superClass;
316 }
317 
318 /*!
319     Sets the superclass meta object of the class being constructed
320     by this meta object builder to \a meta.  The \a meta parameter
321     must not be null.
322 
323     \sa superClass(), setClassName()
324 */
setSuperClass(const QMetaObject * meta)325 void QMetaObjectBuilder::setSuperClass(const QMetaObject *meta)
326 {
327     Q_ASSERT(meta);
328     d->superClass = meta;
329 }
330 
331 /*!
332     Returns the flags of the class being constructed by this meta object
333     builder.
334 
335     \sa setFlags()
336 */
flags() const337 QMetaObjectBuilder::MetaObjectFlags QMetaObjectBuilder::flags() const
338 {
339     return (QMetaObjectBuilder::MetaObjectFlags)d->flags;
340 }
341 
342 /*!
343     Sets the \a flags of the class being constructed by this meta object
344     builder.
345 
346     \sa flags()
347 */
setFlags(MetaObjectFlags flags)348 void QMetaObjectBuilder::setFlags(MetaObjectFlags flags)
349 {
350     d->flags = flags;
351 }
352 
353 /*!
354     Returns the number of methods in this class, excluding the number
355     of methods in the base class.  These include signals and slots
356     as well as normal member functions.
357 
358     \sa addMethod(), method(), removeMethod(), indexOfMethod()
359 */
methodCount() const360 int QMetaObjectBuilder::methodCount() const
361 {
362     return int(d->methods.size());
363 }
364 
365 /*!
366     Returns the number of constructors in this class.
367 
368     \sa addConstructor(), constructor(), removeConstructor(), indexOfConstructor()
369 */
constructorCount() const370 int QMetaObjectBuilder::constructorCount() const
371 {
372     return int(d->constructors.size());
373 }
374 
375 /*!
376     Returns the number of properties in this class, excluding the number
377     of properties in the base class.
378 
379     \sa addProperty(), property(), removeProperty(), indexOfProperty()
380 */
propertyCount() const381 int QMetaObjectBuilder::propertyCount() const
382 {
383     return int(d->properties.size());
384 }
385 
386 /*!
387     Returns the number of enumerators in this class, excluding the
388     number of enumerators in the base class.
389 
390     \sa addEnumerator(), enumerator(), removeEnumerator()
391     \sa indexOfEnumerator()
392 */
enumeratorCount() const393 int QMetaObjectBuilder::enumeratorCount() const
394 {
395     return int(d->enumerators.size());
396 }
397 
398 /*!
399     Returns the number of items of class information in this class,
400     exclusing the number of items of class information in the base class.
401 
402     \sa addClassInfo(), classInfoName(), classInfoValue(), removeClassInfo()
403     \sa indexOfClassInfo()
404 */
classInfoCount() const405 int QMetaObjectBuilder::classInfoCount() const
406 {
407     return d->classInfoNames.size();
408 }
409 
410 /*!
411     Returns the number of related meta objects that are associated
412     with this class.
413 
414     Related meta objects are used when resolving the enumerated type
415     associated with a property, where the enumerated type is in a
416     different class from the property.
417 
418     \sa addRelatedMetaObject(), relatedMetaObject()
419     \sa removeRelatedMetaObject()
420 */
relatedMetaObjectCount() const421 int QMetaObjectBuilder::relatedMetaObjectCount() const
422 {
423     return d->relatedMetaObjects.size();
424 }
425 
426 /*!
427     Adds a new public method to this class with the specified \a signature.
428     Returns an object that can be used to adjust the other attributes
429     of the method.  The \a signature will be normalized before it is
430     added to the class.
431 
432     \sa method(), methodCount(), removeMethod(), indexOfMethod()
433 */
addMethod(const QByteArray & signature)434 QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray& signature)
435 {
436     int index = int(d->methods.size());
437     d->methods.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Method, signature));
438     return QMetaMethodBuilder(this, index);
439 }
440 
441 /*!
442     Adds a new public method to this class with the specified
443     \a signature and \a returnType.  Returns an object that can be
444     used to adjust the other attributes of the method.  The \a signature
445     and \a returnType will be normalized before they are added to
446     the class.
447 
448     \sa method(), methodCount(), removeMethod(), indexOfMethod()
449 */
addMethod(const QByteArray & signature,const QByteArray & returnType)450 QMetaMethodBuilder QMetaObjectBuilder::addMethod
451     (const QByteArray& signature, const QByteArray& returnType)
452 {
453     int index = int(d->methods.size());
454     d->methods.push_back(QMetaMethodBuilderPrivate
455         (QMetaMethod::Method, signature, returnType));
456     return QMetaMethodBuilder(this, index);
457 }
458 
459 /*!
460     Adds a new public method to this class that has the same information as
461     \a prototype.  This is used to clone the methods of an existing
462     QMetaObject.  Returns an object that can be used to adjust the
463     attributes of the method.
464 
465     This function will detect if \a prototype is an ordinary method,
466     signal, slot, or constructor and act accordingly.
467 
468     \sa method(), methodCount(), removeMethod(), indexOfMethod()
469 */
addMethod(const QMetaMethod & prototype)470 QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod& prototype)
471 {
472     QMetaMethodBuilder method;
473     if (prototype.methodType() == QMetaMethod::Method)
474         method = addMethod(prototype.methodSignature());
475     else if (prototype.methodType() == QMetaMethod::Signal)
476         method = addSignal(prototype.methodSignature());
477     else if (prototype.methodType() == QMetaMethod::Slot)
478         method = addSlot(prototype.methodSignature());
479     else if (prototype.methodType() == QMetaMethod::Constructor)
480         method = addConstructor(prototype.methodSignature());
481     method.setReturnType(prototype.typeName());
482     method.setParameterNames(prototype.parameterNames());
483     method.setTag(prototype.tag());
484     method.setAccess(prototype.access());
485     method.setAttributes(prototype.attributes());
486     method.setRevision(prototype.revision());
487     return method;
488 }
489 
490 /*!
491     Adds a new public slot to this class with the specified \a signature.
492     Returns an object that can be used to adjust the other attributes
493     of the slot.  The \a signature will be normalized before it is
494     added to the class.
495 
496     \sa addMethod(), addSignal(), indexOfSlot()
497 */
addSlot(const QByteArray & signature)498 QMetaMethodBuilder QMetaObjectBuilder::addSlot(const QByteArray& signature)
499 {
500     int index = int(d->methods.size());
501     d->methods.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Slot, signature));
502     return QMetaMethodBuilder(this, index);
503 }
504 
505 /*!
506     Adds a new signal to this class with the specified \a signature.
507     Returns an object that can be used to adjust the other attributes
508     of the signal.  The \a signature will be normalized before it is
509     added to the class.
510 
511     \sa addMethod(), addSlot(), indexOfSignal()
512 */
addSignal(const QByteArray & signature)513 QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature)
514 {
515     int index = int(d->methods.size());
516     d->methods.push_back(QMetaMethodBuilderPrivate
517         (QMetaMethod::Signal, signature, QByteArray("void"), QMetaMethod::Public));
518     return QMetaMethodBuilder(this, index);
519 }
520 
521 /*!
522     Adds a new constructor to this class with the specified \a signature.
523     Returns an object that can be used to adjust the other attributes
524     of the constructor.  The \a signature will be normalized before it is
525     added to the class.
526 
527     \sa constructor(), constructorCount(), removeConstructor()
528     \sa indexOfConstructor()
529 */
addConstructor(const QByteArray & signature)530 QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signature)
531 {
532     int index = int(d->constructors.size());
533     d->constructors.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature,
534                                                         /*returnType=*/QByteArray()));
535     return QMetaMethodBuilder(this, -(index + 1));
536 }
537 
538 /*!
539     Adds a new constructor to this class that has the same information as
540     \a prototype.  This is used to clone the constructors of an existing
541     QMetaObject.  Returns an object that can be used to adjust the
542     attributes of the constructor.
543 
544     This function requires that \a prototype be a constructor.
545 
546     \sa constructor(), constructorCount(), removeConstructor()
547     \sa indexOfConstructor()
548 */
addConstructor(const QMetaMethod & prototype)549 QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototype)
550 {
551     Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor);
552     QMetaMethodBuilder ctor = addConstructor(prototype.methodSignature());
553     ctor.setReturnType(prototype.typeName());
554     ctor.setParameterNames(prototype.parameterNames());
555     ctor.setTag(prototype.tag());
556     ctor.setAccess(prototype.access());
557     ctor.setAttributes(prototype.attributes());
558     return ctor;
559 }
560 
561 /*!
562     Adds a new readable/writable property to this class with the
563     specified \a name and \a type.  Returns an object that can be used
564     to adjust the other attributes of the property.  The \a type will
565     be normalized before it is added to the class. \a notifierId will
566     be registered as the property's \e notify signal.
567 
568     \sa property(), propertyCount(), removeProperty(), indexOfProperty()
569 */
addProperty(const QByteArray & name,const QByteArray & type,int notifierId)570 QMetaPropertyBuilder QMetaObjectBuilder::addProperty
571     (const QByteArray& name, const QByteArray& type, int notifierId)
572 {
573     int index = int(d->properties.size());
574     d->properties.push_back(QMetaPropertyBuilderPrivate(name, type, notifierId));
575     return QMetaPropertyBuilder(this, index);
576 }
577 
578 #if QT_DEPRECATED_SINCE(5, 15)
579 QT_WARNING_PUSH
580 QT_WARNING_DISABLE_DEPRECATED
deprecatedIsEditable(const QMetaProperty & prototype)581 static bool deprecatedIsEditable(const QMetaProperty &prototype)
582 {
583     return prototype.isEditable();
584 }
585 QT_WARNING_POP
586 #endif
587 
588 /*!
589     Adds a new property to this class that has the same information as
590     \a prototype.  This is used to clone the properties of an existing
591     QMetaObject.  Returns an object that can be used to adjust the
592     attributes of the property.
593 
594     \sa property(), propertyCount(), removeProperty(), indexOfProperty()
595 */
addProperty(const QMetaProperty & prototype)596 QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& prototype)
597 {
598     QMetaPropertyBuilder property = addProperty(prototype.name(), prototype.typeName());
599     property.setReadable(prototype.isReadable());
600     property.setWritable(prototype.isWritable());
601     property.setResettable(prototype.isResettable());
602     property.setDesignable(prototype.isDesignable());
603     property.setScriptable(prototype.isScriptable());
604     property.setStored(prototype.isStored());
605     property.setEditable(deprecatedIsEditable(prototype));
606     property.setUser(prototype.isUser());
607     property.setStdCppSet(prototype.hasStdCppSet());
608     property.setEnumOrFlag(prototype.isEnumType());
609     property.setConstant(prototype.isConstant());
610     property.setFinal(prototype.isFinal());
611     property.setRevision(prototype.revision());
612     if (prototype.hasNotifySignal()) {
613         // Find an existing method for the notify signal, or add a new one.
614         QMetaMethod method = prototype.notifySignal();
615         int index = indexOfMethod(method.methodSignature());
616         if (index == -1)
617             index = addMethod(method).index();
618         d->properties[property._index].notifySignal = index;
619         d->properties[property._index].setFlag(Notify, true);
620     }
621     return property;
622 }
623 
624 /*!
625     Adds a new enumerator to this class with the specified
626     \a name.  Returns an object that can be used to adjust
627     the other attributes of the enumerator.
628 
629     \sa enumerator(), enumeratorCount(), removeEnumerator()
630     \sa indexOfEnumerator()
631 */
addEnumerator(const QByteArray & name)632 QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray& name)
633 {
634     int index = int(d->enumerators.size());
635     d->enumerators.push_back(QMetaEnumBuilderPrivate(name));
636     return QMetaEnumBuilder(this, index);
637 }
638 
639 /*!
640     Adds a new enumerator to this class that has the same information as
641     \a prototype.  This is used to clone the enumerators of an existing
642     QMetaObject.  Returns an object that can be used to adjust the
643     attributes of the enumerator.
644 
645     \sa enumerator(), enumeratorCount(), removeEnumerator()
646     \sa indexOfEnumerator()
647 */
addEnumerator(const QMetaEnum & prototype)648 QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum& prototype)
649 {
650     QMetaEnumBuilder en = addEnumerator(prototype.name());
651     en.setEnumName(prototype.enumName());
652     en.setIsFlag(prototype.isFlag());
653     en.setIsScoped(prototype.isScoped());
654     int count = prototype.keyCount();
655     for (int index = 0; index < count; ++index)
656         en.addKey(prototype.key(index), prototype.value(index));
657     return en;
658 }
659 
660 /*!
661     Adds \a name and \a value as an item of class information to this class.
662     Returns the index of the new item of class information.
663 
664     \sa classInfoCount(), classInfoName(), classInfoValue(), removeClassInfo()
665     \sa indexOfClassInfo()
666 */
addClassInfo(const QByteArray & name,const QByteArray & value)667 int QMetaObjectBuilder::addClassInfo(const QByteArray& name, const QByteArray& value)
668 {
669     int index = d->classInfoNames.size();
670     d->classInfoNames += name;
671     d->classInfoValues += value;
672     return index;
673 }
674 
675 /*!
676     Adds \a meta to this class as a related meta object.  Returns
677     the index of the new related meta object entry.
678 
679     Related meta objects are used when resolving the enumerated type
680     associated with a property, where the enumerated type is in a
681     different class from the property.
682 
683     \sa relatedMetaObjectCount(), relatedMetaObject()
684     \sa removeRelatedMetaObject()
685 */
addRelatedMetaObject(const QMetaObject * meta)686 int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObject *meta)
687 {
688     Q_ASSERT(meta);
689     int index = d->relatedMetaObjects.size();
690     d->relatedMetaObjects.append(meta);
691     return index;
692 }
693 
694 /*!
695     Adds the contents of \a prototype to this meta object builder.
696     This function is useful for cloning the contents of an existing QMetaObject.
697 
698     The \a members parameter indicates which members of \a prototype
699     should be added.  The default is AllMembers.
700 */
addMetaObject(const QMetaObject * prototype,QMetaObjectBuilder::AddMembers members)701 void QMetaObjectBuilder::addMetaObject
702         (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members)
703 {
704     Q_ASSERT(prototype);
705     int index;
706 
707     if ((members & ClassName) != 0)
708         d->className = prototype->className();
709 
710     if ((members & SuperClass) != 0)
711         d->superClass = prototype->superClass();
712 
713     if ((members & (Methods | Signals | Slots)) != 0) {
714         for (index = prototype->methodOffset(); index < prototype->methodCount(); ++index) {
715             QMetaMethod method = prototype->method(index);
716             if (method.methodType() != QMetaMethod::Signal) {
717                 if (method.access() == QMetaMethod::Public && (members & PublicMethods) == 0)
718                     continue;
719                 if (method.access() == QMetaMethod::Private && (members & PrivateMethods) == 0)
720                     continue;
721                 if (method.access() == QMetaMethod::Protected && (members & ProtectedMethods) == 0)
722                     continue;
723             }
724             if (method.methodType() == QMetaMethod::Method && (members & Methods) != 0) {
725                 addMethod(method);
726             } else if (method.methodType() == QMetaMethod::Signal &&
727                        (members & Signals) != 0) {
728                 addMethod(method);
729             } else if (method.methodType() == QMetaMethod::Slot &&
730                        (members & Slots) != 0) {
731                 addMethod(method);
732             }
733         }
734     }
735 
736     if ((members & Constructors) != 0) {
737         for (index = 0; index < prototype->constructorCount(); ++index)
738             addConstructor(prototype->constructor(index));
739     }
740 
741     if ((members & Properties) != 0) {
742         for (index = prototype->propertyOffset(); index < prototype->propertyCount(); ++index)
743             addProperty(prototype->property(index));
744     }
745 
746     if ((members & Enumerators) != 0) {
747         for (index = prototype->enumeratorOffset(); index < prototype->enumeratorCount(); ++index)
748             addEnumerator(prototype->enumerator(index));
749     }
750 
751     if ((members & ClassInfos) != 0) {
752         for (index = prototype->classInfoOffset(); index < prototype->classInfoCount(); ++index) {
753             QMetaClassInfo ci = prototype->classInfo(index);
754             addClassInfo(ci.name(), ci.value());
755         }
756     }
757 
758     if ((members & RelatedMetaObjects) != 0) {
759         Q_ASSERT(priv(prototype->d.data)->revision >= 2);
760         const auto *objects = prototype->d.relatedMetaObjects;
761         if (objects) {
762             while (*objects != nullptr) {
763                 addRelatedMetaObject(*objects);
764                 ++objects;
765             }
766         }
767     }
768 
769     if ((members & StaticMetacall) != 0) {
770         Q_ASSERT(priv(prototype->d.data)->revision >= 6);
771         if (prototype->d.static_metacall)
772             setStaticMetacallFunction(prototype->d.static_metacall);
773     }
774 }
775 
776 /*!
777     Returns the method at \a index in this class.
778 
779     \sa methodCount(), addMethod(), removeMethod(), indexOfMethod()
780 */
method(int index) const781 QMetaMethodBuilder QMetaObjectBuilder::method(int index) const
782 {
783     if (uint(index) < d->methods.size())
784         return QMetaMethodBuilder(this, index);
785     else
786         return QMetaMethodBuilder();
787 }
788 
789 /*!
790     Returns the constructor at \a index in this class.
791 
792     \sa methodCount(), addMethod(), removeMethod(), indexOfConstructor()
793 */
constructor(int index) const794 QMetaMethodBuilder QMetaObjectBuilder::constructor(int index) const
795 {
796     if (uint(index) < d->constructors.size())
797         return QMetaMethodBuilder(this, -(index + 1));
798     else
799         return QMetaMethodBuilder();
800 }
801 
802 /*!
803     Returns the property at \a index in this class.
804 
805     \sa methodCount(), addMethod(), removeMethod(), indexOfProperty()
806 */
property(int index) const807 QMetaPropertyBuilder QMetaObjectBuilder::property(int index) const
808 {
809     if (uint(index) < d->properties.size())
810         return QMetaPropertyBuilder(this, index);
811     else
812         return QMetaPropertyBuilder();
813 }
814 
815 /*!
816     Returns the enumerator at \a index in this class.
817 
818     \sa enumeratorCount(), addEnumerator(), removeEnumerator()
819     \sa indexOfEnumerator()
820 */
enumerator(int index) const821 QMetaEnumBuilder QMetaObjectBuilder::enumerator(int index) const
822 {
823     if (uint(index) < d->enumerators.size())
824         return QMetaEnumBuilder(this, index);
825     else
826         return QMetaEnumBuilder();
827 }
828 
829 /*!
830     Returns the related meta object at \a index in this class.
831 
832     Related meta objects are used when resolving the enumerated type
833     associated with a property, where the enumerated type is in a
834     different class from the property.
835 
836     \sa relatedMetaObjectCount(), addRelatedMetaObject()
837     \sa removeRelatedMetaObject()
838 */
relatedMetaObject(int index) const839 const QMetaObject *QMetaObjectBuilder::relatedMetaObject(int index) const
840 {
841     if (index >= 0 && index < d->relatedMetaObjects.size())
842         return d->relatedMetaObjects[index];
843     else
844         return nullptr;
845 }
846 
847 /*!
848     Returns the name of the item of class information at \a index
849     in this class.
850 
851     \sa classInfoCount(), addClassInfo(), classInfoValue(), removeClassInfo()
852     \sa indexOfClassInfo()
853 */
classInfoName(int index) const854 QByteArray QMetaObjectBuilder::classInfoName(int index) const
855 {
856     if (index >= 0 && index < d->classInfoNames.size())
857         return d->classInfoNames[index];
858     else
859         return QByteArray();
860 }
861 
862 /*!
863     Returns the value of the item of class information at \a index
864     in this class.
865 
866     \sa classInfoCount(), addClassInfo(), classInfoName(), removeClassInfo()
867     \sa indexOfClassInfo()
868 */
classInfoValue(int index) const869 QByteArray QMetaObjectBuilder::classInfoValue(int index) const
870 {
871     if (index >= 0 && index < d->classInfoValues.size())
872         return d->classInfoValues[index];
873     else
874         return QByteArray();
875 }
876 
877 /*!
878     Removes the method at \a index from this class.  The indices of
879     all following methods will be adjusted downwards by 1.  If the
880     method is registered as a notify signal on a property, then the
881     notify signal will be removed from the property.
882 
883     \sa methodCount(), addMethod(), method(), indexOfMethod()
884 */
removeMethod(int index)885 void QMetaObjectBuilder::removeMethod(int index)
886 {
887     if (uint(index) < d->methods.size()) {
888         d->methods.erase(d->methods.begin() + index);
889         for (auto &property : d->properties) {
890             // Adjust the indices of property notify signal references.
891             if (property.notifySignal == index) {
892                 property.notifySignal = -1;
893                 property.setFlag(Notify, false);
894             } else if (property.notifySignal > index)
895                 property.notifySignal--;
896         }
897     }
898 }
899 
900 /*!
901     Removes the constructor at \a index from this class.  The indices of
902     all following constructors will be adjusted downwards by 1.
903 
904     \sa constructorCount(), addConstructor(), constructor()
905     \sa indexOfConstructor()
906 */
removeConstructor(int index)907 void QMetaObjectBuilder::removeConstructor(int index)
908 {
909     if (uint(index) < d->constructors.size())
910         d->constructors.erase(d->constructors.begin() + index);
911 }
912 
913 /*!
914     Removes the property at \a index from this class.  The indices of
915     all following properties will be adjusted downwards by 1.
916 
917     \sa propertyCount(), addProperty(), property(), indexOfProperty()
918 */
removeProperty(int index)919 void QMetaObjectBuilder::removeProperty(int index)
920 {
921     if (uint(index) < d->properties.size())
922         d->properties.erase(d->properties.begin() + index);
923 }
924 
925 /*!
926     Removes the enumerator at \a index from this class.  The indices of
927     all following enumerators will be adjusted downwards by 1.
928 
929     \sa enumertorCount(), addEnumerator(), enumerator()
930     \sa indexOfEnumerator()
931 */
removeEnumerator(int index)932 void QMetaObjectBuilder::removeEnumerator(int index)
933 {
934     if (uint(index) < d->enumerators.size())
935         d->enumerators.erase(d->enumerators.begin() + index);
936 }
937 
938 /*!
939     Removes the item of class information at \a index from this class.
940     The indices of all following items will be adjusted downwards by 1.
941 
942     \sa classInfoCount(), addClassInfo(), classInfoName(), classInfoValue()
943     \sa indexOfClassInfo()
944 */
removeClassInfo(int index)945 void QMetaObjectBuilder::removeClassInfo(int index)
946 {
947     if (index >= 0 && index < d->classInfoNames.size()) {
948         d->classInfoNames.removeAt(index);
949         d->classInfoValues.removeAt(index);
950     }
951 }
952 
953 /*!
954     Removes the related meta object at \a index from this class.
955     The indices of all following related meta objects will be adjusted
956     downwards by 1.
957 
958     Related meta objects are used when resolving the enumerated type
959     associated with a property, where the enumerated type is in a
960     different class from the property.
961 
962     \sa relatedMetaObjectCount(), addRelatedMetaObject()
963     \sa relatedMetaObject()
964 */
removeRelatedMetaObject(int index)965 void QMetaObjectBuilder::removeRelatedMetaObject(int index)
966 {
967     if (index >= 0 && index < d->relatedMetaObjects.size())
968         d->relatedMetaObjects.removeAt(index);
969 }
970 
971 /*!
972     Finds a method with the specified \a signature and returns its index;
973     otherwise returns -1.  The \a signature will be normalized by this method.
974 
975     \sa method(), methodCount(), addMethod(), removeMethod()
976 */
indexOfMethod(const QByteArray & signature)977 int QMetaObjectBuilder::indexOfMethod(const QByteArray& signature)
978 {
979     QByteArray sig = QMetaObject::normalizedSignature(signature);
980     for (const auto &method : d->methods) {
981         if (sig == method.signature)
982             return int(&method - &d->methods.front());
983     }
984     return -1;
985 }
986 
987 /*!
988     Finds a signal with the specified \a signature and returns its index;
989     otherwise returns -1.  The \a signature will be normalized by this method.
990 
991     \sa indexOfMethod(), indexOfSlot()
992 */
indexOfSignal(const QByteArray & signature)993 int QMetaObjectBuilder::indexOfSignal(const QByteArray& signature)
994 {
995     QByteArray sig = QMetaObject::normalizedSignature(signature);
996     for (const auto &method : d->methods) {
997         if (method.methodType() == QMetaMethod::Signal && sig == method.signature)
998             return int(&method - &d->methods.front());
999     }
1000     return -1;
1001 }
1002 
1003 /*!
1004     Finds a slot with the specified \a signature and returns its index;
1005     otherwise returns -1.  The \a signature will be normalized by this method.
1006 
1007     \sa indexOfMethod(), indexOfSignal()
1008 */
indexOfSlot(const QByteArray & signature)1009 int QMetaObjectBuilder::indexOfSlot(const QByteArray& signature)
1010 {
1011     QByteArray sig = QMetaObject::normalizedSignature(signature);
1012     for (const auto &method : d->methods) {
1013         if (method.methodType() == QMetaMethod::Slot && sig == method.signature)
1014             return int(&method - &d->methods.front());
1015     }
1016     return -1;
1017 }
1018 
1019 /*!
1020     Finds a constructor with the specified \a signature and returns its index;
1021     otherwise returns -1.  The \a signature will be normalized by this method.
1022 
1023     \sa constructor(), constructorCount(), addConstructor(), removeConstructor()
1024 */
indexOfConstructor(const QByteArray & signature)1025 int QMetaObjectBuilder::indexOfConstructor(const QByteArray& signature)
1026 {
1027     QByteArray sig = QMetaObject::normalizedSignature(signature);
1028     for (const auto &constructor : d->constructors) {
1029         if (sig == constructor.signature)
1030             return int(&constructor - &d->constructors.front());
1031     }
1032     return -1;
1033 }
1034 
1035 /*!
1036     Finds a property with the specified \a name and returns its index;
1037     otherwise returns -1.
1038 
1039     \sa property(), propertyCount(), addProperty(), removeProperty()
1040 */
indexOfProperty(const QByteArray & name)1041 int QMetaObjectBuilder::indexOfProperty(const QByteArray& name)
1042 {
1043     for (const auto &property : d->properties) {
1044         if (name == property.name)
1045             return int(&property - &d->properties.front());
1046     }
1047     return -1;
1048 }
1049 
1050 /*!
1051     Finds an enumerator with the specified \a name and returns its index;
1052     otherwise returns -1.
1053 
1054     \sa enumertor(), enumeratorCount(), addEnumerator(), removeEnumerator()
1055 */
indexOfEnumerator(const QByteArray & name)1056 int QMetaObjectBuilder::indexOfEnumerator(const QByteArray& name)
1057 {
1058     for (const auto &enumerator : d->enumerators) {
1059         if (name == enumerator.name)
1060             return int(&enumerator - &d->enumerators.front());
1061     }
1062     return -1;
1063 }
1064 
1065 /*!
1066     Finds an item of class information with the specified \a name and
1067     returns its index; otherwise returns -1.
1068 
1069     \sa classInfoName(), classInfoValue(), classInfoCount(), addClassInfo()
1070     \sa removeClassInfo()
1071 */
indexOfClassInfo(const QByteArray & name)1072 int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name)
1073 {
1074     for (int index = 0; index < d->classInfoNames.size(); ++index) {
1075         if (name == d->classInfoNames[index])
1076             return index;
1077     }
1078     return -1;
1079 }
1080 
1081 // Align on a specific type boundary.
1082 #define ALIGN(size,type)    \
1083     (size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1)
1084 
1085 /*!
1086     \class QMetaStringTable
1087     \inmodule QtCore
1088     \internal
1089     \brief The QMetaStringTable class can generate a meta-object string table at runtime.
1090 */
1091 
QMetaStringTable(const QByteArray & className)1092 QMetaStringTable::QMetaStringTable(const QByteArray &className)
1093     : m_index(0)
1094     , m_className(className)
1095 {
1096     const int index = enter(m_className);
1097     Q_ASSERT(index == 0);
1098     Q_UNUSED(index);
1099 }
1100 
1101 // Enters the given value into the string table (if it hasn't already been
1102 // entered). Returns the index of the string.
enter(const QByteArray & value)1103 int QMetaStringTable::enter(const QByteArray &value)
1104 {
1105     Entries::iterator it = m_entries.find(value);
1106     if (it != m_entries.end())
1107         return it.value();
1108     int pos = m_index;
1109     m_entries.insert(value, pos);
1110     ++m_index;
1111     return pos;
1112 }
1113 
preferredAlignment()1114 int QMetaStringTable::preferredAlignment()
1115 {
1116     return Q_ALIGNOF(QByteArrayData);
1117 }
1118 
1119 // Returns the size (in bytes) required for serializing this string table.
blobSize() const1120 int QMetaStringTable::blobSize() const
1121 {
1122     int size = m_entries.size() * sizeof(QByteArrayData);
1123     Entries::const_iterator it;
1124     for (it = m_entries.constBegin(); it != m_entries.constEnd(); ++it)
1125         size += it.key().size() + 1;
1126     return size;
1127 }
1128 
writeString(char * out,int i,const QByteArray & str,const int offsetOfStringdataMember,int & stringdataOffset)1129 static void writeString(char *out, int i, const QByteArray &str,
1130                         const int offsetOfStringdataMember, int &stringdataOffset)
1131 {
1132     int size = str.size();
1133     qptrdiff offset = offsetOfStringdataMember + stringdataOffset
1134             - i * sizeof(QByteArrayData);
1135     const QByteArrayData data =
1136         Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset);
1137 
1138     memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData));
1139 
1140     memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size);
1141     out[offsetOfStringdataMember + stringdataOffset + size] = '\0';
1142 
1143     stringdataOffset += size + 1;
1144 }
1145 
1146 // Writes strings to string data struct.
1147 // The struct consists of an array of QByteArrayData, followed by a char array
1148 // containing the actual strings. This format must match the one produced by
1149 // moc (see generator.cpp).
writeBlob(char * out) const1150 void QMetaStringTable::writeBlob(char *out) const
1151 {
1152     Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment()-1)));
1153 
1154     int offsetOfStringdataMember = m_entries.size() * sizeof(QByteArrayData);
1155     int stringdataOffset = 0;
1156 
1157     // qt_metacast expects the first string in the string table to be the class name.
1158     writeString(out, /*index*/0, m_className, offsetOfStringdataMember, stringdataOffset);
1159 
1160     for (Entries::ConstIterator it = m_entries.constBegin(), end = m_entries.constEnd();
1161          it != end; ++it) {
1162         const int i = it.value();
1163         if (i == 0)
1164             continue;
1165         const QByteArray &str = it.key();
1166 
1167         writeString(out, i, str, offsetOfStringdataMember, stringdataOffset);
1168     }
1169 }
1170 
1171 // Returns the sum of all parameters (including return type) for the given
1172 // \a methods. This is needed for calculating the size of the methods'
1173 // parameter type/name meta-data.
aggregateParameterCount(const std::vector<QMetaMethodBuilderPrivate> & methods)1174 static int aggregateParameterCount(const std::vector<QMetaMethodBuilderPrivate> &methods)
1175 {
1176     int sum = 0;
1177     for (const auto &method : methods)
1178         sum += method.parameterCount() + 1; // +1 for return type
1179     return sum;
1180 }
1181 
1182 // Build a QMetaObject in "buf" based on the information in "d".
1183 // If "buf" is null, then return the number of bytes needed to
1184 // build the QMetaObject.  Returns -1 if the metaobject if
1185 // relocatable is set, but the metaobject contains relatedMetaObjects.
buildMetaObject(QMetaObjectBuilderPrivate * d,char * buf,int expectedSize,bool relocatable)1186 static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
1187                            int expectedSize, bool relocatable)
1188 {
1189     Q_UNUSED(expectedSize); // Avoid warning in release mode
1190     int size = 0;
1191     int dataIndex;
1192     int paramsIndex;
1193     int enumIndex;
1194     int index;
1195     bool hasRevisionedMethods = d->hasRevisionedMethods();
1196     bool hasRevisionedProperties = d->hasRevisionedProperties();
1197     bool hasNotifySignals = false;
1198 
1199     if (relocatable &&
1200         (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction))
1201         return -1;
1202 
1203     // Create the main QMetaObject structure at the start of the buffer.
1204     QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf);
1205     size += sizeof(QMetaObject);
1206     ALIGN(size, int);
1207     if (buf) {
1208         if (!relocatable) meta->d.superdata = d->superClass;
1209         meta->d.relatedMetaObjects = nullptr;
1210         meta->d.extradata = nullptr;
1211         meta->d.static_metacall = d->staticMetacallFunction;
1212     }
1213 
1214     // Populate the QMetaObjectPrivate structure.
1215     QMetaObjectPrivate *pmeta
1216         = reinterpret_cast<QMetaObjectPrivate *>(buf + size);
1217     int pmetaSize = size;
1218     dataIndex = MetaObjectPrivateFieldCount;
1219     for (const auto &property : d->properties) {
1220         if (property.notifySignal != -1) {
1221             hasNotifySignals = true;
1222             break;
1223         }
1224     }
1225     int methodParametersDataSize =
1226             ((aggregateParameterCount(d->methods)
1227              + aggregateParameterCount(d->constructors)) * 2) // types and parameter names
1228             - int(d->methods.size())       // return "parameters" don't have names
1229             - int(d->constructors.size()); // "this" parameters don't have names
1230     if (buf) {
1231         Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "QMetaObjectBuilder should generate the same version as moc");
1232         pmeta->revision = QMetaObjectPrivate::OutputRevision;
1233         pmeta->flags = d->flags;
1234         pmeta->className = 0;   // Class name is always the first string.
1235         //pmeta->signalCount is handled in the "output method loop" as an optimization.
1236 
1237         pmeta->classInfoCount = d->classInfoNames.size();
1238         pmeta->classInfoData = dataIndex;
1239         dataIndex += 2 * d->classInfoNames.size();
1240 
1241         pmeta->methodCount = int(d->methods.size());
1242         pmeta->methodData = dataIndex;
1243         dataIndex += 5 * int(d->methods.size());
1244         if (hasRevisionedMethods)
1245             dataIndex += int(d->methods.size());
1246         paramsIndex = dataIndex;
1247         dataIndex += methodParametersDataSize;
1248 
1249         pmeta->propertyCount = int(d->properties.size());
1250         pmeta->propertyData = dataIndex;
1251         dataIndex += 3 * int(d->properties.size());
1252         if (hasNotifySignals)
1253             dataIndex += int(d->properties.size());
1254         if (hasRevisionedProperties)
1255             dataIndex += int(d->properties.size());
1256 
1257         pmeta->enumeratorCount = int(d->enumerators.size());
1258         pmeta->enumeratorData = dataIndex;
1259         dataIndex += 5 * int(d->enumerators.size());
1260 
1261         pmeta->constructorCount = int(d->constructors.size());
1262         pmeta->constructorData = dataIndex;
1263         dataIndex += 5 * int(d->constructors.size());
1264     } else {
1265         dataIndex += 2 * int(d->classInfoNames.size());
1266         dataIndex += 5 * int(d->methods.size());
1267         if (hasRevisionedMethods)
1268             dataIndex += int(d->methods.size());
1269         paramsIndex = dataIndex;
1270         dataIndex += methodParametersDataSize;
1271         dataIndex += 3 * int(d->properties.size());
1272         if (hasNotifySignals)
1273             dataIndex += int(d->properties.size());
1274         if (hasRevisionedProperties)
1275             dataIndex += int(d->properties.size());
1276         dataIndex += 5 * int(d->enumerators.size());
1277         dataIndex += 5 * int(d->constructors.size());
1278     }
1279 
1280     // Allocate space for the enumerator key names and values.
1281     enumIndex = dataIndex;
1282     for (const auto &enumerator : d->enumerators)
1283         dataIndex += 2 * enumerator.keys.size();
1284 
1285     // Zero terminator at the end of the data offset table.
1286     ++dataIndex;
1287 
1288     // Find the start of the data and string tables.
1289     int *data = reinterpret_cast<int *>(pmeta);
1290     size += dataIndex * sizeof(int);
1291     ALIGN(size, void *);
1292     char *str = reinterpret_cast<char *>(buf + size);
1293     if (buf) {
1294         if (relocatable) {
1295             meta->d.stringdata = reinterpret_cast<const QByteArrayData *>((quintptr)size);
1296             meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
1297         } else {
1298             meta->d.stringdata = reinterpret_cast<const QByteArrayData *>(str);
1299             meta->d.data = reinterpret_cast<uint *>(data);
1300         }
1301     }
1302 
1303     // Reset the current data position to just past the QMetaObjectPrivate.
1304     dataIndex = MetaObjectPrivateFieldCount;
1305 
1306     QMetaStringTable strings(d->className);
1307 
1308     // Output the class infos,
1309     Q_ASSERT(!buf || dataIndex == pmeta->classInfoData);
1310     for (index = 0; index < d->classInfoNames.size(); ++index) {
1311         int name = strings.enter(d->classInfoNames[index]);
1312         int value = strings.enter(d->classInfoValues[index]);
1313         if (buf) {
1314             data[dataIndex] = name;
1315             data[dataIndex + 1] = value;
1316         }
1317         dataIndex += 2;
1318     }
1319 
1320     // Output the methods in the class.
1321     Q_ASSERT(!buf || dataIndex == pmeta->methodData);
1322     for (const auto &method : d->methods) {
1323         int name = strings.enter(method.name());
1324         int argc = method.parameterCount();
1325         int tag = strings.enter(method.tag);
1326         int attrs = method.attributes;
1327         if (buf) {
1328             data[dataIndex]     = name;
1329             data[dataIndex + 1] = argc;
1330             data[dataIndex + 2] = paramsIndex;
1331             data[dataIndex + 3] = tag;
1332             data[dataIndex + 4] = attrs;
1333             if (method.methodType() == QMetaMethod::Signal)
1334                 pmeta->signalCount++;
1335         }
1336         dataIndex += 5;
1337         paramsIndex += 1 + argc * 2;
1338     }
1339     if (hasRevisionedMethods) {
1340         for (const auto &method : d->methods) {
1341             if (buf)
1342                 data[dataIndex] = method.revision;
1343             ++dataIndex;
1344         }
1345     }
1346 
1347     // Output the method parameters in the class.
1348     Q_ASSERT(!buf || dataIndex == pmeta->methodData + int(d->methods.size()) * 5
1349              + (hasRevisionedMethods ? int(d->methods.size()) : 0));
1350     for (int x = 0; x < 2; ++x) {
1351         const std::vector<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors;
1352         for (const auto &method : methods) {
1353             const QList<QByteArray> paramTypeNames = method.parameterTypes();
1354             int paramCount = paramTypeNames.size();
1355             for (int i = -1; i < paramCount; ++i) {
1356                 const QByteArray &typeName = (i < 0) ? method.returnType : paramTypeNames.at(i);
1357                 int typeInfo;
1358                 if (QtPrivate::isBuiltinType(typeName))
1359                     typeInfo = QMetaType::type(typeName);
1360                 else
1361                     typeInfo = IsUnresolvedType | strings.enter(typeName);
1362                 if (buf)
1363                     data[dataIndex] = typeInfo;
1364                 ++dataIndex;
1365             }
1366 
1367             QList<QByteArray> paramNames = method.parameterNames;
1368             while (paramNames.size() < paramCount)
1369                 paramNames.append(QByteArray());
1370             for (int i = 0; i < paramCount; ++i) {
1371                 int stringIndex = strings.enter(paramNames.at(i));
1372                 if (buf)
1373                     data[dataIndex] = stringIndex;
1374                 ++dataIndex;
1375             }
1376         }
1377     }
1378 
1379     // Output the properties in the class.
1380     Q_ASSERT(!buf || dataIndex == pmeta->propertyData);
1381     for (const auto &prop : d->properties) {
1382         int name = strings.enter(prop.name);
1383 
1384         int typeInfo;
1385         if (QtPrivate::isBuiltinType(prop.type))
1386             typeInfo = QMetaType::type(prop.type);
1387         else
1388             typeInfo = IsUnresolvedType | strings.enter(prop.type);
1389 
1390         int flags = prop.flags;
1391 
1392         if (!QtPrivate::isBuiltinType(prop.type))
1393             flags |= EnumOrFlag;
1394 
1395         if (buf) {
1396             data[dataIndex]     = name;
1397             data[dataIndex + 1] = typeInfo;
1398             data[dataIndex + 2] = flags;
1399         }
1400         dataIndex += 3;
1401     }
1402     if (hasNotifySignals) {
1403         for (const auto &prop : d->properties) {
1404             if (buf) {
1405                 if (prop.notifySignal != -1)
1406                     data[dataIndex] = prop.notifySignal;
1407                 else
1408                     data[dataIndex] = 0;
1409             }
1410             ++dataIndex;
1411         }
1412     }
1413     if (hasRevisionedProperties) {
1414         for (const auto &prop : d->properties) {
1415             if (buf)
1416                 data[dataIndex] = prop.revision;
1417             ++dataIndex;
1418         }
1419     }
1420 
1421     // Output the enumerators in the class.
1422     Q_ASSERT(!buf || dataIndex == pmeta->enumeratorData);
1423     for (const auto &enumerator : d->enumerators) {
1424         int name = strings.enter(enumerator.name);
1425         int enumName = strings.enter(enumerator.enumName);
1426         int isFlag = enumerator.isFlag ? EnumIsFlag : 0;
1427         int isScoped = enumerator.isScoped ? EnumIsScoped : 0;
1428         int count = enumerator.keys.size();
1429         int enumOffset = enumIndex;
1430         if (buf) {
1431             data[dataIndex]     = name;
1432             data[dataIndex + 1] = enumName;
1433             data[dataIndex + 2] = isFlag | isScoped;
1434             data[dataIndex + 3] = count;
1435             data[dataIndex + 4] = enumOffset;
1436         }
1437         for (int key = 0; key < count; ++key) {
1438             int keyIndex = strings.enter(enumerator.keys[key]);
1439             if (buf) {
1440                 data[enumOffset++] = keyIndex;
1441                 data[enumOffset++] = enumerator.values[key];
1442             }
1443         }
1444         dataIndex += 5;
1445         enumIndex += 2 * count;
1446     }
1447 
1448     // Output the constructors in the class.
1449     Q_ASSERT(!buf || dataIndex == pmeta->constructorData);
1450     for (const auto &ctor : d->constructors) {
1451         int name = strings.enter(ctor.name());
1452         int argc = ctor.parameterCount();
1453         int tag = strings.enter(ctor.tag);
1454         int attrs = ctor.attributes;
1455         if (buf) {
1456             data[dataIndex]     = name;
1457             data[dataIndex + 1] = argc;
1458             data[dataIndex + 2] = paramsIndex;
1459             data[dataIndex + 3] = tag;
1460             data[dataIndex + 4] = attrs;
1461         }
1462         dataIndex += 5;
1463         paramsIndex += 1 + argc * 2;
1464     }
1465 
1466     size += strings.blobSize();
1467 
1468     if (buf)
1469         strings.writeBlob(str);
1470 
1471     // Output the zero terminator in the data array.
1472     if (buf)
1473         data[enumIndex] = 0;
1474 
1475     // Create the relatedMetaObjects block if we need one.
1476     if (d->relatedMetaObjects.size() > 0) {
1477         using SuperData = QMetaObject::SuperData;
1478         ALIGN(size, SuperData);
1479         auto objects = reinterpret_cast<SuperData *>(buf + size);
1480         if (buf) {
1481             meta->d.relatedMetaObjects = objects;
1482             for (index = 0; index < d->relatedMetaObjects.size(); ++index)
1483                 objects[index] = d->relatedMetaObjects[index];
1484             objects[index] = nullptr;
1485         }
1486         size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1);
1487     }
1488 
1489     // Align the final size and return it.
1490     ALIGN(size, void *);
1491     Q_ASSERT(!buf || size == expectedSize);
1492     return size;
1493 }
1494 
1495 /*!
1496     Converts this meta object builder into a concrete QMetaObject.
1497     The return value should be deallocated using free() once it
1498     is no longer needed.
1499 
1500     The returned meta object is a snapshot of the state of the
1501     QMetaObjectBuilder.  Any further modifications to the QMetaObjectBuilder
1502     will not be reflected in previous meta objects returned by
1503     this method.
1504 */
toMetaObject() const1505 QMetaObject *QMetaObjectBuilder::toMetaObject() const
1506 {
1507     int size = buildMetaObject(d, nullptr, 0, false);
1508     char *buf = reinterpret_cast<char *>(malloc(size));
1509     memset(buf, 0, size);
1510     buildMetaObject(d, buf, size, false);
1511     return reinterpret_cast<QMetaObject *>(buf);
1512 }
1513 
1514 /*
1515     \internal
1516 
1517     Converts this meta object builder into relocatable data.  This data can
1518     be stored, copied and later passed to fromRelocatableData() to create a
1519     concrete QMetaObject.
1520 
1521     The data is specific to the architecture on which it was created, but is not
1522     specific to the process that created it.  Not all meta object builder's can
1523     be converted to data in this way.  If \a ok is provided, it will be set to
1524     true if the conversion succeeds, and false otherwise.  If a
1525     staticMetacallFunction() or any relatedMetaObject()'s are specified the
1526     conversion to relocatable data will fail.
1527 */
toRelocatableData(bool * ok) const1528 QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const
1529 {
1530     int size = buildMetaObject(d, nullptr, 0, true);
1531     if (size == -1) {
1532         if (ok) *ok = false;
1533         return QByteArray();
1534     }
1535 
1536     QByteArray data;
1537     data.resize(size);
1538     char *buf = data.data();
1539     memset(buf, 0, size);
1540     buildMetaObject(d, buf, size, true);
1541     if (ok) *ok = true;
1542     return data;
1543 }
1544 
1545 /*
1546     \internal
1547 
1548     Sets the \a data returned from toRelocatableData() onto a concrete
1549     QMetaObject instance, \a output.  As the meta object's super class is not
1550     saved in the relocatable data, it must be passed as \a superClass.
1551 */
fromRelocatableData(QMetaObject * output,const QMetaObject * superclass,const QByteArray & data)1552 void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
1553                                              const QMetaObject *superclass,
1554                                              const QByteArray &data)
1555 {
1556     if (!output)
1557         return;
1558 
1559     const char *buf = data.constData();
1560     const QMetaObject *dataMo = reinterpret_cast<const QMetaObject *>(buf);
1561 
1562     quintptr stringdataOffset = (quintptr)dataMo->d.stringdata;
1563     quintptr dataOffset = (quintptr)dataMo->d.data;
1564 
1565     output->d.superdata = superclass;
1566     output->d.stringdata = reinterpret_cast<const QByteArrayData *>(buf + stringdataOffset);
1567     output->d.data = reinterpret_cast<const uint *>(buf + dataOffset);
1568     output->d.extradata = nullptr;
1569     output->d.relatedMetaObjects = nullptr;
1570     output->d.static_metacall = nullptr;
1571 }
1572 
1573 /*!
1574     \typedef QMetaObjectBuilder::StaticMetacallFunction
1575 
1576     Typedef for static metacall functions.  The three parameters are
1577     the call type value, the constructor index, and the
1578     array of parameters.
1579 */
1580 
1581 /*!
1582     Returns the static metacall function to use to construct objects
1583     of this class.  The default value is null.
1584 
1585     \sa setStaticMetacallFunction()
1586 */
staticMetacallFunction() const1587 QMetaObjectBuilder::StaticMetacallFunction QMetaObjectBuilder::staticMetacallFunction() const
1588 {
1589     return d->staticMetacallFunction;
1590 }
1591 
1592 /*!
1593     Sets the static metacall function to use to construct objects
1594     of this class to \a value.  The default value is null.
1595 
1596     \sa staticMetacallFunction()
1597 */
setStaticMetacallFunction(QMetaObjectBuilder::StaticMetacallFunction value)1598 void QMetaObjectBuilder::setStaticMetacallFunction
1599         (QMetaObjectBuilder::StaticMetacallFunction value)
1600 {
1601     d->staticMetacallFunction = value;
1602 }
1603 
1604 #ifndef QT_NO_DATASTREAM
1605 
1606 /*!
1607     Serializes the contents of the meta object builder onto \a stream.
1608 
1609     \sa deserialize()
1610 */
serialize(QDataStream & stream) const1611 void QMetaObjectBuilder::serialize(QDataStream& stream) const
1612 {
1613     int index;
1614 
1615     // Write the class and super class names.
1616     stream << d->className;
1617     if (d->superClass)
1618         stream << QByteArray(d->superClass->className());
1619     else
1620         stream << QByteArray();
1621 
1622     // Write the counts for each type of class member.
1623     stream << d->classInfoNames.size();
1624     stream << int(d->methods.size());
1625     stream << int(d->properties.size());
1626     stream << int(d->enumerators.size());
1627     stream << int(d->constructors.size());
1628     stream << d->relatedMetaObjects.size();
1629 
1630     // Write the items of class information.
1631     for (index = 0; index < d->classInfoNames.size(); ++index) {
1632         stream << d->classInfoNames[index];
1633         stream << d->classInfoValues[index];
1634     }
1635 
1636     // Write the methods.
1637     for (const auto &method : d->methods) {
1638         stream << method.signature;
1639         stream << method.returnType;
1640         stream << method.parameterNames;
1641         stream << method.tag;
1642         stream << method.attributes;
1643         if (method.revision)
1644             stream << method.revision;
1645     }
1646 
1647     // Write the properties.
1648     for (const auto &property : d->properties) {
1649         stream << property.name;
1650         stream << property.type;
1651         stream << property.flags;
1652         stream << property.notifySignal;
1653         if (property.revision)
1654             stream << property.revision;
1655     }
1656 
1657     // Write the enumerators.
1658     for (const auto &enumerator : d->enumerators) {
1659         stream << enumerator.name;
1660         stream << enumerator.isFlag;
1661         stream << enumerator.isScoped;
1662         stream << enumerator.keys;
1663         stream << enumerator.values;
1664     }
1665 
1666     // Write the constructors.
1667     for (const auto &ctor : d->constructors) {
1668         stream << ctor.signature;
1669         stream << ctor.returnType;
1670         stream << ctor.parameterNames;
1671         stream << ctor.tag;
1672         stream << ctor.attributes;
1673     }
1674 
1675     // Write the related meta objects.
1676     for (index = 0; index < d->relatedMetaObjects.size(); ++index) {
1677         const QMetaObject *meta = d->relatedMetaObjects[index];
1678         stream << QByteArray(meta->className());
1679     }
1680 
1681     // Add an extra empty QByteArray for additional data in future versions.
1682     // This should help maintain backwards compatibility, allowing older
1683     // versions to read newer data.
1684     stream << QByteArray();
1685 }
1686 
1687 // Resolve a class name using the name reference map.
resolveClassName(const QMap<QByteArray,const QMetaObject * > & references,const QByteArray & name)1688 static const QMetaObject *resolveClassName
1689         (const QMap<QByteArray, const QMetaObject *>& references,
1690          const QByteArray& name)
1691 {
1692     if (name == QByteArray("QObject"))
1693         return &QObject::staticMetaObject;
1694     else
1695         return references.value(name, 0);
1696 }
1697 
1698 /*!
1699     Deserializes a meta object builder from \a stream into
1700     this meta object builder.
1701 
1702     The \a references parameter specifies a mapping from class names
1703     to QMetaObject instances for resolving the super class name and
1704     related meta objects in the object that is deserialized.
1705     The meta object for QObject is implicitly added to \a references
1706     and does not need to be supplied.
1707 
1708     The QDataStream::status() value on \a stream will be set to
1709     QDataStream::ReadCorruptData if the input data is corrupt.
1710     The status will be set to QDataStream::ReadPastEnd if the
1711     input was exhausted before the full meta object was read.
1712 
1713     \sa serialize()
1714 */
deserialize(QDataStream & stream,const QMap<QByteArray,const QMetaObject * > & references)1715 void QMetaObjectBuilder::deserialize
1716         (QDataStream& stream,
1717          const QMap<QByteArray, const QMetaObject *>& references)
1718 {
1719     QByteArray name;
1720     const QMetaObject *cl;
1721     int index;
1722 
1723     // Clear all members in the builder to their default states.
1724     d->className.clear();
1725     d->superClass = &QObject::staticMetaObject;
1726     d->classInfoNames.clear();
1727     d->classInfoValues.clear();
1728     d->methods.clear();
1729     d->properties.clear();
1730     d->enumerators.clear();
1731     d->constructors.clear();
1732     d->relatedMetaObjects.clear();
1733     d->staticMetacallFunction = nullptr;
1734 
1735     // Read the class and super class names.
1736     stream >> d->className;
1737     stream >> name;
1738     if (name.isEmpty()) {
1739         d->superClass = nullptr;
1740     } else if ((cl = resolveClassName(references, name)) != nullptr) {
1741         d->superClass = cl;
1742     } else {
1743         stream.setStatus(QDataStream::ReadCorruptData);
1744         return;
1745     }
1746 
1747     // Read the counts for each type of class member.
1748     int classInfoCount, methodCount, propertyCount;
1749     int enumeratorCount, constructorCount, relatedMetaObjectCount;
1750     stream >> classInfoCount;
1751     stream >> methodCount;
1752     stream >> propertyCount;
1753     stream >> enumeratorCount;
1754     stream >> constructorCount;
1755     stream >> relatedMetaObjectCount;
1756     if (classInfoCount < 0 || methodCount < 0 ||
1757         propertyCount < 0 || enumeratorCount < 0 ||
1758         constructorCount < 0 || relatedMetaObjectCount < 0) {
1759         stream.setStatus(QDataStream::ReadCorruptData);
1760         return;
1761     }
1762 
1763     // Read the items of class information.
1764     for (index = 0; index < classInfoCount; ++index) {
1765         if (stream.status() != QDataStream::Ok)
1766             return;
1767         QByteArray value;
1768         stream >> name;
1769         stream >> value;
1770         addClassInfo(name, value);
1771     }
1772 
1773     // Read the member methods.
1774     for (index = 0; index < methodCount; ++index) {
1775         if (stream.status() != QDataStream::Ok)
1776             return;
1777         stream >> name;
1778         addMethod(name);
1779         QMetaMethodBuilderPrivate &method = d->methods[index];
1780         stream >> method.returnType;
1781         stream >> method.parameterNames;
1782         stream >> method.tag;
1783         stream >> method.attributes;
1784         if (method.attributes & MethodRevisioned)
1785             stream >> method.revision;
1786         if (method.methodType() == QMetaMethod::Constructor) {
1787             // Cannot add a constructor in this set of methods.
1788             stream.setStatus(QDataStream::ReadCorruptData);
1789             return;
1790         }
1791     }
1792 
1793     // Read the properties.
1794     for (index = 0; index < propertyCount; ++index) {
1795         if (stream.status() != QDataStream::Ok)
1796             return;
1797         QByteArray type;
1798         stream >> name;
1799         stream >> type;
1800         addProperty(name, type);
1801         QMetaPropertyBuilderPrivate &property = d->properties[index];
1802         stream >> property.flags;
1803         stream >> property.notifySignal;
1804         if (property.notifySignal < -1 ||
1805             property.notifySignal >= int(d->methods.size())) {
1806             // Notify signal method index is out of range.
1807             stream.setStatus(QDataStream::ReadCorruptData);
1808             return;
1809         }
1810         if (property.notifySignal >= 0 &&
1811             d->methods[property.notifySignal].methodType() != QMetaMethod::Signal) {
1812             // Notify signal method index does not refer to a signal.
1813             stream.setStatus(QDataStream::ReadCorruptData);
1814             return;
1815         }
1816         if (property.flags & Revisioned)
1817             stream >> property.revision;
1818     }
1819 
1820     // Read the enumerators.
1821     for (index = 0; index < enumeratorCount; ++index) {
1822         if (stream.status() != QDataStream::Ok)
1823             return;
1824         stream >> name;
1825         addEnumerator(name);
1826         QMetaEnumBuilderPrivate &enumerator = d->enumerators[index];
1827         stream >> enumerator.isFlag;
1828         stream >> enumerator.isScoped;
1829         stream >> enumerator.keys;
1830         stream >> enumerator.values;
1831         if (enumerator.keys.size() != enumerator.values.size()) {
1832             // Mismatch between number of keys and number of values.
1833             stream.setStatus(QDataStream::ReadCorruptData);
1834             return;
1835         }
1836     }
1837 
1838     // Read the constructor methods.
1839     for (index = 0; index < constructorCount; ++index) {
1840         if (stream.status() != QDataStream::Ok)
1841             return;
1842         stream >> name;
1843         addConstructor(name);
1844         QMetaMethodBuilderPrivate &method = d->constructors[index];
1845         stream >> method.returnType;
1846         stream >> method.parameterNames;
1847         stream >> method.tag;
1848         stream >> method.attributes;
1849         if (method.methodType() != QMetaMethod::Constructor) {
1850             // The type must be Constructor.
1851             stream.setStatus(QDataStream::ReadCorruptData);
1852             return;
1853         }
1854     }
1855 
1856     // Read the related meta objects.
1857     for (index = 0; index < relatedMetaObjectCount; ++index) {
1858         if (stream.status() != QDataStream::Ok)
1859             return;
1860         stream >> name;
1861         cl = resolveClassName(references, name);
1862         if (!cl) {
1863             stream.setStatus(QDataStream::ReadCorruptData);
1864             return;
1865         }
1866         addRelatedMetaObject(cl);
1867     }
1868 
1869     // Read the extra data block, which is reserved for future use.
1870     stream >> name;
1871 }
1872 
1873 #endif // !QT_NO_DATASTREAM
1874 
1875 /*!
1876     \class QMetaMethodBuilder
1877     \inmodule QtCore
1878     \internal
1879     \brief The QMetaMethodBuilder class enables modifications to a method definition on a meta object builder.
1880 */
1881 
d_func() const1882 QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const
1883 {
1884     // Positive indices indicate methods, negative indices indicate constructors.
1885     if (_mobj && _index >= 0 && _index < int(_mobj->d->methods.size()))
1886         return &(_mobj->d->methods[_index]);
1887     else if (_mobj && -_index >= 1 && -_index <= int(_mobj->d->constructors.size()))
1888         return &(_mobj->d->constructors[(-_index) - 1]);
1889     else
1890         return nullptr;
1891 }
1892 
1893 /*!
1894     \fn QMetaMethodBuilder::QMetaMethodBuilder()
1895     \internal
1896 */
1897 
1898 /*!
1899     Returns the index of this method within its QMetaObjectBuilder.
1900 */
index() const1901 int QMetaMethodBuilder::index() const
1902 {
1903     if (_index >= 0)
1904         return _index;          // Method, signal, or slot
1905     else
1906         return (-_index) - 1;   // Constructor
1907 }
1908 
1909 /*!
1910     Returns the type of this method (signal, slot, method, or constructor).
1911 */
methodType() const1912 QMetaMethod::MethodType QMetaMethodBuilder::methodType() const
1913 {
1914     QMetaMethodBuilderPrivate *d = d_func();
1915     if (d)
1916         return d->methodType();
1917     else
1918         return QMetaMethod::Method;
1919 }
1920 
1921 /*!
1922     Returns the signature of this method.
1923 
1924     \sa parameterNames(), returnType()
1925 */
signature() const1926 QByteArray QMetaMethodBuilder::signature() const
1927 {
1928     QMetaMethodBuilderPrivate *d = d_func();
1929     if (d)
1930         return d->signature;
1931     else
1932         return QByteArray();
1933 }
1934 
1935 /*!
1936     Returns the return type for this method; empty if the method's
1937     return type is \c{void}.
1938 
1939     \sa setReturnType(), signature()
1940 */
returnType() const1941 QByteArray QMetaMethodBuilder::returnType() const
1942 {
1943     QMetaMethodBuilderPrivate *d = d_func();
1944     if (d)
1945         return d->returnType;
1946     else
1947         return QByteArray();
1948 }
1949 
1950 /*!
1951     Sets the return type for this method to \a value.  If \a value
1952     is empty, then the method's return type is \c{void}.  The \a value
1953     will be normalized before it is added to the method.
1954 
1955     \sa returnType(), parameterTypes(), signature()
1956 */
setReturnType(const QByteArray & value)1957 void QMetaMethodBuilder::setReturnType(const QByteArray& value)
1958 {
1959     QMetaMethodBuilderPrivate *d = d_func();
1960     if (d)
1961         d->returnType = QMetaObject::normalizedType(value);
1962 }
1963 
1964 /*!
1965     Returns the list of parameter types for this method.
1966 
1967     \sa returnType(), parameterNames()
1968 */
parameterTypes() const1969 QList<QByteArray> QMetaMethodBuilder::parameterTypes() const
1970 {
1971     QMetaMethodBuilderPrivate *d = d_func();
1972     if (d)
1973         return d->parameterTypes();
1974     else
1975         return QList<QByteArray>();
1976 }
1977 
1978 /*!
1979     Returns the list of parameter names for this method.
1980 
1981     \sa setParameterNames()
1982 */
parameterNames() const1983 QList<QByteArray> QMetaMethodBuilder::parameterNames() const
1984 {
1985     QMetaMethodBuilderPrivate *d = d_func();
1986     if (d)
1987         return d->parameterNames;
1988     else
1989         return QList<QByteArray>();
1990 }
1991 
1992 /*!
1993     Sets the list of parameter names for this method to \a value.
1994 
1995     \sa parameterNames()
1996 */
setParameterNames(const QList<QByteArray> & value)1997 void QMetaMethodBuilder::setParameterNames(const QList<QByteArray>& value)
1998 {
1999     QMetaMethodBuilderPrivate *d = d_func();
2000     if (d)
2001         d->parameterNames = value;
2002 }
2003 
2004 /*!
2005     Returns the tag associated with this method.
2006 
2007     \sa setTag()
2008 */
tag() const2009 QByteArray QMetaMethodBuilder::tag() const
2010 {
2011     QMetaMethodBuilderPrivate *d = d_func();
2012     if (d)
2013         return d->tag;
2014     else
2015         return QByteArray();
2016 }
2017 
2018 /*!
2019     Sets the tag associated with this method to \a value.
2020 
2021     \sa setTag()
2022 */
setTag(const QByteArray & value)2023 void QMetaMethodBuilder::setTag(const QByteArray& value)
2024 {
2025     QMetaMethodBuilderPrivate *d = d_func();
2026     if (d)
2027         d->tag = value;
2028 }
2029 
2030 /*!
2031     Returns the access specification of this method (private, protected,
2032     or public).  The default value is QMetaMethod::Public for methods,
2033     slots, signals and constructors.
2034 
2035     \sa setAccess()
2036 */
access() const2037 QMetaMethod::Access QMetaMethodBuilder::access() const
2038 {
2039     QMetaMethodBuilderPrivate *d = d_func();
2040     if (d)
2041         return d->access();
2042     else
2043         return QMetaMethod::Public;
2044 }
2045 
2046 /*!
2047     Sets the access specification of this method (private, protected,
2048     or public) to \a value.  If the method is a signal, this function
2049     will be ignored.
2050 
2051     \sa access()
2052 */
setAccess(QMetaMethod::Access value)2053 void QMetaMethodBuilder::setAccess(QMetaMethod::Access value)
2054 {
2055     QMetaMethodBuilderPrivate *d = d_func();
2056     if (d && d->methodType() != QMetaMethod::Signal)
2057         d->setAccess(value);
2058 }
2059 
2060 /*!
2061     Returns the additional attributes for this method.
2062 
2063     \sa setAttributes()
2064 */
attributes() const2065 int QMetaMethodBuilder::attributes() const
2066 {
2067     QMetaMethodBuilderPrivate *d = d_func();
2068     if (d)
2069         return (d->attributes >> 4);
2070     else
2071         return 0;
2072 }
2073 
2074 /*!
2075     Sets the additional attributes for this method to \a value.
2076 
2077     \sa attributes()
2078 */
setAttributes(int value)2079 void QMetaMethodBuilder::setAttributes(int value)
2080 {
2081     QMetaMethodBuilderPrivate *d = d_func();
2082     if (d)
2083         d->attributes = ((d->attributes & 0x0f) | (value << 4));
2084 }
2085 
2086 /*!
2087     Returns the revision of this method.
2088 
2089     \sa setRevision()
2090 */
revision() const2091 int QMetaMethodBuilder::revision() const
2092 {
2093     QMetaMethodBuilderPrivate *d = d_func();
2094     if (d)
2095         return d->revision;
2096     return 0;
2097 
2098 }
2099 
2100 /*!
2101     Sets the \a revision of this method.
2102 
2103     \sa revision()
2104 */
setRevision(int revision)2105 void QMetaMethodBuilder::setRevision(int revision)
2106 {
2107     QMetaMethodBuilderPrivate *d = d_func();
2108     if (d) {
2109         d->revision = revision;
2110         if (revision)
2111             d->attributes |= MethodRevisioned;
2112         else
2113             d->attributes &= ~MethodRevisioned;
2114     }
2115 }
2116 
2117 /*!
2118     \class QMetaPropertyBuilder
2119     \inmodule QtCore
2120     \internal
2121     \brief The QMetaPropertyBuilder class enables modifications to a property definition on a meta object builder.
2122 */
2123 
d_func() const2124 QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const
2125 {
2126     if (_mobj && _index >= 0 && _index < int(_mobj->d->properties.size()))
2127         return &(_mobj->d->properties[_index]);
2128     else
2129         return nullptr;
2130 }
2131 
2132 /*!
2133     \fn QMetaPropertyBuilder::QMetaPropertyBuilder()
2134     \internal
2135 */
2136 
2137 /*!
2138     \fn int QMetaPropertyBuilder::index() const
2139 
2140     Returns the index of this property within its QMetaObjectBuilder.
2141 */
2142 
2143 /*!
2144     Returns the name associated with this property.
2145 
2146     \sa type()
2147 */
name() const2148 QByteArray QMetaPropertyBuilder::name() const
2149 {
2150     QMetaPropertyBuilderPrivate *d = d_func();
2151     if (d)
2152         return d->name;
2153     else
2154         return QByteArray();
2155 }
2156 
2157 /*!
2158     Returns the type associated with this property.
2159 
2160     \sa name()
2161 */
type() const2162 QByteArray QMetaPropertyBuilder::type() const
2163 {
2164     QMetaPropertyBuilderPrivate *d = d_func();
2165     if (d)
2166         return d->type;
2167     else
2168         return QByteArray();
2169 }
2170 
2171 /*!
2172     Returns \c true if this property has a notify signal; false otherwise.
2173 
2174     \sa notifySignal(), setNotifySignal(), removeNotifySignal()
2175 */
hasNotifySignal() const2176 bool QMetaPropertyBuilder::hasNotifySignal() const
2177 {
2178     QMetaPropertyBuilderPrivate *d = d_func();
2179     if (d)
2180         return d->flag(Notify);
2181     else
2182         return false;
2183 }
2184 
2185 /*!
2186     Returns the notify signal associated with this property.
2187 
2188     \sa hasNotifySignal(), setNotifySignal(), removeNotifySignal()
2189 */
notifySignal() const2190 QMetaMethodBuilder QMetaPropertyBuilder::notifySignal() const
2191 {
2192     QMetaPropertyBuilderPrivate *d = d_func();
2193     if (d && d->notifySignal >= 0)
2194         return QMetaMethodBuilder(_mobj, d->notifySignal);
2195     else
2196         return QMetaMethodBuilder();
2197 }
2198 
2199 /*!
2200     Sets the notify signal associated with this property to \a value.
2201 
2202     \sa hasNotifySignal(), notifySignal(), removeNotifySignal()
2203 */
setNotifySignal(const QMetaMethodBuilder & value)2204 void QMetaPropertyBuilder::setNotifySignal(const QMetaMethodBuilder& value)
2205 {
2206     QMetaPropertyBuilderPrivate *d = d_func();
2207     if (d) {
2208         if (value._mobj) {
2209             d->notifySignal = value._index;
2210             d->setFlag(Notify, true);
2211         } else {
2212             d->notifySignal = -1;
2213             d->setFlag(Notify, false);
2214         }
2215     }
2216 }
2217 
2218 /*!
2219     Removes the notify signal from this property.
2220 
2221     \sa hasNotifySignal(), notifySignal(), setNotifySignal()
2222 */
removeNotifySignal()2223 void QMetaPropertyBuilder::removeNotifySignal()
2224 {
2225     QMetaPropertyBuilderPrivate *d = d_func();
2226     if (d) {
2227         d->notifySignal = -1;
2228         d->setFlag(Notify, false);
2229     }
2230 }
2231 
2232 /*!
2233     Returns \c true if this property is readable; otherwise returns \c false.
2234     The default value is true.
2235 
2236     \sa setReadable(), isWritable()
2237 */
isReadable() const2238 bool QMetaPropertyBuilder::isReadable() const
2239 {
2240     QMetaPropertyBuilderPrivate *d = d_func();
2241     if (d)
2242         return d->flag(Readable);
2243     else
2244         return false;
2245 }
2246 
2247 /*!
2248     Returns \c true if this property is writable; otherwise returns \c false.
2249     The default value is true.
2250 
2251     \sa setWritable(), isReadable()
2252 */
isWritable() const2253 bool QMetaPropertyBuilder::isWritable() const
2254 {
2255     QMetaPropertyBuilderPrivate *d = d_func();
2256     if (d)
2257         return d->flag(Writable);
2258     else
2259         return false;
2260 }
2261 
2262 /*!
2263     Returns \c true if this property can be reset to a default value; otherwise
2264     returns \c false.  The default value is false.
2265 
2266     \sa setResettable()
2267 */
isResettable() const2268 bool QMetaPropertyBuilder::isResettable() const
2269 {
2270     QMetaPropertyBuilderPrivate *d = d_func();
2271     if (d)
2272         return d->flag(Resettable);
2273     else
2274         return false;
2275 }
2276 
2277 /*!
2278     Returns \c true if this property is designable; otherwise returns \c false.
2279     This default value is false.
2280 
2281     \sa setDesignable(), isScriptable(), isStored()
2282 */
isDesignable() const2283 bool QMetaPropertyBuilder::isDesignable() const
2284 {
2285     QMetaPropertyBuilderPrivate *d = d_func();
2286     if (d)
2287         return d->flag(Designable);
2288     else
2289         return false;
2290 }
2291 
2292 /*!
2293     Returns \c true if the property is scriptable; otherwise returns \c false.
2294     This default value is true.
2295 
2296     \sa setScriptable(), isDesignable(), isStored()
2297 */
isScriptable() const2298 bool QMetaPropertyBuilder::isScriptable() const
2299 {
2300     QMetaPropertyBuilderPrivate *d = d_func();
2301     if (d)
2302         return d->flag(Scriptable);
2303     else
2304         return false;
2305 }
2306 
2307 /*!
2308     Returns \c true if the property is stored; otherwise returns \c false.
2309     This default value is false.
2310 
2311     \sa setStored(), isDesignable(), isScriptable()
2312 */
isStored() const2313 bool QMetaPropertyBuilder::isStored() const
2314 {
2315     QMetaPropertyBuilderPrivate *d = d_func();
2316     if (d)
2317         return d->flag(Stored);
2318     else
2319         return false;
2320 }
2321 
2322 /*!
2323     Returns \c true if the property is editable; otherwise returns \c false.
2324     This default value is false.
2325 
2326     \sa setEditable(), isDesignable(), isScriptable(), isStored()
2327 */
isEditable() const2328 bool QMetaPropertyBuilder::isEditable() const
2329 {
2330     QMetaPropertyBuilderPrivate *d = d_func();
2331     if (d)
2332         return d->flag(Editable);
2333     else
2334         return false;
2335 }
2336 
2337 /*!
2338     Returns \c true if this property is designated as the \c USER
2339     property, i.e., the one that the user can edit or that is
2340     significant in some other way.  Otherwise it returns
2341     false.  This default value is false.
2342 
2343     \sa setUser(), isDesignable(), isScriptable()
2344 */
isUser() const2345 bool QMetaPropertyBuilder::isUser() const
2346 {
2347     QMetaPropertyBuilderPrivate *d = d_func();
2348     if (d)
2349         return d->flag(User);
2350     else
2351         return false;
2352 }
2353 
2354 /*!
2355     Returns \c true if the property has a C++ setter function that
2356     follows Qt's standard "name" / "setName" pattern. Designer and uic
2357     query hasStdCppSet() in order to avoid expensive
2358     QObject::setProperty() calls. All properties in Qt [should] follow
2359     this pattern.  The default value is false.
2360 
2361     \sa setStdCppSet()
2362 */
hasStdCppSet() const2363 bool QMetaPropertyBuilder::hasStdCppSet() const
2364 {
2365     QMetaPropertyBuilderPrivate *d = d_func();
2366     if (d)
2367         return d->flag(StdCppSet);
2368     else
2369         return false;
2370 }
2371 
2372 /*!
2373     Returns \c true if the property is an enumerator or flag type;
2374     otherwise returns \c false.  This default value is false.
2375 
2376     \sa setEnumOrFlag()
2377 */
isEnumOrFlag() const2378 bool QMetaPropertyBuilder::isEnumOrFlag() const
2379 {
2380     QMetaPropertyBuilderPrivate *d = d_func();
2381     if (d)
2382         return d->flag(EnumOrFlag);
2383     else
2384         return false;
2385 }
2386 
2387 /*!
2388     Returns \c true if the property is constant; otherwise returns \c false.
2389     The default value is false.
2390 */
isConstant() const2391 bool QMetaPropertyBuilder::isConstant() const
2392 {
2393     QMetaPropertyBuilderPrivate *d = d_func();
2394     if (d)
2395         return d->flag(Constant);
2396     else
2397         return false;
2398 }
2399 
2400 /*!
2401     Returns \c true if the property is final; otherwise returns \c false.
2402     The default value is false.
2403 */
isFinal() const2404 bool QMetaPropertyBuilder::isFinal() const
2405 {
2406     QMetaPropertyBuilderPrivate *d = d_func();
2407     if (d)
2408         return d->flag(Final);
2409     else
2410         return false;
2411 }
2412 
2413 /*!
2414     Sets this property to readable if \a value is true.
2415 
2416     \sa isReadable(), setWritable()
2417 */
setReadable(bool value)2418 void QMetaPropertyBuilder::setReadable(bool value)
2419 {
2420     QMetaPropertyBuilderPrivate *d = d_func();
2421     if (d)
2422         d->setFlag(Readable, value);
2423 }
2424 
2425 /*!
2426     Sets this property to writable if \a value is true.
2427 
2428     \sa isWritable(), setReadable()
2429 */
setWritable(bool value)2430 void QMetaPropertyBuilder::setWritable(bool value)
2431 {
2432     QMetaPropertyBuilderPrivate *d = d_func();
2433     if (d)
2434         d->setFlag(Writable, value);
2435 }
2436 
2437 /*!
2438     Sets this property to resettable if \a value is true.
2439 
2440     \sa isResettable()
2441 */
setResettable(bool value)2442 void QMetaPropertyBuilder::setResettable(bool value)
2443 {
2444     QMetaPropertyBuilderPrivate *d = d_func();
2445     if (d)
2446         d->setFlag(Resettable, value);
2447 }
2448 
2449 /*!
2450     Sets this property to designable if \a value is true.
2451 
2452     \sa isDesignable(), setScriptable(), setStored()
2453 */
setDesignable(bool value)2454 void QMetaPropertyBuilder::setDesignable(bool value)
2455 {
2456     QMetaPropertyBuilderPrivate *d = d_func();
2457     if (d)
2458         d->setFlag(Designable, value);
2459 }
2460 
2461 /*!
2462     Sets this property to scriptable if \a value is true.
2463 
2464     \sa isScriptable(), setDesignable(), setStored()
2465 */
setScriptable(bool value)2466 void QMetaPropertyBuilder::setScriptable(bool value)
2467 {
2468     QMetaPropertyBuilderPrivate *d = d_func();
2469     if (d)
2470         d->setFlag(Scriptable, value);
2471 }
2472 
2473 /*!
2474     Sets this property to storable if \a value is true.
2475 
2476     \sa isStored(), setDesignable(), setScriptable()
2477 */
setStored(bool value)2478 void QMetaPropertyBuilder::setStored(bool value)
2479 {
2480     QMetaPropertyBuilderPrivate *d = d_func();
2481     if (d)
2482         d->setFlag(Stored, value);
2483 }
2484 
2485 /*!
2486     Sets this property to editable if \a value is true.
2487 
2488     \sa isEditable(), setDesignable(), setScriptable(), setStored()
2489 */
setEditable(bool value)2490 void QMetaPropertyBuilder::setEditable(bool value)
2491 {
2492     QMetaPropertyBuilderPrivate *d = d_func();
2493     if (d)
2494         d->setFlag(Editable, value);
2495 }
2496 
2497 /*!
2498     Sets the \c USER flag on this property to \a value.
2499 
2500     \sa isUser(), setDesignable(), setScriptable()
2501 */
setUser(bool value)2502 void QMetaPropertyBuilder::setUser(bool value)
2503 {
2504     QMetaPropertyBuilderPrivate *d = d_func();
2505     if (d)
2506         d->setFlag(User, value);
2507 }
2508 
2509 /*!
2510     Sets the C++ setter flag on this property to \a value, which is
2511     true if the property has a C++ setter function that follows Qt's
2512     standard "name" / "setName" pattern.
2513 
2514     \sa hasStdCppSet()
2515 */
setStdCppSet(bool value)2516 void QMetaPropertyBuilder::setStdCppSet(bool value)
2517 {
2518     QMetaPropertyBuilderPrivate *d = d_func();
2519     if (d)
2520         d->setFlag(StdCppSet, value);
2521 }
2522 
2523 /*!
2524     Sets this property to be of an enumerator or flag type if
2525     \a value is true.
2526 
2527     \sa isEnumOrFlag()
2528 */
setEnumOrFlag(bool value)2529 void QMetaPropertyBuilder::setEnumOrFlag(bool value)
2530 {
2531     QMetaPropertyBuilderPrivate *d = d_func();
2532     if (d)
2533         d->setFlag(EnumOrFlag, value);
2534 }
2535 
2536 /*!
2537     Sets the \c CONSTANT flag on this property to \a value.
2538 
2539     \sa isConstant()
2540 */
setConstant(bool value)2541 void QMetaPropertyBuilder::setConstant(bool value)
2542 {
2543     QMetaPropertyBuilderPrivate *d = d_func();
2544     if (d)
2545         d->setFlag(Constant, value);
2546 }
2547 
2548 /*!
2549     Sets the \c FINAL flag on this property to \a value.
2550 
2551     \sa isFinal()
2552 */
setFinal(bool value)2553 void QMetaPropertyBuilder::setFinal(bool value)
2554 {
2555     QMetaPropertyBuilderPrivate *d = d_func();
2556     if (d)
2557         d->setFlag(Final, value);
2558 }
2559 
2560 /*!
2561     Returns the revision of this property.
2562 
2563     \sa setRevision()
2564 */
revision() const2565 int QMetaPropertyBuilder::revision() const
2566 {
2567     QMetaPropertyBuilderPrivate *d = d_func();
2568     if (d)
2569         return d->revision;
2570     return 0;
2571 
2572 }
2573 
2574 /*!
2575     Sets the \a revision of this property.
2576 
2577     \sa revision()
2578 */
setRevision(int revision)2579 void QMetaPropertyBuilder::setRevision(int revision)
2580 {
2581     QMetaPropertyBuilderPrivate *d = d_func();
2582     if (d) {
2583         d->revision = revision;
2584         d->setFlag(Revisioned, revision != 0);
2585     }
2586 }
2587 
2588 
2589 /*!
2590     \class QMetaEnumBuilder
2591     \inmodule QtCore
2592     \internal
2593     \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder.
2594 */
2595 
d_func() const2596 QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const
2597 {
2598     if (_mobj && _index >= 0 && _index < int(_mobj->d->enumerators.size()))
2599         return &(_mobj->d->enumerators[_index]);
2600     else
2601         return nullptr;
2602 }
2603 
2604 /*!
2605     \fn QMetaEnumBuilder::QMetaEnumBuilder()
2606     \internal
2607 */
2608 
2609 /*!
2610     \fn int QMetaEnumBuilder::index() const
2611 
2612     Returns the index of this enumerator within its QMetaObjectBuilder.
2613 */
2614 
2615 /*!
2616     Returns the type name of the enumerator (without the scope).
2617 */
name() const2618 QByteArray QMetaEnumBuilder::name() const
2619 {
2620     QMetaEnumBuilderPrivate *d = d_func();
2621     if (d)
2622         return d->name;
2623     else
2624         return QByteArray();
2625 }
2626 
2627 /*!
2628     Returns the enum name of the enumerator (without the scope).
2629 
2630     \since 5.12
2631 */
enumName() const2632 QByteArray QMetaEnumBuilder::enumName() const
2633 {
2634     QMetaEnumBuilderPrivate *d = d_func();
2635     if (d)
2636         return d->enumName;
2637     else
2638         return QByteArray();
2639 }
2640 
2641 /*!
2642     Sets this enumerator to have the enum name \c alias.
2643 
2644     \since 5.12
2645     \sa isFlag(), enumName()
2646 */
setEnumName(const QByteArray & alias)2647 void QMetaEnumBuilder::setEnumName(const QByteArray &alias)
2648 {
2649     QMetaEnumBuilderPrivate *d = d_func();
2650     if (d)
2651         d->enumName = alias;
2652 }
2653 
2654 /*!
2655     Returns \c true if this enumerator is used as a flag; otherwise returns
2656     false.
2657 
2658     \sa setIsFlag()
2659 */
isFlag() const2660 bool QMetaEnumBuilder::isFlag() const
2661 {
2662     QMetaEnumBuilderPrivate *d = d_func();
2663     if (d)
2664         return d->isFlag;
2665     else
2666         return false;
2667 }
2668 
2669 /*!
2670     Sets this enumerator to be used as a flag if \a value is true.
2671 
2672     \sa isFlag()
2673 */
setIsFlag(bool value)2674 void QMetaEnumBuilder::setIsFlag(bool value)
2675 {
2676     QMetaEnumBuilderPrivate *d = d_func();
2677     if (d)
2678         d->isFlag = value;
2679 }
2680 
2681 /*!
2682     Return \c true if this enumerator should be considered scoped (C++11 enum class).
2683 
2684     \sa setIsScoped()
2685 */
isScoped() const2686 bool QMetaEnumBuilder::isScoped() const
2687 {
2688     QMetaEnumBuilderPrivate *d = d_func();
2689     if (d)
2690         return d->isScoped;
2691     return false;
2692 }
2693 
2694 /*!
2695     Sets this enumerator to be a scoped enum if \value is true
2696 
2697     \sa isScoped()
2698 */
setIsScoped(bool value)2699 void QMetaEnumBuilder::setIsScoped(bool value)
2700 {
2701     QMetaEnumBuilderPrivate *d = d_func();
2702     if (d)
2703         d->isScoped = value;
2704 }
2705 
2706 /*!
2707     Returns the number of keys.
2708 
2709     \sa key(), addKey()
2710 */
keyCount() const2711 int QMetaEnumBuilder::keyCount() const
2712 {
2713     QMetaEnumBuilderPrivate *d = d_func();
2714     if (d)
2715         return d->keys.size();
2716     else
2717         return 0;
2718 }
2719 
2720 /*!
2721     Returns the key with the given \a index, or an empty QByteArray
2722     if no such key exists.
2723 
2724     \sa keyCount(), addKey(), value()
2725 */
key(int index) const2726 QByteArray QMetaEnumBuilder::key(int index) const
2727 {
2728     QMetaEnumBuilderPrivate *d = d_func();
2729     if (d && index >= 0 && index < d->keys.size())
2730         return d->keys[index];
2731     else
2732         return QByteArray();
2733 }
2734 
2735 /*!
2736     Returns the value with the given \a index; or returns -1 if there
2737     is no such value.
2738 
2739     \sa keyCount(), addKey(), key()
2740 */
value(int index) const2741 int QMetaEnumBuilder::value(int index) const
2742 {
2743     QMetaEnumBuilderPrivate *d = d_func();
2744     if (d && index >= 0 && index < d->keys.size())
2745         return d->values[index];
2746     else
2747         return -1;
2748 }
2749 
2750 /*!
2751     Adds a new key called \a name to this enumerator, associated
2752     with \a value.  Returns the index of the new key.
2753 
2754     \sa keyCount(), key(), value(), removeKey()
2755 */
addKey(const QByteArray & name,int value)2756 int QMetaEnumBuilder::addKey(const QByteArray& name, int value)
2757 {
2758     QMetaEnumBuilderPrivate *d = d_func();
2759     if (d) {
2760         int index = d->keys.size();
2761         d->keys += name;
2762         d->values += value;
2763         return index;
2764     } else {
2765         return -1;
2766     }
2767 }
2768 
2769 /*!
2770     Removes the key at \a index from this enumerator.
2771 
2772     \sa addKey()
2773 */
removeKey(int index)2774 void QMetaEnumBuilder::removeKey(int index)
2775 {
2776     QMetaEnumBuilderPrivate *d = d_func();
2777     if (d && index >= 0 && index < d->keys.size()) {
2778         d->keys.removeAt(index);
2779         d->values.removeAt(index);
2780     }
2781 }
2782 
2783 QT_END_NAMESPACE
2784