unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
- DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
+ DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
+
+ DBusString signature; /**< Signature */
};
enum {
dbus_free (message);
return NULL;
}
+
+ if (!_dbus_string_init_preallocated (&message->signature, 4))
+ {
+ _dbus_string_free (&message->header);
+ _dbus_string_free (&message->body);
+ dbus_free (message);
+ return NULL;
+ }
return message;
}
retval->header_padding = message->header_padding;
retval->locked = FALSE;
- if (!_dbus_string_init (&retval->header))
+ if (!_dbus_string_init_preallocated (&retval->header,
+ _dbus_string_get_length (&message->header)))
{
dbus_free (retval);
return NULL;
}
- if (!_dbus_string_init (&retval->body))
+ if (!_dbus_string_init_preallocated (&retval->body,
+ _dbus_string_get_length (&message->body)))
{
_dbus_string_free (&retval->header);
dbus_free (retval);
return NULL;
}
- if (!_dbus_string_copy (&message->header, 0,
- &retval->header, 0))
+ if (!_dbus_string_init_preallocated (&retval->signature,
+ _dbus_string_get_length (&message->signature)))
{
_dbus_string_free (&retval->header);
_dbus_string_free (&retval->body);
dbus_free (retval);
-
return NULL;
}
+
+ if (!_dbus_string_copy (&message->header, 0,
+ &retval->header, 0))
+ goto failed_copy;
if (!_dbus_string_copy (&message->body, 0,
&retval->body, 0))
- {
- _dbus_string_free (&retval->header);
- _dbus_string_free (&retval->body);
- dbus_free (retval);
-
- return NULL;
- }
+ goto failed_copy;
+ if (!_dbus_string_copy (&message->signature, 0,
+ &retval->signature, 0))
+ goto failed_copy;
+
for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
{
retval->header_fields[i] = message->header_fields[i];
}
return retval;
+
+ failed_copy:
+ _dbus_string_free (&retval->header);
+ _dbus_string_free (&retval->body);
+ _dbus_string_free (&retval->signature);
+ dbus_free (retval);
+
+ return NULL;
}
_dbus_string_free (&message->header);
_dbus_string_free (&message->body);
+ _dbus_string_free (&message->signature);
dbus_free (message);
}
return pos;
}
+/* FIXME what are these _dbus_type_is_valid() checks for?
+ * haven't we validated the message?
+ */
static int
dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)
{
case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
data = _dbus_string_get_const_data_len (&iter->message->body,
iter->pos, 1);
- if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
+ if (_dbus_type_is_valid (*data))
*type = *data;
else
*type = DBUS_TYPE_INVALID;
case DBUS_MESSAGE_ITER_TYPE_ARRAY:
data = _dbus_string_get_const_data_len (&iter->message->body,
iter->array_type_pos, 1);
- if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
+ if (_dbus_type_is_valid (*data))
*type = *data;
else
*type = DBUS_TYPE_INVALID;
data = _dbus_string_get_const_data_len (&iter->message->body,
pos, 1);
- if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
+ if (_dbus_type_is_valid (*data))
*type = *data;
else
*type = DBUS_TYPE_INVALID;
return type;
}
+/* FIXME why do we validate the typecode in here, hasn't the message
+ * already been verified?
+ */
static int
iter_get_array_type (DBusMessageRealIter *iter, int *array_type_pos)
{
data = _dbus_string_get_const_data_len (&iter->message->body,
_array_type_pos, 1);
- if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
+ if (_dbus_type_is_valid (*data))
return *data;
return DBUS_TYPE_INVALID;
* @param iter the iterator
* @param array_iter pointer to an iterator to initialize
* @param array_type gets set to the type of the array elements
- * @returns #TRUE on success
*/
-dbus_bool_t
+void
dbus_message_iter_init_array_iterator (DBusMessageIter *iter,
DBusMessageIter *array_iter,
int *array_type)
int type, pos, len_pos, len, array_type_pos;
int _array_type;
- _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
+ _dbus_return_if_fail (dbus_message_iter_check (real));
pos = dbus_message_iter_get_data_start (real, &type);
if (array_type != NULL)
*array_type = _array_type;
-
- return TRUE;
}
*
* @param iter the iterator
* @param dict_iter pointer to an iterator to initialize
- * @returns #TRUE on success
*/
-dbus_bool_t
+void
dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,
DBusMessageIter *dict_iter)
{
DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter;
int type, pos, len_pos, len;
- _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
+ _dbus_return_if_fail (dbus_message_iter_check (real));
pos = dbus_message_iter_get_data_start (real, &type);
dict_real->container_start = pos;
dict_real->container_length_pos = len_pos;
dict_real->wrote_dict_key = 0;
-
- return TRUE;
}
/**
switch (iter->type)
{
case DBUS_MESSAGE_ITER_TYPE_MESSAGE:
+ if (!_dbus_string_append_byte (&iter->message->signature, type))
+ return FALSE;
+
if (!_dbus_string_append_byte (&iter->message->body, type))
- return FALSE;
+ {
+ _dbus_string_shorten (&iter->message->signature, 1);
+ return FALSE;
+ }
break;
case DBUS_MESSAGE_ITER_TYPE_ARRAY:
}
if (!_dbus_string_append_byte (&iter->message->body, type))
- return FALSE;
+ return FALSE;
break;
{
if (array_type_pos != NULL)
*array_type_pos = _dbus_string_get_length (&real->message->body);
+
+
+ if (!_dbus_string_append_byte (&real->message->signature, element_type))
+ {
+ _dbus_string_set_length (&real->message->body, real->pos);
+ return FALSE;
+ }
/* Append element type */
if (!_dbus_string_append_byte (&real->message->body, element_type))
{
+ _dbus_string_shorten (&real->message->signature, 1);
_dbus_string_set_length (&real->message->body, real->pos);
return FALSE;
}
if (element_type != DBUS_TYPE_ARRAY &&
!array_iter_type_mark_done (real))
- return FALSE;
+ {
+ _dbus_string_shorten (&real->message->signature, 1);
+ return FALSE;
+ }
}
return TRUE;
int len_pos;
_dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
+
if (!dbus_message_iter_append_type (real, DBUS_TYPE_DICT))
- return FALSE;
-
+ return FALSE;
+
len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t));
/* Empty length for now, backfill later */
NULL);
}
+/**
+ * Gets the type signature of the message, i.e. the arguments in the
+ * message payload. The signature includes only "in" arguments for
+ * #DBUS_MESSAGE_TYPE_METHOD_CALL and only "out" arguments for
+ * #DBUS_MESSAGE_TYPE_METHOD_RETURN, so is slightly different from
+ * what you might expect (it does not include the signature of the
+ * entire C++-style method).
+ *
+ * The signature is a string made up of type codes such
+ * as #DBUS_TYPE_STRING. The string is terminated with nul
+ * (nul is also the value of #DBUS_TYPE_INVALID).
+ *
+ * @param message the message
+ * @returns the type signature
+ */
+const char*
+dbus_message_get_signature (DBusMessage *message)
+{
+ _dbus_return_val_if_fail (message != NULL, NULL);
+
+ return _dbus_string_get_const_data (&message->signature);
+}
+
static dbus_bool_t
_dbus_message_has_type_interface_member (DBusMessage *message,
int type,
{
const char *s;
- _dbus_assert (service != NULL);
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (service != NULL, FALSE);
s = dbus_message_get_sender (message);
return FALSE;
}
+/**
+ * Checks whether the message has the given signature;
+ * see dbus_message_get_signature() for more details on
+ * what the signature looks like.
+ *
+ * @param message the message
+ * @param signature typecode array
+ * @returns #TRUE if message has the given signature
+*/
+dbus_bool_t
+dbus_message_has_signature (DBusMessage *message,
+ const char *signature)
+{
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (signature != NULL, FALSE);
+
+ return _dbus_string_equal_c_str (&message->signature, signature);
+}
+
/**
* Sets a #DBusError based on the contents of the given
* message. The error is only set if the message
message->byte_order,
CLIENT_SERIAL_OFFSET,
NULL);
+
+ /* Fill in signature (FIXME should do this during validation,
+ * but I didn't want to spend time on it since we want to change
+ * the wire format to contain the signature anyway)
+ */
+ {
+ DBusMessageIter iter;
+
+ dbus_message_iter_init (message, &iter);
+
+ do
+ {
+ int t;
+
+ t = dbus_message_iter_get_arg_type (&iter);
+ if (t == DBUS_TYPE_INVALID)
+ break;
+
+ if (!_dbus_string_append_byte (&message->signature,
+ t))
+ {
+ _dbus_verbose ("failed to append type byte to signature\n");
+ _dbus_list_remove_last (&loader->messages, message);
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ if (t == DBUS_TYPE_ARRAY)
+ {
+ DBusMessageIter child_iter;
+ int array_type = t;
+
+ child_iter = iter;
+
+ while (array_type == DBUS_TYPE_ARRAY)
+ {
+ DBusMessageIter parent_iter = child_iter;
+ dbus_message_iter_init_array_iterator (&parent_iter,
+ &child_iter,
+ &array_type);
+
+ if (!_dbus_string_append_byte (&message->signature,
+ array_type))
+ {
+ _dbus_verbose ("failed to append array type byte to signature\n");
+ _dbus_list_remove_last (&loader->messages, message);
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ }
+ }
+ }
+ while (dbus_message_iter_next (&iter));
+ }
_dbus_verbose ("Loaded message %p\n", message);
}
_dbus_assert_not_reached ("Array type not double");
- if (!dbus_message_iter_init_array_iterator (&iter, &array, NULL))
- _dbus_assert_not_reached ("Array init failed");
+ dbus_message_iter_init_array_iterator (&iter, &array, NULL);
if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE)
_dbus_assert_not_reached ("Argument type isn't double");
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
_dbus_assert_not_reached ("not dict type");
- if (!dbus_message_iter_init_dict_iterator (&iter, &dict))
- _dbus_assert_not_reached ("dict iter failed");
+ dbus_message_iter_init_dict_iterator (&iter, &dict);
str = dbus_message_iter_get_dict_key (&dict);
if (str == NULL || strcmp (str, "test") != 0)
if (dbus_message_iter_get_array_type (&dict) != DBUS_TYPE_ARRAY)
_dbus_assert_not_reached ("Array type not array");
- if (!dbus_message_iter_init_array_iterator (&dict, &array, NULL))
- _dbus_assert_not_reached ("Array init failed");
+ dbus_message_iter_init_array_iterator (&dict, &array, NULL);
if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_ARRAY)
_dbus_assert_not_reached ("Argument type isn't array");
if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32)
_dbus_assert_not_reached ("Array type not int32");
- if (!dbus_message_iter_init_array_iterator (&array, &array2, NULL))
- _dbus_assert_not_reached ("Array init failed");
+ dbus_message_iter_init_array_iterator (&array, &array2, NULL);
if (dbus_message_iter_get_arg_type (&array2) != DBUS_TYPE_INT32)
_dbus_assert_not_reached ("Argument type isn't int32");
{
int array_type;
- if (!dbus_message_iter_init_array_iterator (iter, &child_iter, &array_type))
- {
- _dbus_warn ("Failed to init array iterator\n");
- return FALSE;
- }
+ dbus_message_iter_init_array_iterator (iter, &child_iter, &array_type);
while (dbus_message_iter_has_next (&child_iter))
{
int entry_type;
char *key;
- if (!dbus_message_iter_init_dict_iterator (iter, &child_iter))
- {
- _dbus_warn ("Failed to init dict iterator\n");
- return FALSE;
- }
+ dbus_message_iter_init_dict_iterator (iter, &child_iter);
while ((entry_type = dbus_message_iter_get_arg_type (&child_iter)) != DBUS_TYPE_INVALID)
{
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)
_dbus_assert_not_reached ("not dict type");
- if (!dbus_message_iter_init_dict_iterator (&iter, &dict))
- _dbus_assert_not_reached ("dict iter failed");
+ dbus_message_iter_init_dict_iterator (&iter, &dict);
our_str = dbus_message_iter_get_dict_key (&dict);
if (our_str == NULL || strcmp (our_str, "test") != 0)
const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
const unsigned char our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
+ char sig[64];
+ const char *s;
_dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
dbus_message_iter_append_dict_key (&child_iter, "test");
dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF);
dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE);
+
+ i = 0;
+ sig[i++] = DBUS_TYPE_INT32;
+#ifdef DBUS_HAVE_INT64
+ sig[i++] = DBUS_TYPE_INT64;
+ sig[i++] = DBUS_TYPE_UINT64;
+#endif
+ sig[i++] = DBUS_TYPE_STRING;
+ sig[i++] = DBUS_TYPE_DOUBLE;
+ sig[i++] = DBUS_TYPE_BOOLEAN;
+ sig[i++] = DBUS_TYPE_ARRAY;
+ sig[i++] = DBUS_TYPE_UINT32;
+ sig[i++] = DBUS_TYPE_ARRAY;
+ sig[i++] = DBUS_TYPE_INT32;
+#ifdef DBUS_HAVE_INT64
+ sig[i++] = DBUS_TYPE_ARRAY;
+ sig[i++] = DBUS_TYPE_UINT64;
+ sig[i++] = DBUS_TYPE_ARRAY;
+ sig[i++] = DBUS_TYPE_INT64;
+#endif
+ sig[i++] = DBUS_TYPE_ARRAY;
+ sig[i++] = DBUS_TYPE_STRING;
+ sig[i++] = DBUS_TYPE_ARRAY;
+ sig[i++] = DBUS_TYPE_DOUBLE;
+ sig[i++] = DBUS_TYPE_ARRAY;
+ sig[i++] = DBUS_TYPE_BYTE;
+ sig[i++] = DBUS_TYPE_ARRAY;
+ sig[i++] = DBUS_TYPE_BOOLEAN;
+ sig[i++] = DBUS_TYPE_DICT;
+ sig[i++] = DBUS_TYPE_UINT32;
+ sig[i++] = DBUS_TYPE_INVALID;
+
+ _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));
_dbus_verbose_bytes_of_string (&message->header, 0,
_dbus_string_get_length (&message->header));
_dbus_verbose_bytes_of_string (&message->body, 0,
_dbus_string_get_length (&message->body));
-
+
+ _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n",
+ sig, dbus_message_get_signature (message));
+
+ s = dbus_message_get_signature (message);
+
+ _dbus_assert (dbus_message_has_signature (message, sig));
+ _dbus_assert (strcmp (s, sig) == 0);
+
verify_test_message (message);
copy = dbus_message_copy (message);
_dbus_assert (_dbus_string_get_length (&message->body) ==
_dbus_string_get_length (©->body));
+ _dbus_assert (_dbus_string_get_length (&message->signature) ==
+ _dbus_string_get_length (©->signature));
+
verify_test_message (copy);
name1 = dbus_message_get_interface (message);