예제 #1
0
void ObjectEndPoint::newPackageReady()
{
    //client and service side
#ifdef QT_SFW_ENDPOINT_DEBUG
    qDebug() << "ObjectEndPoint::newPackageReady: Start ..." ;
#endif 
    
    // The monitor keeps track of this ObjectEndPoint so that it doesn't get deleted while in progress.    
#ifdef Q_OS_SYMBIAN
    ObjectEndPointMonitor aOem(this);
#endif //End Q_OS_SYMBIAN
    while(dispatch->packageAvailable())
    {
        QServicePackage p = dispatch->nextPackage();
        if (!p.isValid())
            continue;

        switch(p.d->packageType) {
            case QServicePackage::ObjectCreation:
                objectRequest(p);
                break;
            case QServicePackage::MethodCall:
                methodCall(p);
                break;
            case QServicePackage::PropertyCall:
                propertyCall(p);
                break;
            default:
                qWarning() << "Unknown package type received.";
        }
    }
#ifdef QT_SFW_ENDPOINT_DEBUG
	qDebug() << "ObjectEndPoint::newPackageReady: End" ;
#endif 
}
예제 #2
0
int QServiceProxy::qt_metacall(QMetaObject::Call c, int id, void **a)
{   
#ifdef  QT_SFW_ENDPOINT_DEBUG
	qDebug() << "QServiceProxy::qt_metacall: Start";
#endif
    id = QObject::qt_metacall(c, id, a);
    if (id < 0 || !d->meta) 
        return id;
    
		//Let the object endpoint monitor keep track of the usage...
#ifdef Q_OS_SYMBIAN
		ObjectEndPointMonitor aOem(d->endPoint);
#endif //End Q_OS_SYMBIAN

    if(localSignals.at(id)){
      QMetaObject::activate(this, d->meta, id, a);
      return id;      
    }

    if (c == QMetaObject::InvokeMetaMethod) {
        const int mcount = d->meta->methodCount() - d->meta->methodOffset();
        const int metaIndex = id + d->meta->methodOffset();

        QMetaMethod method = d->meta->method(metaIndex);

        const int returnType = QMetaType::type(method.typeName());

        //process arguments
        const QList<QByteArray> pTypes = method.parameterTypes();
        const int pTypesCount = pTypes.count();
        QVariantList args ;
        if (pTypesCount > 10) {
            qWarning() << "Cannot call" << method.signature() << ". More than 10 parameter.";
            return id;
        }
        for (int i=0; i < pTypesCount; i++) {
            const QByteArray& t = pTypes[i];

            int variantType = QVariant::nameToType(t);
            if (variantType == QVariant::UserType)
                variantType = QMetaType::type(t);

            if (t == "QVariant") {  //ignore whether QVariant is declared as metatype
                args << *reinterpret_cast<const QVariant(*)>(a[i+1]);
            } else if ( variantType == 0 ){
                qWarning("%s: argument %s has unknown type. Use qRegisterMetaType to register it.",
                        method.signature(), t.data());
                return id;
            } else {
                args << QVariant(variantType, a[i+1]);
            }
        }

        //QVariant looks the same as Void type. we need to distinguish them
        if (returnType == QMetaType::Void && strcmp(method.typeName(),"QVariant") ) {
            d->endPoint->invokeRemote(metaIndex, args, returnType);
        } else {
            //TODO: ugly but works
            //add +1 if we have a variant return type to avoid triggering of void
            //code path
            //invokeRemote() parameter list needs review
            QVariant result = d->endPoint->invokeRemote(metaIndex, args, 
                    returnType==0 ? returnType+1: returnType);
            if(result.type() != QVariant::Invalid){
                if (returnType != 0 && strcmp(method.typeName(),"QVariant")) {
                    QByteArray buffer;
                    QDataStream stream(&buffer, QIODevice::ReadWrite);
                    QMetaType::save(stream, returnType, result.constData());
                    stream.device()->seek(0);
                    QMetaType::load(stream, returnType, a[0]);
                } else {
                    if (a[0]) *reinterpret_cast< QVariant*>(a[0]) = result;
                }
            }
        }
        id-=mcount;
    } else if ( c == QMetaObject::ReadProperty 
            || c == QMetaObject::WriteProperty
            || c == QMetaObject::ResetProperty ) {
        const int pCount = d->meta->propertyCount() - d->meta->propertyOffset();
        const int metaIndex = id + d->meta->propertyOffset();
        QMetaProperty property = d->meta->property(metaIndex);
        if (property.isValid()) {
            int pType = property.type();
            if (pType == QVariant::UserType)
                pType = QMetaType::type(property.typeName());

            QVariant arg;
            if ( c == QMetaObject::WriteProperty ) {
                if (pType == QVariant::Invalid && QByteArray(property.typeName()) == "QVariant")
                    arg =  *reinterpret_cast<const QVariant(*)>(a[0]);
                else if (pType == 0) {
                    qWarning("%s: property %s has unknown type", property.name(), property.typeName());
                    return id;
                } else {
                    arg = QVariant(pType, a[0]);
                }
            }
            QVariant result;
            if (c == QMetaObject::ReadProperty) {
                result = d->endPoint->invokeRemoteProperty(metaIndex, arg, pType, c);
                //wrap result for client
                if (pType != 0) {
                    QByteArray buffer;
                    QDataStream stream(&buffer, QIODevice::ReadWrite);
                    QMetaType::save(stream, pType, result.constData());
                    stream.device()->seek(0);
                    QMetaType::load(stream, pType, a[0]);
                } else {
                    if (a[0]) *reinterpret_cast< QVariant*>(a[0]) = result;
                }
            } else {
                d->endPoint->invokeRemoteProperty(metaIndex, arg, pType, c);
            }
        } 
        id-=pCount;
    } else if ( c == QMetaObject::QueryPropertyDesignable
            || c == QMetaObject::QueryPropertyScriptable
            || c == QMetaObject::QueryPropertyStored
            || c == QMetaObject::QueryPropertyEditable
            || c == QMetaObject::QueryPropertyUser ) 
    {
        //Nothing to do?
        //These values are part of the transferred meta object already
    } else {
        //TODO
        qWarning() << "MetaCall type" << c << "not yet handled";
    }
#ifdef  QT_SFW_ENDPOINT_DEBUG
    qDebug() << "QServiceProxy::qt_metacall: End";
#endif
    return id;
}