diff options
| author | William Lachance <wrlach@gmail.com> | 2009-04-21 13:51:46 -0400 | 
|---|---|---|
| committer | Colin Walters <walters@verbum.org> | 2009-04-21 13:51:46 -0400 | 
| commit | 16a947eedb7f7f2951fff4ebbf301af7776aa8df (patch) | |
| tree | b3095a345c3547e36ae5015660d2b8a7655569f0 | |
| parent | ce09b82ec2dd3cb1d239605f8f458e09afd70694 (diff) | |
Bug 19567 - Make marshaling code usable without DBusConnection
Some projects want to reuse the DBus message format, without
actually going through a DBusConnection.  This set of changes
makes a few functions from DBusMessage public, and adds a new
function to determine the number of bytes needed to demarshal
a message.
Signed-off-by: Colin Walters <walters@verbum.org>
| -rw-r--r-- | dbus/dbus-connection.c | 6 | ||||
| -rw-r--r-- | dbus/dbus-message-factory.c | 4 | ||||
| -rw-r--r-- | dbus/dbus-message-internal.h | 2 | ||||
| -rw-r--r-- | dbus/dbus-message-util.c | 16 | ||||
| -rw-r--r-- | dbus/dbus-message.c | 75 | ||||
| -rw-r--r-- | dbus/dbus-message.h | 6 | ||||
| -rw-r--r-- | dbus/dbus-transport-socket.c | 2 | 
7 files changed, 90 insertions, 21 deletions
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index d44d728b..947c0afe 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -1950,7 +1950,7 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *con    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;      } @@ -1963,7 +1963,7 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *con    _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 @@ -3208,7 +3208,7 @@ dbus_connection_send_with_reply (DBusConnection     *connection,    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)) diff --git a/dbus/dbus-message-factory.c b/dbus/dbus-message-factory.c index ceffc764..8550ee86 100644 --- a/dbus/dbus-message-factory.c +++ b/dbus/dbus-message-factory.c @@ -222,8 +222,8 @@ generate_from_message (DBusString            *data,                         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; diff --git a/dbus/dbus-message-internal.h b/dbus/dbus-message-internal.h index 76615859..2e995b47 100644 --- a/dbus/dbus-message-internal.h +++ b/dbus/dbus-message-internal.h @@ -37,8 +37,6 @@ void _dbus_message_get_network_data  (DBusMessage       *message,  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, diff --git a/dbus/dbus-message-util.c b/dbus/dbus-message-util.c index 0fa010cc..46cbe4e3 100644 --- a/dbus/dbus-message-util.c +++ b/dbus/dbus-message-util.c @@ -949,7 +949,7 @@ _dbus_message_test (const char *test_data_dir)                                               "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")) @@ -1041,7 +1041,7 @@ _dbus_message_test (const char *test_data_dir)                                            "/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; @@ -1172,7 +1172,7 @@ _dbus_message_test (const char *test_data_dir)    dbus_message_unref (copy);    /* Message loader test */ -  _dbus_message_lock (message); +  dbus_message_lock (message);    loader = _dbus_message_loader_new ();    /* check ref/unref */ @@ -1226,6 +1226,7 @@ _dbus_message_test (const char *test_data_dir)        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"); @@ -1233,6 +1234,7 @@ _dbus_message_test (const char *test_data_dir)        _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); @@ -1255,6 +1257,14 @@ _dbus_message_test (const char *test_data_dir)        _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); diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index e2c4771e..edae4258 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -142,7 +142,7 @@ _dbus_message_byteswap (DBusMessage *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. @@ -163,16 +163,19 @@ _dbus_message_get_network_data (DBusMessage          *message,   * 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);  } @@ -277,12 +280,13 @@ _dbus_message_remove_size_counter (DBusMessage  *message,   * 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)      { @@ -3941,7 +3945,7 @@ dbus_message_marshal (DBusMessage  *msg,    _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; @@ -4023,6 +4027,57 @@ dbus_message_demarshal (const char *str,    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 */ diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index 1bf7d0c2..2e29fef0 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -131,6 +131,8 @@ dbus_bool_t   dbus_message_has_sender       (DBusMessage   *message,  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); @@ -196,6 +198,7 @@ dbus_bool_t dbus_message_iter_open_container     (DBusMessageIter *iter,  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); @@ -220,6 +223,9 @@ DBusMessage* dbus_message_demarshal (const char *str,                                       int         len,                                       DBusError  *error); +int          dbus_message_demarshal_bytes_needed (const char *str,  +                                                  int len); +  /** @} */  DBUS_END_DECLS diff --git a/dbus/dbus-transport-socket.c b/dbus/dbus-transport-socket.c index 10b671c2..6d7c89cd 100644 --- a/dbus/dbus-transport-socket.c +++ b/dbus/dbus-transport-socket.c @@ -537,7 +537,7 @@ do_writing (DBusTransport *transport)        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);  | 
