if (dbus_message_get_serial (message) == 0)
{
serial = _dbus_connection_get_next_client_serial (connection);
- _dbus_message_set_serial (message, serial);
+ dbus_message_set_serial (message, serial);
if (client_serial)
*client_serial = serial;
}
_dbus_verbose ("Message %p serial is %u\n",
message, dbus_message_get_serial (message));
- _dbus_message_lock (message);
+ dbus_message_lock (message);
/* Now we need to run an iteration to hopefully just write the messages
* out immediately, and otherwise get them queued up
if (serial == 0)
{
serial = _dbus_connection_get_next_client_serial (connection);
- _dbus_message_set_serial (message, serial);
+ dbus_message_set_serial (message, serial);
}
if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
DBusValidity *expected_validity,
DBusMessage *message)
{
- _dbus_message_set_serial (message, 1);
- _dbus_message_lock (message);
+ dbus_message_set_serial (message, 1);
+ dbus_message_lock (message);
*expected_validity = DBUS_VALID;
void _dbus_message_lock (DBusMessage *message);
void _dbus_message_unlock (DBusMessage *message);
-void _dbus_message_set_serial (DBusMessage *message,
- dbus_uint32_t serial);
dbus_bool_t _dbus_message_add_size_counter (DBusMessage *message,
DBusCounter *counter);
void _dbus_message_add_size_counter_link (DBusMessage *message,
"TestMethod"));
_dbus_assert (strcmp (dbus_message_get_path (message),
"/org/freedesktop/TestPath") == 0);
- _dbus_message_set_serial (message, 1234);
+ dbus_message_set_serial (message, 1234);
/* string length including nul byte not a multiple of 4 */
if (!dbus_message_set_sender (message, "org.foo.bar1"))
"/org/freedesktop/TestPath",
"Foo.TestInterface",
"TestMethod");
- _dbus_message_set_serial (message, 1);
+ dbus_message_set_serial (message, 1);
dbus_message_set_reply_serial (message, 5678);
v_INT16 = -0x123;
dbus_message_unref (copy);
/* Message loader test */
- _dbus_message_lock (message);
+ dbus_message_lock (message);
loader = _dbus_message_loader_new ();
/* check ref/unref */
DBusError error = DBUS_ERROR_INIT;
char *marshalled = NULL;
int len = 0;
+ char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx";
if (!dbus_message_marshal (message, &marshalled, &len))
_dbus_assert_not_reached ("failed to marshal message");
_dbus_assert (len != 0);
_dbus_assert (marshalled != NULL);
+ _dbus_assert (dbus_message_demarshal_bytes_needed (marshalled, len) == len);
message2 = dbus_message_demarshal (marshalled, len, &error);
_dbus_assert (message2 != NULL);
_dbus_assert (message2 == NULL);
_dbus_assert (dbus_error_is_set (&error));
dbus_error_free (&error);
+
+ /* Bytes needed to demarshal empty message: 0 (more) */
+
+ _dbus_assert (dbus_message_demarshal_bytes_needed ("", 0) == 0);
+
+ /* Bytes needed to demarshal invalid message: -1 (error). */
+
+ _dbus_assert (dbus_message_demarshal_bytes_needed (garbage_header, DBUS_MINIMUM_HEADER_SIZE) == -1);
}
dbus_message_unref (message);
* Gets the data to be sent over the network for this message.
* The header and then the body should be written out.
* This function is guaranteed to always return the same
- * data once a message is locked (with _dbus_message_lock()).
+ * data once a message is locked (with dbus_message_lock()).
*
* @param message the message.
* @param header return location for message header data.
* Sets the serial number of a message.
* This can only be done once on a message.
*
+ * DBusConnection will automatically set the serial to an appropriate value
+ * when the message is sent; this function is only needed when encapsulating
+ * messages in another protocol, or otherwise bypassing DBusConnection.
+ *
* @param message the message
* @param serial the serial
*/
-void
-_dbus_message_set_serial (DBusMessage *message,
- dbus_uint32_t serial)
+void
+dbus_message_set_serial (DBusMessage *message,
+ dbus_uint32_t serial)
{
- _dbus_assert (message != NULL);
- _dbus_assert (!message->locked);
- _dbus_assert (dbus_message_get_serial (message) == 0);
+ _dbus_return_if_fail (message != NULL);
+ _dbus_return_if_fail (!message->locked);
_dbus_header_set_serial (&message->header, serial);
}
* reference to a message in the outgoing queue and change it
* underneath us. Messages are locked when they enter the outgoing
* queue (dbus_connection_send_message()), and the library complains
- * if the message is modified while locked.
+ * if the message is modified while locked. This function may also
+ * called externally, for applications wrapping D-Bus in another protocol.
*
* @param message the message to lock.
*/
void
-_dbus_message_lock (DBusMessage *message)
+dbus_message_lock (DBusMessage *message)
{
if (!message->locked)
{
_dbus_return_val_if_fail (msg != NULL, FALSE);
_dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
_dbus_return_val_if_fail (len_p != NULL, FALSE);
-
+
if (!_dbus_string_init (&tmp))
return FALSE;
return NULL;
}
+/**
+ * Returns the number of bytes required to be in the buffer to demarshal a
+ * D-Bus message.
+ *
+ * Generally, this function is only useful for encapsulating D-Bus messages in
+ * a different protocol.
+ *
+ * @param str data to be marshalled
+ * @param len the length of str
+ * @param error the location to save errors to
+ * @returns -1 if there was no valid data to be demarshalled, 0 if there wasn't enough data to determine how much should be demarshalled. Otherwise returns the number of bytes to be demarshalled
+ *
+ */
+int
+dbus_message_demarshal_bytes_needed(const char *buf,
+ int len)
+{
+ DBusString str;
+ int byte_order, fields_array_len, header_len, body_len;
+ DBusValidity validity = DBUS_VALID;
+ int have_message;
+
+ if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
+ return 0;
+
+ if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
+ len = DBUS_MAXIMUM_MESSAGE_LENGTH;
+ _dbus_string_init_const_len (&str, buf, len);
+
+ validity = DBUS_VALID;
+ have_message
+ = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH,
+ &validity, &byte_order,
+ &fields_array_len,
+ &header_len,
+ &body_len,
+ &str, 0,
+ len);
+ _dbus_string_free (&str);
+
+ if (validity == DBUS_VALID)
+ {
+ _dbus_assert(have_message);
+ return header_len + body_len;
+ }
+ else
+ {
+ return -1; /* broken! */
+ }
+}
+
/** @} */
/* tests in dbus-message-util.c */
dbus_bool_t dbus_message_has_signature (DBusMessage *message,
const char *signature);
dbus_uint32_t dbus_message_get_serial (DBusMessage *message);
+void dbus_message_set_serial (DBusMessage *message,
+ dbus_uint32_t serial);
dbus_bool_t dbus_message_set_reply_serial (DBusMessage *message,
dbus_uint32_t reply_serial);
dbus_uint32_t dbus_message_get_reply_serial (DBusMessage *message);
dbus_bool_t dbus_message_iter_close_container (DBusMessageIter *iter,
DBusMessageIter *sub);
+void dbus_message_lock (DBusMessage *message);
dbus_bool_t dbus_set_error_from_message (DBusError *error,
DBusMessage *message);
int len,
DBusError *error);
+int dbus_message_demarshal_bytes_needed (const char *str,
+ int len);
+
/** @} */
DBUS_END_DECLS
message = _dbus_connection_get_message_to_send (transport->connection);
_dbus_assert (message != NULL);
- _dbus_message_lock (message);
+ dbus_message_lock (message);
#if 0
_dbus_verbose ("writing message %p\n", message);