summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-string.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-01-26 07:48:16 +0000
committerHavoc Pennington <hp@redhat.com>2003-01-26 07:48:16 +0000
commit50c25505f62786756519ef1e194883360eda82e0 (patch)
tree968d4b0b148a78a665ea7b023350047e070aafed /dbus/dbus-string.c
parentd5ad082fecbbd803fd89b3574ac137b3fa964bc7 (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.c128
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))