QByteArray MaiaXmlRpcServerConnection::getReturnType( const QMetaObject *obj, const QByteArray &method, const QList<QByteArray> &argTypes ) { for( int n = 0; n < obj->methodCount(); ++n ) { QMetaMethod m = obj->method(n); #if QT_VERSION >= 0x050000 if( m.name() == method && m.parameterTypes() == argTypes ) { return m.typeName(); } #else QByteArray sig = m.signature(); int offset = sig.indexOf('('); if( offset == -1 ) { continue; } QByteArray name = sig.mid(0, offset); if( name == method && m.parameterTypes() == argTypes ) { return m.typeName(); } #endif } return QByteArray(); } // QByteArray getReturnType( const QMetaObject *obj, const QByteArray &method, const QList<QByteArray> &argTypes )
void listInterface(const QString &service, const QString &path, const QString &interface) { QDBusInterfacePtr iface(*connection, service, path, interface); if (!iface->isValid()) { QDBusError err(iface->lastError()); fprintf(stderr, "Interface '%s' not available in object %s at %s:\n%s (%s)\n", qPrintable(interface), qPrintable(path), qPrintable(service), qPrintable(err.name()), qPrintable(err.message())); exit(1); } const QMetaObject *mo = iface->metaObject(); // properties for (int i = mo->propertyOffset(); i < mo->propertyCount(); ++i) { QMetaProperty mp = mo->property(i); printf("property "); if (mp.isReadable() && mp.isWritable()) printf("readwrite"); else if (mp.isReadable()) printf("read"); else printf("write"); printf(" %s %s.%s\n", mp.typeName(), qPrintable(interface), mp.name()); } // methods (signals and slots) for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) { QMetaMethod mm = mo->method(i); QByteArray signature = mm.signature(); signature.truncate(signature.indexOf('(')); printf("%s %s%s%s %s.%s(", mm.methodType() == QMetaMethod::Signal ? "signal" : "method", mm.tag(), *mm.tag() ? " " : "", *mm.typeName() ? mm.typeName() : "void", qPrintable(interface), signature.constData()); QList<QByteArray> types = mm.parameterTypes(); QList<QByteArray> names = mm.parameterNames(); bool first = true; for (int i = 0; i < types.count(); ++i) { printf("%s%s", first ? "" : ", ", types.at(i).constData()); if (!names.at(i).isEmpty()) printf(" %s", names.at(i).constData()); first = false; } printf(")\n"); } }
/*! Function for executing a slot that does not take parameters */ QString ObjectService::doCallMethod(TasCommand* command, QObject* target, QString& errorString) { Q_ASSERT(command->name() == "CallMethod"); QString methodName = command->parameter("method_name"); TasLogger::logger()->debug("name: " + methodName); int methodId = target->metaObject()->indexOfMethod( QMetaObject::normalizedSignature(methodName.toLatin1()).constData()); if (methodId == -1){ errorString.append(methodName + " method not found on object. "); TasLogger::logger()->debug("...method not found on object"); } else{ QMetaMethod metaMethod = target->metaObject()->method(methodId); QVariantList args = parseArguments(command); QList<QGenericArgument> arguments; for (int i = 0; i < args.size(); i++) { QVariant& argument = args[i]; QGenericArgument genericArgument( QMetaType::typeName(argument.userType()), const_cast<void*>(argument.constData())); arguments << genericArgument; } QVariant returnValue(QMetaType::type(metaMethod.typeName()), static_cast<void*>(NULL)); QGenericReturnArgument returnArgument( metaMethod.typeName(), const_cast<void*>(returnValue.constData())); if (!metaMethod.invoke( target, Qt::AutoConnection, // In case the object is in another thread. returnArgument, arguments.value(0), arguments.value(1), arguments.value(2), arguments.value(3), arguments.value(4), arguments.value(5), arguments.value(6), arguments.value(7), arguments.value(8), arguments.value(9))) { errorString.append(methodName + " method invocation failed! "); } else { return returnValue.toString(); } } return QString(""); }
// based on https://gist.github.com/andref/2838534. bool JsonRpcServer::doCall(QObject* object, const QMetaMethod& meta_method, QVariantList& converted_args, QVariant& return_value) { QList<QGenericArgument> arguments; for (int i = 0; i < converted_args.size(); i++) { // Notice that we have to take a reference to the argument, else we'd be // pointing to a copy that will be destroyed when this loop exits. QVariant& argument = converted_args[i]; // A const_cast is needed because calling data() would detach the // QVariant. QGenericArgument generic_argument( QMetaType::typeName(argument.userType()), const_cast<void*>(argument.constData()) ); arguments << generic_argument; } const char* return_type_name = meta_method.typeName(); int return_type = QMetaType::type(return_type_name); if (return_type != QMetaType::Void) { return_value = QVariant(return_type, nullptr); } QGenericReturnArgument return_argument( return_type_name, const_cast<void*>(return_value.constData()) ); // perform the call bool ok = meta_method.invoke( object, Qt::DirectConnection, return_argument, arguments.value(0), arguments.value(1), arguments.value(2), arguments.value(3), arguments.value(4), arguments.value(5), arguments.value(6), arguments.value(7), arguments.value(8), arguments.value(9) ); if (!ok) { // qDebug() << "calling" << meta_method.methodSignature() << "failed."; return false; } logInfo(logInvoke(meta_method, converted_args, return_value)); return true; }
QSObject QSAEditor::queryQSObject( const QMetaObject *meta, const QString &property, bool /*includeSuperClass*/ ) const { int propertyIndex = -1; const QMetaObject *m = meta; propertyIndex = m->indexOfProperty(property.toLatin1().constData()); if (propertyIndex >= 0) { QMetaProperty mp = m->property(propertyIndex); QSObject o = vTypeToQSType( QString::fromLatin1(mp.typeName()) ); if ( !o.isNull() && !o.isUndefined() ) return o; } m = meta; for (int i=0; i<m->methodCount(); ++i) { QMetaMethod mm = m->method(i); if (mm.methodType() == QMetaMethod::Slot) { QString n = QLatin1String(mm.methodSignature()); n = n.left(n.indexOf('(')); if ( property != n ) continue; return vTypeToQSType(mm.typeName()); } } return env()->createUndefined(); }
const QMetaObject *QSAEditor::queryQMetaObject( const QMetaObject *meta, const QString &property, bool /*includeSuperClass*/ ) const { const QMetaObject *m = meta; for (int i=0; i<m->methodCount(); ++i) { QMetaMethod mm = m->method(i); if (mm.methodType() == QMetaMethod::Slot) { QString n = QLatin1String(mm.methodSignature()); n = n.left(n.indexOf('(')); if (property != n) continue ; QByteArray retType(mm.typeName()); if (retType.count('*') == 1) { extern const QMetaObject *qsa_query_meta_object(const QByteArray &name); return qsa_query_meta_object(qsa_strip_stars(retType)); } } } return 0; }
extern "C" SEXP qt_qmocMethods(SEXP x) { const QMetaObject *meta = unwrapSmoke(x, QMetaObject); int n = meta->methodCount(); SEXP ans, ans_type, ans_signature, ans_return, ans_nargs; PROTECT(ans = allocVector(VECSXP, 4)); ans_type = allocVector(INTSXP, n); SET_VECTOR_ELT(ans, 0, ans_type); ans_signature = allocVector(STRSXP, n); SET_VECTOR_ELT(ans, 1, ans_signature); ans_return = allocVector(STRSXP, n); SET_VECTOR_ELT(ans, 2, ans_return); ans_nargs = allocVector(INTSXP, n); SET_VECTOR_ELT(ans, 3, ans_nargs); for (int i = 0; i < n; i++) { QMetaMethod metaMethod = meta->method(i); INTEGER(ans_type)[i] = metaMethod.methodType(); SET_STRING_ELT(ans_signature, i, mkChar(metaMethod.signature())); SET_STRING_ELT(ans_return, i, mkChar(metaMethod.typeName())); INTEGER(ans_nargs)[i] = metaMethod.parameterNames().size(); } UNPROTECT(1); return ans; }
void QDeclarativePropertyCache::Data::lazyLoad(const QMetaMethod &m) { coreIndex = m.methodIndex(); relatedIndex = -1; flags |= Data::IsFunction; if (m.methodType() == QMetaMethod::Signal) flags |= Data::IsSignal; propType = QVariant::Invalid; const char *returnType = m.typeName(); if (returnType && *returnType) { propTypeName = returnType; flags |= Data::NotFullyResolved; } const char *signature = m.signature(); while (*signature != '(') { Q_ASSERT(*signature != 0); ++signature; } ++signature; if (*signature != ')') { flags |= Data::HasArguments; if (0 == ::strcmp(signature, "QDeclarativeV8Function*)")) { flags |= Data::IsV8Function; } } revision = m.revision(); }
void InvokeMethod::on_comboMethods_activated(const QString &method) { if (!activex) return; listParameters->clear(); const QMetaObject *mo = activex->metaObject(); const QMetaMethod slot = mo->method(mo->indexOfSlot(method.toLatin1())); QString signature = QString::fromLatin1(slot.signature()); signature = signature.mid(signature.indexOf(QLatin1Char('(')) + 1); signature.truncate(signature.length()-1); QList<QByteArray> pnames = slot.parameterNames(); QList<QByteArray> ptypes = slot.parameterTypes(); for (int p = 0; p < ptypes.count(); ++p) { QString ptype(QString::fromLatin1(ptypes.at(p))); if (ptype.isEmpty()) continue; QString pname(QString::fromLatin1(pnames.at(p).constData())); if (pname.isEmpty()) pname = QString::fromLatin1("<unnamed %1>").arg(p); QTreeWidgetItem *item = new QTreeWidgetItem(listParameters); item->setText(0, pname); item->setText(1, ptype); } if (listParameters->topLevelItemCount()) listParameters->setCurrentItem(listParameters->topLevelItem(0)); editReturn->setText(QString::fromLatin1(slot.typeName())); }
JSValue QtInstance::stringValue(ExecState* exec) const { QObject* obj = getObject(); if (!obj) return jsNull(); // Hmm.. see if there is a toString defined QByteArray buf; bool useDefault = true; getClass(); if (m_class) { // Cheat and don't use the full name resolution int index = obj->metaObject()->indexOfMethod("toString()"); if (index >= 0) { QMetaMethod m = obj->metaObject()->method(index); // Check to see how much we can call it if (m.access() != QMetaMethod::Private && m.methodType() != QMetaMethod::Signal #if HAVE(QT5) && m.parameterCount() == 0 && m.returnType() != QMetaType::Void) { QVariant ret(m.returnType(), (void*)0); void * qargs[1]; qargs[0] = ret.data(); if (QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, index, qargs) < 0) { if (ret.isValid() && ret.canConvert(QVariant::String)) { buf = ret.toString().toLatin1().constData(); // ### Latin 1? Ascii? useDefault = false; #else && m.parameterTypes().isEmpty()) { const char* retsig = m.typeName(); if (retsig && *retsig) { QVariant ret(QMetaType::type(retsig), (void*)0); void * qargs[1]; qargs[0] = ret.data(); if (QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, index, qargs) < 0) { if (ret.isValid() && ret.canConvert(QVariant::String)) { buf = ret.toString().toLatin1().constData(); // ### Latin 1? Ascii? useDefault = false; } #endif } } } } } if (useDefault) { const QMetaObject* meta = obj ? obj->metaObject() : &QObject::staticMetaObject; QString name = obj ? obj->objectName() : QString::fromUtf8("unnamed"); QString str = QString::fromUtf8("%0(name = \"%1\")") .arg(QLatin1String(meta->className())).arg(name); buf = str.toLatin1(); } return jsString(exec, buf.constData()); }
PythonQtMethodInfo::PythonQtMethodInfo(const QMetaMethod& meta, PythonQtClassInfo* classInfo) { #ifdef PYTHONQT_DEBUG QByteArray sig(meta.signature()); sig = sig.mid(sig.indexOf('(')); QByteArray fullSig = QByteArray(meta.typeName()) + " " + sig; std::cout << "caching " << fullSig.data() << std::endl; #endif ParameterInfo type; fillParameterInfo(type, QByteArray(meta.typeName()), classInfo); _parameters.append(type); QList<QByteArray> names = meta.parameterTypes(); foreach (const QByteArray& name, names) { fillParameterInfo(type, name, classInfo); _parameters.append(type); }
QString QbMySQLMappingHelper::getStringValue(QbPersistable &object, QMetaMethod method) { QString returnValue = ""; QString typeName = method.typeName(); if(!typeName.compare("int", Qt::CaseInsensitive)) { int memberValue; QMetaObject::invokeMethod(&object, method.name(), Q_RETURN_ARG(int, memberValue)); returnValue = QString::number(memberValue); }
int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv) { Q_Q(QDBusInterface); if (c == QMetaObject::InvokeMetaMethod) { int offset = metaObject->methodOffset(); QMetaMethod mm = metaObject->method(id + offset); if (mm.methodType() == QMetaMethod::Signal) { // signal relay from D-Bus world to Qt world QMetaObject::activate(q, metaObject, id, argv); } else if (mm.methodType() == QMetaMethod::Slot || mm.methodType() == QMetaMethod::Method) { // method call relay from Qt world to D-Bus world // get D-Bus equivalent signature QString methodName = QLatin1String(metaObject->dbusNameForMethod(id)); const int *inputTypes = metaObject->inputTypesForMethod(id); int inputTypesCount = *inputTypes; // we will assume that the input arguments were passed correctly QVariantList args; int i = 1; for ( ; i <= inputTypesCount; ++i) args << QVariant(inputTypes[i], argv[i]); // make the call QDBusMessage reply = q->callWithArgumentList(QDBus::Block, methodName, args); if (reply.type() == QDBusMessage::ReplyMessage) { // attempt to demarshall the return values args = reply.arguments(); QVariantList::ConstIterator it = args.constBegin(); const int *outputTypes = metaObject->outputTypesForMethod(id); int outputTypesCount = *outputTypes++; if (*mm.typeName()) { // this method has a return type if (argv[0] && it != args.constEnd()) copyArgument(argv[0], *outputTypes++, *it); // skip this argument even if we didn't copy it --outputTypesCount; ++it; } for (int j = 0; j < outputTypesCount && it != args.constEnd(); ++i, ++j, ++it) { copyArgument(argv[i], outputTypes[j], *it); } } // done lastError = reply; return -1; } } return id; }
QVariantMap SyncableObject::toVariantMap() { QVariantMap properties; const QMetaObject *meta = metaObject(); // we collect data from properties QMetaProperty prop; QString propName; for (int i = 0; i < meta->propertyCount(); i++) { prop = meta->property(i); propName = QString(prop.name()); if (propName == "objectName") continue; properties[propName] = prop.read(this); } // ...as well as methods, which have names starting with "init" for (int i = 0; i < meta->methodCount(); i++) { QMetaMethod method = meta->method(i); QString methodname(SignalProxy::ExtendedMetaObject::methodName(method)); if (!methodname.startsWith("init") || methodname.startsWith("initSet") || methodname.startsWith("initDone")) continue; QVariant::Type variantType = QVariant::nameToType(method.typeName()); if (variantType == QVariant::Invalid && !QByteArray(method.typeName()).isEmpty()) { #if QT_VERSION >= 0x050000 qWarning() << "SyncableObject::toVariantMap(): cannot fetch init data for:" << this << method.methodSignature() << "- Returntype is unknown to Qt's MetaSystem:" << QByteArray(method.typeName()); #else qWarning() << "SyncableObject::toVariantMap(): cannot fetch init data for:" << this << method.signature() << "- Returntype is unknown to Qt's MetaSystem:" << QByteArray(method.typeName()); #endif continue; } QVariant value(variantType, (const void *)0); QGenericReturnArgument genericvalue = QGenericReturnArgument(method.typeName(), value.data()); QMetaObject::invokeMethod(this, methodname.toLatin1(), genericvalue); properties[SignalProxy::ExtendedMetaObject::methodBaseName(method)] = value; } return properties; }
factory_method::factory_method(type result_type, QMetaMethod meta_method) : _object_type{meta_method.enclosingMetaObject()}, _result_type{std::move(result_type)}, _meta_method{std::move(meta_method)} { assert(meta_method.methodType() == QMetaMethod::Method || meta_method.methodType() == QMetaMethod::Slot); assert(meta_method.parameterCount() == 0); assert(meta_method.enclosingMetaObject() != nullptr); assert(!_result_type.is_empty()); assert(_result_type.name() + "*" == std::string{meta_method.typeName()}); }
static bool NPClass_Invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args, uint32 argCount, NPVariant *result) { NPClass_Prolog; const QByteArray slotName = NPN_UTF8FromIdentifier(name); int slotIndex = publicMethodIndex(npobj, slotName, static_cast<int>(argCount)); if (slotIndex == -1) { NPN_SetException(npobj, QByteArray("No method '" + slotName + "' with " + QByteArray::number(argCount) + " parameters").constData()); return false; } const QMetaMethod slot = qobject->metaObject()->method(slotIndex); QList<QByteArray> parameterTypes = slot.parameterTypes(); if (parameterTypes.count() != static_cast<int>(argCount)) { NPN_SetException(npobj, QByteArray("Wrong parameter count for method " + slotName).constData()); return false; } QVariant returnVariant(QVariant::nameToType(slot.typeName()), (void*)0); QVector<QVariant> variants(parameterTypes.count()); // keep data alive QVector<const void*> metacallArgs(parameterTypes.count() + 1); // arguments for qt_metacall metacallArgs[0] = returnVariant.data(); // args[0] == return value for (int p = 0; p < parameterTypes.count(); ++p) { QVariant::Type type = QVariant::nameToType(parameterTypes.at(p)); if (type == QVariant::Invalid && parameterTypes.at(p) != "QVariant") { NPN_SetException(npobj, QString("Parameter %1 in method '%2' has invalid type") .arg(p).arg(QString::fromUtf8(slotName)).toAscii().constData()); return false; } QVariant qvar = args[p]; if (type != QVariant::Invalid && !qvar.convert(type)) { NPN_SetException(npobj, QString("Parameter %1 to method '%2' needs to be convertable to '%3'") .arg(p).arg(QString::fromUtf8(slotName)).arg(QString::fromAscii(parameterTypes.at(p))).toAscii().constData()); return false; } variants[p] = qvar; if (type == QVariant::Invalid) metacallArgs[p + 1] = &variants.at(p); else metacallArgs[p + 1] = variants.at(p).constData(); // must not detach! } qobject->qt_metacall(QMetaObject::InvokeMetaMethod, slotIndex, const_cast<void**>(metacallArgs.data())); if (returnVariant.isValid() && result) *result = NPVariant::fromQVariant(This, returnVariant); return true; }
static bool NPClass_Invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args, uint32 argCount, NPVariant *result) { NPClass_Prolog; int slotIndex = publicMethodIndex(npobj, name); if (slotIndex == -1) { QByteArray qname = NPN_UTF8FromIdentifier(name); NPN_SetException(npobj, QByteArray("No such method " + qname).constData()); return false; } const QMetaMethod slot = qobject->metaObject()->method(slotIndex); QList<QByteArray> parameterTypes = slot.parameterTypes(); if (parameterTypes.count() != static_cast<int>(argCount)) { QByteArray qname = NPN_UTF8FromIdentifier(name); NPN_SetException(npobj, QByteArray("Wrong parameter count for method " + qname).constData()); return false; } QVariant returnVariant(QVariant::nameToType(slot.typeName()), (void *)0); QVector<QVariant> variants(parameterTypes.count()); // keep data alive QVector<const void *> metacallArgs(parameterTypes.count() + 1); // arguments for qt_metacall metacallArgs[0] = returnVariant.data(); // args[0] == return value for (int p = 0; p < parameterTypes.count(); ++p) { QVariant::Type type = QVariant::nameToType(parameterTypes.at(p)); if (type == QVariant::Invalid) { QByteArray qname = NPN_UTF8FromIdentifier(name); NPN_SetException(npobj, QByteArray("Unsupported parameter in method " + qname).constData()); return false; } QVariant qvar = args[p]; if (!qvar.convert(type)) { QByteArray qname = NPN_UTF8FromIdentifier(name); NPN_SetException(npobj, QByteArray("Unsupported parameter value in method " + qname).constData()); return false; } variants[p] = qvar; metacallArgs[p + 1] = variants.at(p).constData(); // must not detach! } qobject->qt_metacall(QMetaObject::InvokeMetaMethod, slotIndex, const_cast<void * *>(metacallArgs.data())); if (returnVariant.isValid() && result) *result = NPVariant::fromQVariant(This, returnVariant); return true; }
static void getSlots( const QMetaObject *meta, QList<Property> &result, bool super, bool withArgs, bool sigs ) { while (meta) { int nmethods = meta->methodCount(); for (int i=0; i<nmethods; ++i) { const QMetaMethod m = meta->method(i); if (m.access() == QMetaMethod::Private) continue ; if ((m.methodType() == QMetaMethod::Slot && !sigs) || (m.methodType() == QMetaMethod::Signal && sigs)) { Property prop; QString s = QLatin1String( m.methodSignature() ); s = s.left(s.indexOf('(')); QList<QByteArray> parameterTypes = m.parameterTypes(); QList<QByteArray> parameterNames = m.parameterNames(); prop.type = m.typeName(); QuickInterpreter::cleanType(prop.type); if ( withArgs ) { s += QLatin1String("("); for ( int j = 0; j < parameterTypes.count(); ++j ) { s += parameterTypes.at(j); s += QLatin1String(" "); s += QString::fromLatin1(parameterNames.at(j)); if ( j < parameterTypes.count() - 1 ) s += QString::fromLatin1(","); } s += QString::fromLatin1(")"); } prop.name = s; if (result.indexOf(prop) == -1) result << prop; } } if (super) meta = meta->superClass(); else meta = 0; } }
void QDeclarativePropertyCache::Data::load(const QMetaMethod &m) { coreIndex = m.methodIndex(); relatedIndex = -1; flags |= Data::IsFunction; if (m.methodType() == QMetaMethod::Signal) flags |= Data::IsSignal; propType = QVariant::Invalid; const char *returnType = m.typeName(); if (returnType) propType = QMetaType::type(returnType); QList<QByteArray> params = m.parameterTypes(); if (!params.isEmpty()) flags |= Data::HasArguments; revision = m.revision(); }
QByteArray MaiaXmlRpcServerConnection::getReturnType(const QMetaObject *obj, const QByteArray &method, const QList<QByteArray> argTypes) { for(int n = 0; n < obj->methodCount(); ++n) { QMetaMethod m = obj->method(n); QByteArray sig = m.signature(); int offset = sig.indexOf('('); if(offset == -1) continue; QByteArray name = sig.mid(0, offset); if(name != method) continue; if(m.parameterTypes() != argTypes) continue; return m.typeName(); } return QByteArray(); }
void tst_QQmlMetaObject::method() { QFETCH(QString, testFile); QFETCH(QString, signature); QFETCH(QMetaMethod::MethodType, methodType); QFETCH(int, returnType); QFETCH(QString, returnTypeName); QFETCH(QList<int>, parameterTypes); QFETCH(QList<QByteArray>, parameterTypeNames); QFETCH(QList<QByteArray>, parameterNames); QCOMPARE(parameterTypes.size(), parameterTypeNames.size()); QCOMPARE(parameterTypeNames.size(), parameterNames.size()); QQmlEngine engine; QQmlComponent component(&engine, testFileUrl(testFile)); QObject *object = component.create(); QVERIFY(object != 0); const QMetaObject *mo = object->metaObject(); QVERIFY(mo->superClass() != 0); QVERIFY(QByteArray(mo->className()).contains("_QML_")); QCOMPARE(mo->methodOffset(), mo->superClass()->methodCount()); QCOMPARE(mo->methodCount(), mo->superClass()->methodCount() + 1); QMetaMethod method = mo->method(mo->methodOffset()); QCOMPARE(method.methodType(), methodType); QCOMPARE(QString::fromUtf8(method.methodSignature().constData()), signature); QCOMPARE(method.access(), QMetaMethod::Public); QString computedName = signature.left(signature.indexOf('(')); QCOMPARE(QString::fromUtf8(method.name()), computedName); QCOMPARE(method.parameterCount(), parameterTypes.size()); for (int i = 0; i < parameterTypes.size(); ++i) QCOMPARE(method.parameterType(i), parameterTypes.at(i)); QCOMPARE(method.parameterTypes(), parameterTypeNames); QCOMPARE(method.tag(), ""); QCOMPARE(QString::fromUtf8(method.typeName()), returnTypeName); QCOMPARE(method.returnType(), returnType); delete object; }
void QxtWebJsonRPCService::Private::initTables(QObject *in) { invokable = in; const QMetaObject *po = invokable->metaObject(); for (int i = po->methodOffset(); i < po->methodCount(); i++) { QxtWebJsonRPCService::Private::Method method; QMetaMethod mo = po->method (i); #if QT_VERSION >= 0x50000 method.name = QByteArray(mo.methodSignature()).split('(').at(0); #else method.name = QByteArray(mo.signature()).split('(').at(0); #endif method.meta = mo; method.argCount = mo.parameterTypes ().count(); method.returns = QByteArray(mo.typeName()).count(); methods.insert(method.name + QByteArray::number(method.argCount), method); } }
/*! Create a slot invoker that can invoke \a member on \a receiver. The object will be attached to \a parent, if present. \since 1.1 */ QSlotInvoker::QSlotInvoker( QObject *receiver, const QByteArray &member, QObject *parent ) : QObject( parent ) { d = new QSlotInvokerPrivate(); d->receiver = receiver; QByteArray name; if ( member.size() > 0 && member[0] >= '0' && member[0] <= '9' ) { // Strip off the member type code. name = member.mid(1); } else { name = member; } name = QMetaObject::normalizedSignature( name.constData() ); d->member = name; d->destroyed = false; d->returnType = 0; d->types = 0; d->numArgs = 0; if ( receiver && name.size() > 0 ) { d->memberIndex = receiver->metaObject()->indexOfMethod( name.constData() ); } else { d->memberIndex = -1; } if ( d->memberIndex != -1 ) { QMetaMethod method = receiver->metaObject()->method ( d->memberIndex ); { connect( receiver, SIGNAL(destroyed()), this, SLOT(receiverDestroyed()) ); d->returnType = QSignalIntercepter::typeFromName( method.typeName() ); d->types = QSignalIntercepter::connectionTypes ( name, d->numArgs ); if ( !( d->types ) ) d->destroyed = true; } } else { d->destroyed = true; } }
QString Util::prettyMethodSignature(const QMetaMethod& method) { #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) return method.signature(); #else QString signature = method.typeName(); signature += ' ' + method.name() + '('; QStringList args; args.reserve(method.parameterCount()); const QList<QByteArray> paramTypes = method.parameterTypes(); const QList<QByteArray> paramNames = method.parameterNames(); for (int i = 0; i < method.parameterCount(); ++i) { QString arg = paramTypes.at(i); if (!paramNames.at(i).isEmpty()) arg += ' ' + paramNames.at(i); args.push_back(arg); } signature += args.join(QStringLiteral(", ")) + ')'; return signature; #endif }
MethodParameters(int Index, const QMetaMethod &Method, int AllowedRequestTypes, const QString &ReturnType) : m_valid(false), m_index(Index), m_allowedRequestTypes(AllowedRequestTypes), m_returnType(ReturnType) { // statically initialise the list of unsupported types (either non-serialisable (QHash) // or nonsensical (pointer types) static QList<int> unsupportedtypes; static QList<int> unsupportedparameters; static bool initialised = false; if (!initialised) { // this list is probably incomplete initialised = true; unsupportedtypes << QMetaType::UnknownType; unsupportedtypes << QMetaType::VoidStar << QMetaType::QObjectStar << QMetaType::QVariantHash; unsupportedtypes << QMetaType::QRect << QMetaType::QRectF << QMetaType::QSize << QMetaType::QSizeF << QMetaType::QLine << QMetaType::QLineF << QMetaType::QPoint << QMetaType::QPointF; unsupportedparameters << unsupportedtypes; unsupportedparameters << QMetaType::QVariantMap << QMetaType::QStringList << QMetaType::QVariantList; } // the return type/value is first int returntype = QMetaType::type(Method.typeName()); // discard slots with an unsupported return type if (unsupportedtypes.contains(returntype)) { LOG(VB_GENERAL, LOG_ERR, QString("Method '%1' has unsupported return type '%2'").arg(Method.name().data()).arg(Method.typeName())); return; } // discard overly complicated slots not supported by QMetaMethod if (Method.parameterCount() > 10) { LOG(VB_GENERAL, LOG_ERR, QString("Method '%1' takes more than 10 parameters - ignoring").arg(Method.name().data())); return; } m_types.append(returntype > 0 ? returntype : 0); m_names.append(Method.name()); QList<QByteArray> names = Method.parameterNames(); QList<QByteArray> types = Method.parameterTypes(); // add type/value for each method parameter for (int i = 0; i < names.size(); ++i) { int type = QMetaType::type(types[i]); // discard slots that use unsupported parameter types if (unsupportedparameters.contains(type)) { LOG(VB_GENERAL, LOG_ERR, QString("Method '%1' has unsupported parameter type '%2'") .arg(Method.name().data()).arg(types[i].data())); return; } m_names.append(names[i]); m_types.append(type); } m_valid = true; }
void tst_QMetaMethod::method() { QFETCH(QByteArray, signature); QFETCH(int, returnType); QFETCH(QByteArray, returnTypeName); QFETCH(QList<int>, parameterTypes); QFETCH(QList<QByteArray>, parameterTypeNames); QFETCH(QList<QByteArray>, parameterNames); QFETCH(QMetaMethod::MethodType, methodType); QFETCH(QMetaMethod::Access, access); QVERIFY(parameterTypes.size() == parameterTypeNames.size()); QVERIFY(parameterTypes.size() == parameterNames.size()); const QMetaObject *mo = &MethodTestObject::staticMetaObject; int index = (methodType == QMetaMethod::Constructor) ? mo->indexOfConstructor(signature) : mo->indexOfMethod(signature); QVERIFY(index != -1); QMetaMethod method = (methodType == QMetaMethod::Constructor) ? mo->constructor(index) : mo->method(index); QVERIFY(method.isValid()); QCOMPARE(method.methodType(), methodType); QCOMPARE(method.access(), access); QVERIFY(!method.methodSignature().isEmpty()); if (method.methodSignature() != signature) { // QMetaMethod should always produce a semantically equivalent signature int signatureIndex = (methodType == QMetaMethod::Constructor) ? mo->indexOfConstructor(method.methodSignature()) : mo->indexOfMethod(method.methodSignature()); QCOMPARE(signatureIndex, index); } QByteArray computedName = signature.left(signature.indexOf('(')); QCOMPARE(method.name(), computedName); QCOMPARE(method.tag(), ""); QCOMPARE(method.returnType(), returnType); QVERIFY(method.typeName() != 0); if (QByteArray(method.typeName()) != returnTypeName) { // QMetaMethod should always produce a semantically equivalent typename QCOMPARE(QMetaType::type(method.typeName()), QMetaType::type(returnTypeName)); } if (method.parameterTypes() != parameterTypeNames) { // QMetaMethod should always produce semantically equivalent typenames QList<QByteArray> actualTypeNames = method.parameterTypes(); QCOMPARE(actualTypeNames.size(), parameterTypeNames.size()); for (int i = 0; i < parameterTypeNames.size(); ++i) { QCOMPARE(QMetaType::type(actualTypeNames.at(i)), QMetaType::type(parameterTypeNames.at(i))); } } QCOMPARE(method.parameterNames(), parameterNames); QCOMPARE(method.parameterCount(), parameterTypes.size()); for (int i = 0; i < parameterTypes.size(); ++i) QCOMPARE(method.parameterType(i), parameterTypes.at(i)); { QVector<int> actualParameterTypes(parameterTypes.size()); method.getParameterTypes(actualParameterTypes.data()); for (int i = 0; i < parameterTypes.size(); ++i) QCOMPARE(actualParameterTypes.at(i), parameterTypes.at(i)); } // Bogus indexes QCOMPARE(method.parameterType(-1), 0); QCOMPARE(method.parameterType(parameterTypes.size()), 0); }
bool QObjectProxy::invokeMethod( const char *method, PyrSlot *retSlot, PyrSlot *argSlot, Qt::ConnectionType ctype ) { mutex.lock(); if( !qObject ) { mutex.unlock(); return true; } // the signature char array QVarLengthArray<char, 512> sig; // serialize method name int len = qstrlen( method ); if( len <= 0 ) { mutex.unlock(); return false; } sig.append( method, len ); sig.append( '(' ); // get data from argument slots QtCollider::Variant argSlots[10]; if( isKindOfSlot( argSlot, class_Array ) ) { PyrSlot *slots = slotRawObject( argSlot )->slots; int size = slotRawObject( argSlot )->size; int i; for( i = 0; i<size && i<10; ++i ) { argSlots[i].setData( slots ); ++slots; } } else argSlots[0].setData( argSlot ); // serialize argument types int i; for( i = 0; i < 10; ++i ) { int type = argSlots[i].type(); if( type == QMetaType::Void ) break; const char *typeName = QMetaType::typeName( type ); int len = qstrlen( typeName ); if( len <= 0 ) break; sig.append( typeName, len ); sig.append( ',' ); } // finalize the signature if( i==0 ) sig.append( ')' ); else sig[sig.size() - 1] = ')'; sig.append('\0'); // get the meta method const QMetaObject *mo = qObject->metaObject(); int mi = mo->indexOfMethod( sig.constData() ); if( mi < 0 ) { QByteArray mnorm = QMetaObject::normalizedSignature( sig.constData() ); mi = mo->indexOfMethod( mnorm.constData() ); } if( mi < 0 || mi >= mo->methodCount() ) { qcProxyDebugMsg( 1, QString("WARNING: No such method: %1::%2").arg( mo->className() ) .arg( sig.constData() ) ); mutex.unlock(); return false; } QMetaMethod mm = mo->method( mi ); // construct the return data object QGenericReturnArgument retGArg; const char *retTypeName = mm.typeName(); int retType = QMetaType::type( retTypeName ); void *retPtr = 0; if( retSlot ) { retPtr = QMetaType::construct( retType ); retGArg = QGenericReturnArgument( retTypeName, retPtr ); } //do it! bool success = mm.invoke( qObject, ctype, retGArg, argSlots[0].asGenericArgument(), argSlots[1].asGenericArgument(), argSlots[2].asGenericArgument(), argSlots[3].asGenericArgument(), argSlots[4].asGenericArgument(), argSlots[5].asGenericArgument(), argSlots[6].asGenericArgument(), argSlots[7].asGenericArgument(), argSlots[8].asGenericArgument(), argSlots[9].asGenericArgument()); // store the return data into the return slot if( success && retPtr ) { QVariant retVar( retType, retPtr ); Slot::setVariant( retSlot, retVar ); }; if( retPtr ) QMetaType::destroy( retType, retPtr ); mutex.unlock(); return success; }
// The type call slot. static PyObject *pyqtMethodProxy_call(PyObject *self, PyObject *args, PyObject *kw_args) { qpycore_pyqtMethodProxy *mp = (qpycore_pyqtMethodProxy *)self; const char *py_name = mp->py_name->constData(); // Check for keyword arguments. if (kw_args) { PyErr_Format(PyExc_TypeError, "%s() does not support keyword arguments", py_name); return 0; } QMetaMethod method = mp->qobject->metaObject()->method(mp->method_index); QList<QByteArray> arg_types = method.parameterTypes(); if (PyTuple_Size(args) != arg_types.size()) { PyErr_Format(PyExc_TypeError, "%s() called with %zd arguments but %d expected", py_name, PyTuple_Size(args), arg_types.size()); return 0; } // Parse the return type and the arguments. QGenericReturnArgument ret; QGenericArgument a0, a1, a2, a3, a4, a5, a6, a7, a8, a9; Chimera::Storage *return_storage, *storage[10]; QByteArray return_type(method.typeName()); bool failed = false; return_storage = 0; if (!return_type.isEmpty()) { const Chimera *ct = Chimera::parse(return_type); if (!ct) { PyErr_Format(PyExc_TypeError, "unable to convert return value of %s from '%s' to a Python object", py_name, return_type.constData()); return 0; } return_storage = ct->storageFactory(); ret = QGenericReturnArgument(return_type.constData(), return_storage->address()); } parse_arg(args, 0, arg_types, a0, storage, failed, py_name); parse_arg(args, 1, arg_types, a1, storage, failed, py_name); parse_arg(args, 2, arg_types, a2, storage, failed, py_name); parse_arg(args, 3, arg_types, a3, storage, failed, py_name); parse_arg(args, 4, arg_types, a4, storage, failed, py_name); parse_arg(args, 5, arg_types, a5, storage, failed, py_name); parse_arg(args, 6, arg_types, a6, storage, failed, py_name); parse_arg(args, 7, arg_types, a7, storage, failed, py_name); parse_arg(args, 8, arg_types, a8, storage, failed, py_name); parse_arg(args, 9, arg_types, a9, storage, failed, py_name); // Invoke the method. PyObject *result = 0; if (!failed) { failed = !method.invoke(mp->qobject, ret, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); if (failed) { PyErr_Format(PyExc_TypeError, "invocation of %s() failed", py_name); } else if (return_storage) { result = return_storage->toPyObject(); } else { result = Py_None; Py_INCREF(result); } } // Release any storage. if (return_storage) { delete return_storage->type(); delete return_storage; } for (int i = 0; i < 10; ++i) { Chimera::Storage *st = storage[i]; if (st) { delete st->type(); delete st; } } return result; }
/** * \brief Extract the return type of a meta method * * \param metaMethod Qt meta method * * \return Return type of the meta method */ static ponder::Type returnType(const QMetaMethod& metaMethod) { return QtHelper::type(metaMethod.typeName()); }
static QString generateInterfaceXml(const QMetaObject *mo, int flags, int methodOffset, int propOffset) { QString retval; // start with properties: if (flags & (QDBusConnection::ExportScriptableProperties | QDBusConnection::ExportNonScriptableProperties)) { for (int i = propOffset; i < mo->propertyCount(); ++i) { static const char *accessvalues[] = {0, "read", "write", "readwrite"}; QMetaProperty mp = mo->property(i); if (!((mp.isScriptable() && (flags & QDBusConnection::ExportScriptableProperties)) || (!mp.isScriptable() && (flags & QDBusConnection::ExportNonScriptableProperties)))) continue; int access = 0; if (mp.isReadable()) access |= 1; if (mp.isWritable()) access |= 2; int typeId = qDBusNameToTypeId(mp.typeName()); if (!typeId) continue; const char *signature = QDBusMetaType::typeToSignature(typeId); if (!signature) continue; retval += QString::fromLatin1(" <property name=\"%1\" type=\"%2\" access=\"%3\"") .arg(QLatin1String(mp.name())) .arg(QLatin1String(signature)) .arg(QLatin1String(accessvalues[access])); if (QDBusMetaType::signatureToType(signature) == QVariant::Invalid) { const char *typeName = QVariant::typeToName(QVariant::Type(typeId)); retval += QString::fromLatin1(">\n <annotation name=\"com.trolltech.QtDBus.QtTypeName\" value=\"%3\"/>\n </property>\n") .arg(typeNameToXml(typeName)); } else { retval += QLatin1String("/>\n"); } } } // now add methods: for (int i = methodOffset; i < mo->methodCount(); ++i) { QMetaMethod mm = mo->method(i); QByteArray signature = mm.signature(); int paren = signature.indexOf('('); bool isSignal; if (mm.methodType() == QMetaMethod::Signal) // adding a signal isSignal = true; else if (mm.methodType() == QMetaMethod::Slot && mm.access() == QMetaMethod::Public) isSignal = false; else continue; // neither signal nor public slot if (isSignal && !(flags & (QDBusConnection::ExportScriptableSignals | QDBusConnection::ExportNonScriptableSignals))) continue; // we're not exporting any signals if (!isSignal && !(flags & (QDBusConnection::ExportScriptableSlots | QDBusConnection::ExportNonScriptableSlots))) continue; // we're not exporting any slots QString xml = QString::fromLatin1(" <%1 name=\"%2\">\n") .arg(isSignal ? QLatin1String("signal") : QLatin1String("method")) .arg(QLatin1String(signature.left(paren))); // check the return type first int typeId = qDBusNameToTypeId(mm.typeName()); if (typeId) { const char *typeName = QDBusMetaType::typeToSignature(typeId); if (typeName) { xml += QString::fromLatin1(" <arg type=\"%1\" direction=\"out\"/>\n") .arg(typeNameToXml(typeName)); // do we need to describe this argument? if (QDBusMetaType::signatureToType(typeName) == QVariant::Invalid) xml += QString::fromLatin1(" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"%1\"/>\n") .arg(typeNameToXml(mm.typeName())); } else continue; } else if (*mm.typeName()) continue; // wasn't a valid type QList<QByteArray> names = mm.parameterNames(); QList<int> types; int inputCount = qDBusParametersForMethod(mm, types); if (inputCount == -1) continue; // invalid form if (isSignal && inputCount + 1 != types.count()) continue; // signal with output arguments? if (isSignal && types.at(inputCount) == QDBusMetaTypeId::message) continue; // signal with QDBusMessage argument? if (isSignal && mm.attributes() & QMetaMethod::Cloned) continue; // cloned signal? int j; bool isScriptable = mm.attributes() & QMetaMethod::Scriptable; for (j = 1; j < types.count(); ++j) { // input parameter for a slot or output for a signal if (types.at(j) == QDBusMetaTypeId::message) { isScriptable = true; continue; } QString name; if (!names.at(j - 1).isEmpty()) name = QString::fromLatin1("name=\"%1\" ").arg(QLatin1String(names.at(j - 1))); bool isOutput = isSignal || j > inputCount; const char *signature = QDBusMetaType::typeToSignature(types.at(j)); xml += QString::fromLatin1(" <arg %1type=\"%2\" direction=\"%3\"/>\n") .arg(name) .arg(QLatin1String(signature)) .arg(isOutput ? QLatin1String("out") : QLatin1String("in")); // do we need to describe this argument? if (QDBusMetaType::signatureToType(signature) == QVariant::Invalid) { const char *typeName = QVariant::typeToName( QVariant::Type(types.at(j)) ); xml += QString::fromLatin1(" <annotation name=\"com.trolltech.QtDBus.QtTypeName.%1%2\" value=\"%3\"/>\n") .arg(isOutput ? QLatin1String("Out") : QLatin1String("In")) .arg(isOutput ? j - 1 : j - inputCount) .arg(typeNameToXml(typeName)); } } int wantedMask; if (isScriptable) wantedMask = isSignal ? QDBusConnection::ExportScriptableSignals : QDBusConnection::ExportScriptableSlots; else wantedMask = isSignal ? QDBusConnection::ExportNonScriptableSignals : QDBusConnection::ExportNonScriptableSlots; if ((flags & wantedMask) != wantedMask) continue; if (qDBusCheckAsyncTag(mm.tag())) // add the no-reply annotation xml += QLatin1String(" <annotation name=\"" ANNOTATION_NO_WAIT "\"" " value=\"true\"/>\n"); retval += xml; retval += QString::fromLatin1(" </%1>\n") .arg(isSignal ? QLatin1String("signal") : QLatin1String("method")); } return retval; }