예제 #1
0
파일: qdbusmessage.cpp 프로젝트: Afreeca/qt
/*!
    \internal
    Constructs a QDBusMessage by parsing the given DBusMessage object.
*/
QDBusMessage QDBusMessagePrivate::fromDBusMessage(DBusMessage *dmsg, QDBusConnection::ConnectionCapabilities capabilities)
{
    QDBusMessage message;
    if (!dmsg)
        return message;

    message.d_ptr->type = q_dbus_message_get_type(dmsg);
    message.d_ptr->path = QString::fromUtf8(q_dbus_message_get_path(dmsg));
    message.d_ptr->interface = QString::fromUtf8(q_dbus_message_get_interface(dmsg));
    message.d_ptr->name = message.d_ptr->type == DBUS_MESSAGE_TYPE_ERROR ?
                      QString::fromUtf8(q_dbus_message_get_error_name(dmsg)) :
                      QString::fromUtf8(q_dbus_message_get_member(dmsg));
    message.d_ptr->service = QString::fromUtf8(q_dbus_message_get_sender(dmsg));
    message.d_ptr->signature = QString::fromUtf8(q_dbus_message_get_signature(dmsg));
    message.d_ptr->msg = q_dbus_message_ref(dmsg);

    QDBusDemarshaller demarshaller(capabilities);
    demarshaller.message = q_dbus_message_ref(dmsg);
    if (q_dbus_message_iter_init(demarshaller.message, &demarshaller.iterator))
        while (!demarshaller.atEnd())
            message << demarshaller.toVariantInternal();
    return message;
}
예제 #2
0
bool QDBusMarshaller::appendVariantInternal(const QVariant &arg)
{
    int id = arg.userType();
    if (id == QVariant::Invalid) {
        qWarning("QDBusMarshaller: cannot add an invalid QVariant");
        error(QLatin1String("Variant containing QVariant::Invalid passed in arguments"));
        return false;
    }

    // intercept QDBusArgument parameters here
    if (id == QDBusMetaTypeId::argument()) {
        QDBusArgument dbusargument = qvariant_cast<QDBusArgument>(arg);
        QDBusArgumentPrivate *d = QDBusArgumentPrivate::d(dbusargument);
        if (!d->message)
            return false;       // can't append this one...

        QDBusDemarshaller demarshaller(capabilities);
        demarshaller.message = q_dbus_message_ref(d->message);

        if (d->direction == Demarshalling) {
            // it's demarshalling; just copy
            demarshaller.iterator = static_cast<QDBusDemarshaller *>(d)->iterator;
        } else {
            // it's marshalling; start over
            if (!q_dbus_message_iter_init(demarshaller.message, &demarshaller.iterator))
                return false;   // error!
        }

        return appendCrossMarshalling(&demarshaller);
    }

    const char *signature = QDBusMetaType::typeToSignature( QVariant::Type(id) );
    if (!signature) {
        qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. "
                 "Use qDBusRegisterMetaType to register it",
                 QMetaType::typeName(id), id);
        error(QString::fromLatin1("Unregistered type %1 passed in arguments")
              .arg(QLatin1String(QMetaType::typeName(id))));
        return false;
    }

    switch (*signature) {
#ifdef __OPTIMIZE__
    case DBUS_TYPE_BYTE:
    case DBUS_TYPE_INT16:
    case DBUS_TYPE_UINT16:
    case DBUS_TYPE_INT32:
    case DBUS_TYPE_UINT32:
    case DBUS_TYPE_INT64:
    case DBUS_TYPE_UINT64:
    case DBUS_TYPE_DOUBLE:
        qIterAppend(&iterator, ba, *signature, arg.constData());
        return true;
    case DBUS_TYPE_BOOLEAN:
        append( arg.toBool() );
        return true;
#else
    case DBUS_TYPE_BYTE:
        append( qvariant_cast<uchar>(arg) );
        return true;
    case DBUS_TYPE_BOOLEAN:
        append( arg.toBool() );
        return true;
    case DBUS_TYPE_INT16:
        append( qvariant_cast<short>(arg) );
        return true;
    case DBUS_TYPE_UINT16:
        append( qvariant_cast<ushort>(arg) );
        return true;
    case DBUS_TYPE_INT32:
        append( static_cast<dbus_int32_t>(arg.toInt()) );
        return true;
    case DBUS_TYPE_UINT32:
        append( static_cast<dbus_uint32_t>(arg.toUInt()) );
        return true;
    case DBUS_TYPE_INT64:
        append( arg.toLongLong() );
        return true;
    case DBUS_TYPE_UINT64:
        append( arg.toULongLong() );
        return true;
    case DBUS_TYPE_DOUBLE:
        append( arg.toDouble() );
        return true;
#endif

    case DBUS_TYPE_STRING:
        append( arg.toString() );
        return true;
    case DBUS_TYPE_OBJECT_PATH:
        append( qvariant_cast<QDBusObjectPath>(arg) );
        return true;
    case DBUS_TYPE_SIGNATURE:
        append( qvariant_cast<QDBusSignature>(arg) );
        return true;

    // compound types:
    case DBUS_TYPE_VARIANT:
        // nested QVariant
        return append( qvariant_cast<QDBusVariant>(arg) );

    case DBUS_TYPE_ARRAY:
        // could be many things
        // find out what kind of array it is
        switch (arg.type()) {
        case QVariant::StringList:
            append( arg.toStringList() );
            return true;

        case QVariant::ByteArray:
            append( arg.toByteArray() );
            return true;

        default:
            ;
        }
        Q_FALLTHROUGH();

    case DBUS_TYPE_STRUCT:
    case DBUS_STRUCT_BEGIN_CHAR:
        return appendRegisteredType( arg );

    case DBUS_TYPE_DICT_ENTRY:
    case DBUS_DICT_ENTRY_BEGIN_CHAR:
        qFatal("QDBusMarshaller::appendVariantInternal got a DICT_ENTRY!");
        return false;

    case DBUS_TYPE_UNIX_FD:
        if (capabilities & QDBusConnection::UnixFileDescriptorPassing || ba) {
            append(qvariant_cast<QDBusUnixFileDescriptor>(arg));
            return true;
        }
        Q_FALLTHROUGH();

    default:
        qWarning("QDBusMarshaller::appendVariantInternal: Found unknown D-BUS type '%s'",
                 signature);
        return false;
    }

    return true;
}
예제 #3
0
파일: marshal.c 프로젝트: openhpi1/testrepo
int
Demarshal( int byte_order, const cMarshalType *type, void *d, const void *b )
{
  if ( IsSimpleType( type->m_type ) )
     {
       return DemarshalSimpleTypes( byte_order, type->m_type, d, b );
     }

  int                  size = 0;
  unsigned char       *data  = d;
  const unsigned char *buffer = b;

  switch( type->m_type )
     {
       case eMtArray:
	    {
	      const size_t nelems = type->u.m_array.m_nelements;

	      size_t i;
	      for( i = 0; i < nelems; i++ )
		 {
	           const cMarshalType *elem = type->u.m_array.m_element;
	           const size_t elem_sizeof = type->u.m_array.m_element_sizeof;

		   int cc = Demarshal( byte_order, elem, data, buffer );
		   if ( cc < 0 )
		      {
			   CRIT( "Demarshal: %s[%d]: failure, cc = %d!", type->m_name, i, cc );
			   return cc;
		      }

		   data   += elem_sizeof;
		   buffer += cc;
		   size   += cc;
		 }
	    }
	    break;

       case eMtStruct:
	    {
	      const cMarshalType *elems = &type->u.m_struct.m_elements[0];
	      size_t i;
	      for( i = 0; elems[i].m_type == eMtStructElement; i++ )
		 {
		   const cMarshalType *elem = elems[i].u.m_struct_element.m_element;
		   const size_t offset      = elems[i].u.m_struct_element.m_offset;
		   int cc = 0;

		   if ( elem->m_type == eMtUnion )
		      {
			const size_t mod2_idx = elem->u.m_union.m_mod_idx;
			if ( mod2_idx >= i ) {
			    // NB: this is a limitation of demarshaling of unions
 	                    CRIT( "Demarshal: %s:%s: mod field must be before union!",
			          type->m_name, elems[i].m_name );
			    return -EINVAL;
			}
			const size_t mod2 = GetStructElementIntegerValue( type, mod2_idx, data );
			const cMarshalType *elem2 = GetUnionElement( elem, mod2 );
			if ( !elem2 ) {
 	                    CRIT( "Demarshal: %s:%s: invalid mod value %u!",
			          type->m_name, elems[i].m_name, (unsigned int)mod2 );
			    return -EINVAL;
			}

			cc = Demarshal( byte_order, elem2, data + offset, buffer );
			if ( cc < 0 )
			   {
			     CRIT( "Demarshal: %s:%s, mod %u: failure, cc = %d!",
			           type->m_name, elems[i].m_name, (unsigned int)mod2, cc );
			     return cc;
			   }
		      }
		   else if ( elem->m_type == eMtVarArray )
		      {
			const size_t nelems2_idx   = elem->u.m_var_array.m_nelements_idx;
			const cMarshalType *elem2  = elem->u.m_var_array.m_element;
			const size_t elem2_sizeof  = elem->u.m_var_array.m_element_sizeof;

			if ( nelems2_idx >= i ) {
			    // NB: this is a limitation of demarshaling of var arrays
 	                    CRIT( "Demarshal: %s:%s: nelements field must be before vararray!",
			          type->m_name, elems[i].m_name );
			    return -EINVAL;
			}
			const size_t nelems2 = GetStructElementIntegerValue( type, nelems2_idx, data );

			// allocate storage for var array content
			unsigned char *data2 = g_new0(unsigned char, nelems2 * elem2_sizeof );
			// (data + offset ) points to pointer to var array content
			memcpy(data + offset, &data2, sizeof(void *));

			const unsigned char *buffer2 = buffer;
			size_t i2;
			for( i2 = 0; i2 < nelems2; i2++ )
			   {
			     int cc2 = Demarshal( byte_order, elem2, data2, buffer2 );
			     if ( cc2 < 0 )
				{
			          CRIT( "Demarshal: %s:%s[%d]: failure, cc = %d!",
			                 type->m_name, elems[i].m_name, i2, cc2 );
				  return cc2;
				}

			     data2   += elem2_sizeof;
			     buffer2 += cc2;
			     cc      += cc2;
			   }
		      }
		   else
		      {
			cc = Demarshal( byte_order, elem, data + offset, buffer );
			if ( cc < 0 )
			   {
			     CRIT( "Demarshal: %s:%s: failure, cc = %d!",
			           type->m_name, elems[i].m_name, cc );
			     return cc;
			   }
		      }

		   buffer += cc;
		   size   += cc;
		 }
	    }

	    break;

       case eMtUserDefined:
	    {
	      tDemarshalFunction demarshaller = type->u.m_user_defined.m_demarshaller;
	      void * user_data = type->u.m_user_defined.m_user_data;
	      size = demarshaller ? demarshaller( byte_order, type, d, b, user_data ) : 0;
            }
	    break;

       default:
	    return -ENOSYS;
     }