Logo Search packages:      
Sourcecode: dbus version File versions

dbus_bool_t dbus_message_iter_get_args_valist ( DBusMessageIter iter,
DBusError error,
int  first_arg_type,
va_list  var_args 
)

This function takes a va_list for use by language bindings

This function supports DBUS_TYPE_INT64 and DBUS_TYPE_UINT64 only if DBUS_HAVE_INT64 is defined.

Todo:
this function (or some lower-level non-convenience function) needs better error handling; should allow the application to distinguish between out of memory, and bad data from the remote app. It also needs to not leak a bunch of args when it gets to the arg that's bad, as that would be a security hole (allow one app to force another to leak memory)
Todo:
We need to free the argument data when an error occurs.
See also:
dbus_message_get_args
Parameters:
iter the message iter
error error to be filled in
first_arg_type type of the first argument
var_args return location for first argument, followed by list of type/location pairs
Returns:
FALSE if error was set

Definition at line 2865 of file dbus-message.c.

References _dbus_type_to_string(), _dbus_warn(), dbus_message_iter_get_arg_type(), dbus_message_iter_get_array_type(), dbus_message_iter_get_boolean(), dbus_message_iter_get_boolean_array(), dbus_message_iter_get_byte_array(), dbus_message_iter_get_custom(), dbus_message_iter_get_double_array(), dbus_message_iter_get_int32_array(), dbus_message_iter_get_object_path(), dbus_message_iter_get_object_path_array(), dbus_message_iter_get_string(), dbus_message_iter_get_string_array(), dbus_message_iter_get_uint32_array(), dbus_message_iter_next(), dbus_set_error(), FALSE, NULL, and TRUE.

Referenced by dbus_message_get_args_valist(), and dbus_message_iter_get_args().

{
  int spec_type, msg_type, i;
  dbus_bool_t retval;

  _dbus_return_val_if_fail (iter != NULL, FALSE);
  _dbus_return_val_if_error_is_set (error, FALSE);

  retval = FALSE;
  
  spec_type = first_arg_type;
  i = 0;
  
  while (spec_type != DBUS_TYPE_INVALID)
    {
      msg_type = dbus_message_iter_get_arg_type (iter);      
      
      if (msg_type != spec_type)
      {
          dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
                          "Argument %d is specified to be of type \"%s\", but "
                          "is actually of type \"%s\"\n", i,
                          _dbus_type_to_string (spec_type),
                          _dbus_type_to_string (msg_type));

          goto out;
      }

      switch (spec_type)
      {
      case DBUS_TYPE_NIL:
        break;
      case DBUS_TYPE_BOOLEAN:
        {
          dbus_bool_t *ptr;

          ptr = va_arg (var_args, dbus_bool_t *);

          *ptr = dbus_message_iter_get_boolean (iter);
          break;
        }
      case DBUS_TYPE_BYTE:
      case DBUS_TYPE_INT32:
      case DBUS_TYPE_UINT32:
#ifdef DBUS_HAVE_INT64
      case DBUS_TYPE_INT64:
      case DBUS_TYPE_UINT64:
#endif /* DBUS_HAVE_INT64 */
      case DBUS_TYPE_DOUBLE:
        {
          void *ptr = va_arg (var_args, double *);
          _dbus_message_iter_get_basic_type (iter, spec_type, ptr);
          break;
        }

      case DBUS_TYPE_STRING:
        {
          char **ptr;

          ptr = va_arg (var_args, char **);

          *ptr = dbus_message_iter_get_string (iter);

          if (!*ptr)
              {
                dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
                goto out;
              }
          
          break;
        }

        case DBUS_TYPE_OBJECT_PATH:
        {
          char **ptr;

          ptr = va_arg (var_args, char **);

          *ptr = dbus_message_iter_get_object_path (iter);

          if (!*ptr)
            {
              dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
              goto out;
            }

          break;
        }

      case DBUS_TYPE_CUSTOM:
        {
          char **name;
          unsigned char **data;
          int *len;
 
          name = va_arg (var_args, char **);
          data = va_arg (var_args, unsigned char **);
          len = va_arg (var_args, int *);

          if (!dbus_message_iter_get_custom (iter, name, data, len))
            {
                dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
            goto out;
            }
        }
        break;
      case DBUS_TYPE_ARRAY:
        {
          void **data;
          int *len, type;
          dbus_bool_t err = FALSE;
 
          type = va_arg (var_args, int);
          data = va_arg (var_args, void *);
          len = va_arg (var_args, int *);

            _dbus_return_val_if_fail (data != NULL, FALSE);
            _dbus_return_val_if_fail (len != NULL, FALSE);
            
          if (dbus_message_iter_get_array_type (iter) != type)
            {
            dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
                        "Argument %d is specified to be of type \"array of %s\", but "
                        "is actually of type \"array of %s\"\n", i,
                        _dbus_type_to_string (type),
                        _dbus_type_to_string (dbus_message_iter_get_array_type (iter)));
            goto out;
            }
          
          switch (type)
            {
            case DBUS_TYPE_BYTE:
            err = !dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len);
            break;
            case DBUS_TYPE_BOOLEAN:
            err = !dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len);
            break;
            case DBUS_TYPE_INT32:
            err = !dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len);
            break;
            case DBUS_TYPE_UINT32:
            err = !dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len);
            break;
#ifdef DBUS_HAVE_INT64
              case DBUS_TYPE_INT64:
            err = !dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len);
            break;
            case DBUS_TYPE_UINT64:
            err = !dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len);
            break;
#endif /* DBUS_HAVE_INT64 */
            case DBUS_TYPE_DOUBLE:
            err = !dbus_message_iter_get_double_array (iter, (double **)data, len);
            break;
            case DBUS_TYPE_STRING:
            err = !dbus_message_iter_get_string_array (iter, (char ***)data, len);
            break;
            case DBUS_TYPE_OBJECT_PATH:
              err = !dbus_message_iter_get_object_path_array (iter, (char ***)data, len);
              break;

            case DBUS_TYPE_NIL:
            case DBUS_TYPE_ARRAY:
            case DBUS_TYPE_CUSTOM:
            case DBUS_TYPE_DICT:
            _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n");
            dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
            goto out;
            default:
            _dbus_warn ("Unknown field type %d\n", type);
            dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
            goto out;
            }
          if (err)
            {
              dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
            goto out;
            }
        }
        break;
      case DBUS_TYPE_DICT:
        _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n");
        dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
        goto out;
      default:      
        dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL);
        _dbus_warn ("Unknown field type %d\n", spec_type);
        goto out;
      }

      spec_type = va_arg (var_args, int);
      if (!dbus_message_iter_next (iter) && spec_type != DBUS_TYPE_INVALID)
        {
          dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
                          "Message has only %d arguments, but more were expected", i);
          goto out;
        }

      i++;
    }
  
  retval = TRUE;
  
 out:
  
  return retval;
}


Generated by  Doxygen 1.6.0   Back to index