diff options
author | Havoc Pennington <hp@redhat.com> | 2003-01-26 07:48:16 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2003-01-26 07:48:16 +0000 |
commit | 50c25505f62786756519ef1e194883360eda82e0 (patch) | |
tree | 968d4b0b148a78a665ea7b023350047e070aafed /dbus/dbus-string.c | |
parent | d5ad082fecbbd803fd89b3574ac137b3fa964bc7 (diff) |
2003-01-26 Havoc Pennington <hp@pobox.com>
The unit tests pass, but otherwise untested. If it breaks, the
tests should have been better. ;-)
* bus/driver.c (bus_driver_handle_hello): return if we disconnect
the connection.
* dbus/dbus-message.c: redo everything so we maintain
message->header as the only copy of the various fields.
This avoids the possibility of out-of-memory in some cases,
for example dbus_message_lock() can't run out of memory anymore,
and avoids extra copying. Figured I may as well go ahead and do
this since it was busted for dbus_message_lock to not return
failure on OOM, and dbus_message_write_header was totally
unchecked for OOM. Also fixed some random other bugs.
* dbus/dbus-marshal.c (_dbus_marshal_get_field_end_pos): verify
that strings are nul-terminated. Also, end_pos can be equal
to string length just not greater than, I think.
(_dbus_marshal_set_int32): new function
(_dbus_marshal_set_uint32): new function
(_dbus_marshal_set_string): new function
* dbus/dbus-connection.c (_dbus_connection_new_for_transport): fix
a warning, init timeout_list to NULL
(dbus_connection_send_message): don't use uninitialized variable
"serial"
* dbus/dbus-string.c (_dbus_string_replace_len): new function
Diffstat (limited to 'dbus/dbus-string.c')
-rw-r--r-- | dbus/dbus-string.c | 128 |
1 files changed, 125 insertions, 3 deletions
diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 257935eb..e1707bcc 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -195,6 +195,25 @@ void _dbus_string_init_const (DBusString *str, const char *value) { + _dbus_string_init_const_len (str, value, + strlen (value)); +} + +/** + * Initializes a constant string with a length. The value parameter is + * not copied (should be static), and the string may never be + * modified. It is safe but not necessary to call _dbus_string_free() + * on a const string. + * + * @param str memory to use for the string + * @param value a string to be stored in str (not copied!!!) + * @param len the length to use + */ +void +_dbus_string_init_const_len (DBusString *str, + const char *value, + int len) +{ DBusRealString *real; _dbus_assert (str != NULL); @@ -203,7 +222,7 @@ _dbus_string_init_const (DBusString *str, real = (DBusRealString*) str; real->str = (char*) value; - real->len = strlen (real->str); + real->len = len; real->allocated = real->len; real->max_length = real->len; real->constant = TRUE; @@ -358,6 +377,23 @@ _dbus_string_get_const_data_len (const DBusString *str, } /** + * Gets the byte at the given position. + * + * @param str the string + * @param start the position + * @returns the byte at that position + */ +char +_dbus_string_get_byte (const DBusString *str, + int start) +{ + DBUS_CONST_STRING_PREAMBLE (str); + _dbus_assert (start < real->len); + + return real->str[start]; +} + +/** * Like _dbus_string_get_data(), but removes the * gotten data from the original string. The caller * must free the data returned. This function may @@ -760,7 +796,7 @@ _dbus_string_delete (DBusString *str, _dbus_assert (start >= 0); _dbus_assert (len >= 0); _dbus_assert ((start + len) <= real->len); - + delete (real, start, len); } @@ -789,9 +825,12 @@ copy (DBusRealString *source, DBusRealString *dest, int insert_at) { + if (len == 0) + return TRUE; + if (!open_gap (len, dest, insert_at)) return FALSE; - + memcpy (dest->str + insert_at, source->str + start, len); @@ -938,6 +977,44 @@ _dbus_string_copy_len (const DBusString *source, insert_at); } +/** + * Replaces a segment of dest string with a segment of source string. + * + * @todo optimize the case where the two lengths are the same, and + * avoid memmoving the data in the trailing part of the string twice. + * + * @param source the source string + * @param start where to start copying the source string + * @param len length of segment to copy + * @param dest the destination string + * @param replace_at start of segment of dest string to replace + * @param replace_len length of segment of dest string to replace + * @returns #FALSE if not enough memory + * + */ +dbus_bool_t +_dbus_string_replace_len (const DBusString *source, + int start, + int len, + DBusString *dest, + int replace_at, + int replace_len) +{ + DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at); + _dbus_assert (len >= 0); + _dbus_assert ((start + len) <= real_source->len); + _dbus_assert (replace_at >= 0); + _dbus_assert ((replace_at + replace_len) <= real_dest->len); + + if (!copy (real_source, start, len, + real_dest, replace_at)) + return FALSE; + + delete (real_dest, replace_at + len, replace_len); + + return TRUE; +} + /* Unicode macros from GLib */ /** computes length and mask of a unicode character @@ -1931,6 +2008,51 @@ _dbus_string_test (void) _dbus_string_free (&str); _dbus_string_free (&other); + /* Check replace */ + + if (!_dbus_string_init (&str, _DBUS_INT_MAX)) + _dbus_assert_not_reached ("failed to init string"); + + if (!_dbus_string_append (&str, "Hello World")) + _dbus_assert_not_reached ("could not append to string"); + + i = _dbus_string_get_length (&str); + + if (!_dbus_string_init (&other, _DBUS_INT_MAX)) + _dbus_assert_not_reached ("could not init string"); + + if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), + &other, 0, _dbus_string_get_length (&other))) + _dbus_assert_not_reached ("could not replace"); + + _dbus_assert (_dbus_string_get_length (&str) == i); + _dbus_assert (_dbus_string_get_length (&other) == i); + _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World")); + + if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), + &other, 5, 1)) + _dbus_assert_not_reached ("could not replace center space"); + + _dbus_assert (_dbus_string_get_length (&str) == i); + _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); + _dbus_assert (_dbus_string_equal_c_str (&other, + "HelloHello WorldWorld")); + + + if (!_dbus_string_replace_len (&str, 1, 1, + &other, + _dbus_string_get_length (&other) - 1, + 1)) + _dbus_assert_not_reached ("could not replace end character"); + + _dbus_assert (_dbus_string_get_length (&str) == i); + _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); + _dbus_assert (_dbus_string_equal_c_str (&other, + "HelloHello WorldWorle")); + + _dbus_string_free (&str); + _dbus_string_free (&other); + /* Check append/get unichar */ if (!_dbus_string_init (&str, _DBUS_INT_MAX)) |