summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2004-12-19 16:23:09 +0000
committerHavoc Pennington <hp@redhat.com>2004-12-19 16:23:09 +0000
commit617e73f7631e605fc9ebf6a67042a1f451b97850 (patch)
treea83539d7c9c92f422d2dca3026c8e19f522a0766 /dbus
parent305a8d4d988a1011982e284e358165d3368067cc (diff)
2004-12-19 Havoc Pennington <hp@redhat.com>
* dbus/dbus-string.c (_dbus_string_insert_4_aligned) (_dbus_string_insert_8_aligned): new functions * dbus/dbus-string.c (_dbus_string_alloc_space): new function
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-marshal-basic.c203
-rw-r--r--dbus/dbus-marshal-basic.h71
-rw-r--r--dbus/dbus-marshal-recursive.c362
-rw-r--r--dbus/dbus-marshal-recursive.h44
-rw-r--r--dbus/dbus-protocol-new.h3
-rw-r--r--dbus/dbus-string.c197
-rw-r--r--dbus/dbus-string.h11
7 files changed, 657 insertions, 234 deletions
diff --git a/dbus/dbus-marshal-basic.c b/dbus/dbus-marshal-basic.c
index 76477279..d325d5f0 100644
--- a/dbus/dbus-marshal-basic.c
+++ b/dbus/dbus-marshal-basic.c
@@ -22,11 +22,12 @@
*
*/
-#include "dbus-marshal-basic.h"
#include "dbus-internals.h"
#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
#include "dbus-string-private.h"
+#include "dbus-marshal-basic.h"
+
#include <string.h>
/**
@@ -85,7 +86,7 @@ typedef union
{
#ifdef DBUS_HAVE_INT64
dbus_int64_t s; /**< 64-bit integer */
- dbus_uint64_t u; /**< 64-bit unsinged integer */
+ dbus_uint64_t u; /**< 64-bit unsigned integer */
#endif
double d; /**< double */
} DBusOctets8;
@@ -462,6 +463,7 @@ _dbus_marshal_set_object_path (DBusString *str,
static dbus_bool_t
marshal_4_octets (DBusString *str,
+ int insert_at,
int byte_order,
dbus_uint32_t value)
{
@@ -470,12 +472,13 @@ marshal_4_octets (DBusString *str,
if (byte_order != DBUS_COMPILER_BYTE_ORDER)
value = DBUS_UINT32_SWAP_LE_BE (value);
- return _dbus_string_append_4_aligned (str,
+ return _dbus_string_insert_4_aligned (str, insert_at,
(const unsigned char *)&value);
}
static dbus_bool_t
marshal_8_octets (DBusString *str,
+ int insert_at,
int byte_order,
DBusOctets8 value)
{
@@ -484,7 +487,7 @@ marshal_8_octets (DBusString *str,
if (byte_order != DBUS_COMPILER_BYTE_ORDER)
pack_8_octets (value, byte_order, (unsigned char*) &value); /* pack into self, swapping as we go */
- return _dbus_string_append_8_aligned (str,
+ return _dbus_string_insert_8_aligned (str, insert_at,
(const unsigned char *)&value);
}
@@ -503,7 +506,8 @@ _dbus_marshal_double (DBusString *str,
{
DBusOctets8 r;
r.d = value;
- return marshal_8_octets (str, byte_order, r);
+ return marshal_8_octets (str, _dbus_string_get_length (str),
+ byte_order, r);
}
/**
@@ -519,7 +523,8 @@ _dbus_marshal_int32 (DBusString *str,
int byte_order,
dbus_int32_t value)
{
- return marshal_4_octets (str, byte_order, (dbus_uint32_t) value);
+ return marshal_4_octets (str, _dbus_string_get_length (str),
+ byte_order, (dbus_uint32_t) value);
}
/**
@@ -531,11 +536,12 @@ _dbus_marshal_int32 (DBusString *str,
* @returns #TRUE on success
*/
dbus_bool_t
-_dbus_marshal_uint32 (DBusString *str,
- int byte_order,
- dbus_uint32_t value)
+_dbus_marshal_uint32 (DBusString *str,
+ int byte_order,
+ dbus_uint32_t value)
{
- return marshal_4_octets (str, byte_order, value);
+ return marshal_4_octets (str, _dbus_string_get_length (str),
+ byte_order, value);
}
@@ -555,7 +561,8 @@ _dbus_marshal_int64 (DBusString *str,
{
DBusOctets8 r;
r.s = value;
- return marshal_8_octets (str, byte_order, r);
+ return marshal_8_octets (str, _dbus_string_get_length (str),
+ byte_order, r);
}
/**
@@ -573,7 +580,8 @@ _dbus_marshal_uint64 (DBusString *str,
{
DBusOctets8 r;
r.u = value;
- return marshal_8_octets (str, byte_order, r);
+ return marshal_8_octets (str, _dbus_string_get_length (str),
+ byte_order, r);
}
#endif /* DBUS_HAVE_INT64 */
@@ -930,7 +938,7 @@ _dbus_marshal_string_array (DBusString *str,
* @param path_len length of the path
* @returns #TRUE on success
*/
-dbus_bool_t
+static dbus_bool_t
_dbus_marshal_object_path (DBusString *str,
int byte_order,
const char **path,
@@ -1160,7 +1168,15 @@ _dbus_demarshal_basic_type (const DBusString *str,
#endif
*pos += 8;
break;
+ case DBUS_TYPE_STRING:
+ _dbus_assert_not_reached ("FIXME string is a basic type");
+ break;
+ case DBUS_TYPE_OBJECT_PATH:
+ _dbus_assert_not_reached ("FIXME object path is a basic type");
+ break;
default:
+ _dbus_verbose ("type %s not a basic type\n",
+ _dbus_type_to_string (type));
_dbus_assert_not_reached ("not a basic type");
break;
}
@@ -1746,6 +1762,74 @@ _dbus_demarshal_object_path (const DBusString *str,
return TRUE;
}
+/**
+ * Skips over a basic type, reporting the following position.
+ *
+ * @param str the string containing the data
+ * @param type type of value to demarshal
+ * @param byte_order the byte order
+ * @param pos pointer to position in the string,
+ * updated on return to new position
+ **/
+void
+_dbus_marshal_skip_basic_type (const DBusString *str,
+ int type,
+ int byte_order,
+ int *pos)
+{
+ switch (type)
+ {
+ case DBUS_TYPE_BYTE:
+ case DBUS_TYPE_BOOLEAN:
+ (*pos)++;
+ break;
+ case DBUS_TYPE_INT32:
+ case DBUS_TYPE_UINT32:
+ *pos = _DBUS_ALIGN_VALUE (*pos, 4);
+ *pos += 4;
+ break;
+#ifdef DBUS_HAVE_INT64
+ case DBUS_TYPE_INT64:
+ case DBUS_TYPE_UINT64:
+#endif /* DBUS_HAVE_INT64 */
+ case DBUS_TYPE_DOUBLE:
+ *pos = _DBUS_ALIGN_VALUE (*pos, 8);
+ *pos += 8;
+ break;
+ case DBUS_TYPE_STRING:
+ _dbus_assert_not_reached ("FIXME string is a basic type");
+ break;
+ case DBUS_TYPE_OBJECT_PATH:
+ _dbus_assert_not_reached ("FIXME object path is a basic type");
+ break;
+ default:
+ _dbus_verbose ("type %s not a basic type\n",
+ _dbus_type_to_string (type));
+ _dbus_assert_not_reached ("not a basic type");
+ break;
+ }
+}
+
+/**
+ * Skips an array, returning the next position.
+ *
+ * @param str the string containing the data
+ * @param byte_order the byte order
+ * @param pos pointer to position in the string,
+ * updated on return to new position
+ */
+void
+_dbus_marshal_skip_array (const DBusString *str,
+ int byte_order,
+ int *pos)
+{
+ int len;
+
+ len = _dbus_demarshal_uint32 (str, byte_order, *pos, pos);
+
+ *pos += len;
+}
+
/**
* Returns the position right after the end of an argument. PERFORMS
* NO VALIDATION WHATSOEVER. The message must have been previously
@@ -1775,10 +1859,6 @@ _dbus_marshal_get_arg_end_pos (const DBusString *str,
return FALSE;
break;
- case DBUS_TYPE_NIL:
- *end_pos = pos;
- break;
-
case DBUS_TYPE_BYTE:
*end_pos = pos + 1;
break;
@@ -1810,22 +1890,6 @@ _dbus_marshal_get_arg_end_pos (const DBusString *str,
*end_pos = pos + len + 1;
}
break;
-
- case DBUS_TYPE_CUSTOM:
- {
- int len;
-
- /* Demarshal the string length */
- len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-
- pos += len + 1;
-
- /* Demarshal the data length */
- len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
-
- *end_pos = pos + len;
- }
- break;
case DBUS_TYPE_ARRAY:
{
@@ -2002,12 +2066,8 @@ validate_array_data (const DBusString *str,
return FALSE;
break;
- case DBUS_TYPE_NIL:
- break;
-
case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_STRING:
- case DBUS_TYPE_CUSTOM:
case DBUS_TYPE_ARRAY:
case DBUS_TYPE_DICT:
/* This clean recursion to validate_arg is what we
@@ -2127,10 +2187,6 @@ _dbus_marshal_validate_arg (const DBusString *str,
return FALSE;
break;
- case DBUS_TYPE_NIL:
- *end_pos = pos;
- break;
-
case DBUS_TYPE_BYTE:
if (1 > _dbus_string_get_length (str) - pos)
{
@@ -2220,29 +2276,6 @@ _dbus_marshal_validate_arg (const DBusString *str,
}
}
break;
-
- case DBUS_TYPE_CUSTOM:
- {
- int len;
-
- /* Demarshal the string length, which does NOT include
- * nul termination
- */
- len = demarshal_and_validate_len (str, byte_order, pos, &pos);
- if (len < 0)
- return FALSE;
-
- if (!validate_string (str, pos, len, &pos))
- return FALSE;
-
- /* Validate data */
- len = demarshal_and_validate_len (str, byte_order, pos, &pos);
- if (len < 0)
- return FALSE;
-
- *end_pos = pos + len;
- }
- break;
case DBUS_TYPE_ARRAY:
{
@@ -2261,16 +2294,6 @@ _dbus_marshal_validate_arg (const DBusString *str,
_dbus_verbose ("invalid array type\n");
return FALSE;
}
-
- /* NIL values take up no space, so you couldn't iterate over an array of them.
- * array of nil seems useless anyway; the useful thing might be array of
- * (nil OR string) but we have no framework for that.
- */
- if (array_type == DBUS_TYPE_NIL)
- {
- _dbus_verbose ("array of NIL is not allowed\n");
- return FALSE;
- }
}
while (array_type == DBUS_TYPE_ARRAY);
}
@@ -2397,7 +2420,6 @@ _dbus_type_is_valid (int typecode)
{
switch (typecode)
{
- case DBUS_TYPE_NIL:
case DBUS_TYPE_BYTE:
case DBUS_TYPE_BOOLEAN:
case DBUS_TYPE_INT32:
@@ -2406,7 +2428,6 @@ _dbus_type_is_valid (int typecode)
case DBUS_TYPE_UINT64:
case DBUS_TYPE_DOUBLE:
case DBUS_TYPE_STRING:
- case DBUS_TYPE_CUSTOM:
case DBUS_TYPE_ARRAY:
case DBUS_TYPE_DICT:
case DBUS_TYPE_OBJECT_PATH:
@@ -2457,7 +2478,7 @@ _dbus_verbose_bytes (const unsigned char *data,
if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
{
_dbus_verbose ("%4d\t%p: ",
- i, &data[i]);
+ i, &data[i]);
}
if (data[i] >= 32 &&
@@ -2465,7 +2486,7 @@ _dbus_verbose_bytes (const unsigned char *data,
_dbus_verbose (" '%c' ", data[i]);
else
_dbus_verbose ("0x%s%x ",
- data[i] <= 0xf ? "0" : "", data[i]);
+ data[i] <= 0xf ? "0" : "", data[i]);
++i;
@@ -2532,6 +2553,7 @@ _dbus_verbose_bytes_of_string (const DBusString *str,
* Marshals a basic type
*
* @param str string to marshal to
+ * @param insert_at where to insert the value
* @param type type of value
* @param value pointer to value
* @param byte_order byte order
@@ -2539,8 +2561,9 @@ _dbus_verbose_bytes_of_string (const DBusString *str,
**/
dbus_bool_t
_dbus_marshal_basic_type (DBusString *str,
+ int insert_at,
char type,
- void *value,
+ const void *value,
int byte_order)
{
dbus_bool_t retval;
@@ -2549,20 +2572,28 @@ _dbus_marshal_basic_type (DBusString *str,
{
case DBUS_TYPE_BYTE:
case DBUS_TYPE_BOOLEAN:
- retval = _dbus_string_append_byte (str, *(unsigned char *)value);
+ retval = _dbus_string_insert_byte (str, insert_at, *(const unsigned char *)value);
break;
case DBUS_TYPE_INT32:
case DBUS_TYPE_UINT32:
- return marshal_4_octets (str, byte_order, *(dbus_uint32_t *)value);
+ return marshal_4_octets (str, insert_at, byte_order, *(const dbus_uint32_t *)value);
break;
#ifdef DBUS_HAVE_INT64
case DBUS_TYPE_INT64:
- case DBUS_TYPE_UINT64:
- retval = _dbus_marshal_uint64 (str, byte_order, *(dbus_uint64_t *)value);
+ case DBUS_TYPE_UINT64:
+ {
+ DBusOctets8 r;
+ r.u = *(const dbus_uint64_t *)value;
+ retval = marshal_8_octets (str, insert_at, byte_order, r);
+ }
break;
#endif /* DBUS_HAVE_INT64 */
case DBUS_TYPE_DOUBLE:
- retval = _dbus_marshal_double (str, byte_order, *(double *)value);
+ {
+ DBusOctets8 r;
+ r.d = *(const double *)value;
+ retval = marshal_8_octets (str, insert_at, byte_order, r);
+ }
break;
default:
_dbus_assert_not_reached ("not a basic type");
@@ -2576,6 +2607,7 @@ _dbus_marshal_basic_type (DBusString *str,
* Marshals a basic type array
*
* @param str string to marshal to
+ * @param insert_at where to insert the value
* @param element_type type of array elements
* @param value pointer to value
* @param len length of value data in elements
@@ -2584,11 +2616,14 @@ _dbus_marshal_basic_type (DBusString *str,
**/
dbus_bool_t
_dbus_marshal_basic_type_array (DBusString *str,
+ int insert_at,
char element_type,
const void *value,
int len,
int byte_order)
{
+ /* FIXME use the insert_at arg */
+
switch (element_type)
{
case DBUS_TYPE_BOOLEAN:
diff --git a/dbus/dbus-marshal-basic.h b/dbus/dbus-marshal-basic.h
index 25db7cc5..e8c0b3fb 100644
--- a/dbus/dbus-marshal-basic.h
+++ b/dbus/dbus-marshal-basic.h
@@ -37,6 +37,8 @@
/****************************************************** Remove later */
#undef DBUS_TYPE_INVALID
+#undef DBUS_TYPE_NIL
+#undef DBUS_TYPE_CUSTOM
#undef DBUS_TYPE_BYTE
#undef DBUS_TYPE_INT32
#undef DBUS_TYPE_UINT32
@@ -83,7 +85,43 @@
/* characters other than typecodes that appear in type signatures */
#define DBUS_STRUCT_BEGIN_CHAR ((int) '(')
#define DBUS_STRUCT_END_CHAR ((int) ')')
-#define DBUS_NAME_DELIMITER_CHAR ((int) '\'')
+
+static const char *
+_hack_dbus_type_to_string (int type)
+{
+ switch (type)
+ {
+ case DBUS_TYPE_INVALID:
+ return "invalid";
+ case DBUS_TYPE_BOOLEAN:
+ return "boolean";
+ case DBUS_TYPE_INT32:
+ return "int32";
+ case DBUS_TYPE_UINT32:
+ return "uint32";
+ case DBUS_TYPE_DOUBLE:
+ return "double";
+ case DBUS_TYPE_STRING:
+ return "string";
+ case DBUS_TYPE_STRUCT:
+ return "struct";
+ case DBUS_TYPE_ARRAY:
+ return "array";
+ case DBUS_TYPE_DICT:
+ return "dict";
+ case DBUS_TYPE_VARIANT:
+ return "variant";
+ case DBUS_STRUCT_BEGIN_CHAR:
+ return "begin_struct";
+ case DBUS_STRUCT_END_CHAR:
+ return "end_struct";
+ default:
+ return "unknown";
+ }
+}
+
+#define _dbus_type_to_string(t) _hack_dbus_type_to_string(t)
+
/****************************************************** Remove later */
#ifdef WORDS_BIGENDIAN
@@ -222,6 +260,7 @@ dbus_bool_t _dbus_marshal_int32 (DBusString *str,
dbus_bool_t _dbus_marshal_uint32 (DBusString *str,
int byte_order,
dbus_uint32_t value);
+
#ifdef DBUS_HAVE_INT64
dbus_bool_t _dbus_marshal_int64 (DBusString *str,
int byte_order,
@@ -233,6 +272,7 @@ dbus_bool_t _dbus_marshal_uint64 (DBusString *str,
dbus_bool_t _dbus_marshal_double (DBusString *str,
int byte_order,
double value);
+
dbus_bool_t _dbus_marshal_string (DBusString *str,
int byte_order,
const char *value);
@@ -240,10 +280,18 @@ dbus_bool_t _dbus_marshal_string_len (DBusString *str,
int byte_order,
const char *value,
int len);
+
dbus_bool_t _dbus_marshal_basic_type (DBusString *str,
+ int insert_at,
char type,
- void *value,
+ const void *value,
int byte_order);
+dbus_bool_t _dbus_marshal_basic_type_array (DBusString *str,
+ int insert_at,
+ char element_type,
+ const void *value,
+ int len,
+ int byte_order);
dbus_bool_t _dbus_marshal_byte_array (DBusString *str,
int byte_order,
const unsigned char *value,
@@ -270,21 +318,10 @@ dbus_bool_t _dbus_marshal_double_array (DBusString *str,
int byte_order,
const double *value,
int len);
-dbus_bool_t _dbus_marshal_basic_type_array (DBusString *str,
- char element_type,
- const void *value,
- int len,
- int byte_order);
-
dbus_bool_t _dbus_marshal_string_array (DBusString *str,
int byte_order,
const char **value,
int len);
-dbus_bool_t _dbus_marshal_object_path (DBusString *str,
- int byte_order,
- const char **path,
- int path_len);
-
double _dbus_demarshal_double (const DBusString *str,
int byte_order,
int pos,
@@ -378,6 +415,14 @@ dbus_bool_t _dbus_demarshal_object_path (const DBusString *str,
char ***path,
int *path_len);
+void _dbus_marshal_skip_basic_type (const DBusString *str,
+ int type,
+ int byte_order,
+ int *pos);
+void _dbus_marshal_skip_array (const DBusString *str,
+ int byte_order,
+ int *pos);
+
dbus_bool_t _dbus_marshal_get_arg_end_pos (const DBusString *str,
int byte_order,
int type,
diff --git a/dbus/dbus-marshal-recursive.c b/dbus/dbus-marshal-recursive.c
index eb85a2c4..1962e629 100644
--- a/dbus/dbus-marshal-recursive.c
+++ b/dbus/dbus-marshal-recursive.c
@@ -37,76 +37,197 @@ _dbus_type_reader_init (DBusTypeReader *reader,
const DBusString *value_str,
int value_pos)
{
-
+ reader->byte_order = byte_order;
+ reader->type_str = type_str;
+ reader->type_pos = type_pos;
+ reader->value_str = value_str;
+ reader->value_pos = value_pos;
+ _dbus_verbose ("type reader %p init type_pos = %d value_pos = %d remaining sig '%s'\n",
+ reader, reader->type_pos, reader->value_pos,
+ _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
}
int
-_dbus_type_reader_get_value_end (DBusTypeReader *reader)
+_dbus_type_reader_get_current_type (DBusTypeReader *reader)
{
+ int t;
+ t = _dbus_string_get_byte (reader->type_str,
+ reader->type_pos);
-}
-
-int
-_dbus_type_reader_get_type_end (DBusTypeReader *reader)
-{
+ if (t == DBUS_STRUCT_BEGIN_CHAR)
+ t = DBUS_TYPE_STRUCT;
+ /* this should never be a stopping place */
+ _dbus_assert (t != DBUS_STRUCT_END_CHAR);
+#if 0
+ _dbus_verbose ("type reader %p current type_pos = %d type = %s\n",
+ reader, reader->type_pos,
+ _dbus_type_to_string (t));
+#endif
+
+ return t;
}
int
-_dbus_type_reader_get_current_type (DBusTypeReader *reader)
+_dbus_type_reader_get_array_type (DBusTypeReader *reader)
{
+ int t;
+ t = _dbus_type_reader_get_current_type (reader);
-}
-
-int
-_dbus_type_reader_get_array_type (DBusTypeReader *reader)
-{
-
+ if (t != DBUS_TYPE_ARRAY)
+ return DBUS_TYPE_INVALID;
+ t = _dbus_string_get_byte (reader->type_str,
+ reader->type_pos + 1);
+
+ return t;
}
void
_dbus_type_reader_read_basic (DBusTypeReader *reader,
void *value)
{
+ int t;
+ int next;
+ t = _dbus_type_reader_get_current_type (reader);
+ next = reader->value_pos;
+ _dbus_demarshal_basic_type (reader->value_str,
+ t, value,
+ reader->byte_order,
+ &next);
+
+ _dbus_verbose ("type reader %p read basic type_pos = %d value_pos = %d next = %d remaining sig '%s'\n",
+ reader, reader->type_pos, reader->value_pos, next,
+ _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
+
+ _dbus_verbose_bytes_of_string (reader->value_str,
+ reader->value_pos,
+ MIN (16,
+ _dbus_string_get_length (reader->value_str) - reader->value_pos));
}
dbus_bool_t
-_dbus_type_reader_read_array (DBusTypeReader *reader,
- int type,
- void **array,
- int *array_len)
+_dbus_type_reader_read_array_of_basic (DBusTypeReader *reader,
+ int type,
+ void **array,
+ int *array_len)
{
-
-
+
+
}
+/**
+ * Initialize a new reader pointing to the first type and
+ * corresponding value that's a child of the current container. It's
+ * an error to call this if the current type is a non-container.
+ *
+ * @param reader the reader
+ * @param sub a reader to init pointing to the first child
+ */
void
-_dbus_type_reader_recurse (DBusTypeReader *reader)
+_dbus_type_reader_recurse (DBusTypeReader *reader,
+ DBusTypeReader *sub)
{
+ int t;
+ t = _dbus_string_get_byte (reader->type_str, reader->type_pos);
+
+ /* point subreader at the same place as reader */
+ _dbus_type_reader_init (sub,
+ reader->byte_order,
+ reader->type_str,
+ reader->type_pos,
+ reader->value_str,
+ reader->value_pos);
-}
-
-void
-_dbus_type_reader_unrecurse (DBusTypeReader *reader)
-{
+ _dbus_assert (t == DBUS_STRUCT_BEGIN_CHAR); /* only this works right now */
+
+ sub->type_pos += 1;
+ /* no value_pos increment since the struct itself doesn't take up value space */
+ _dbus_verbose ("type reader %p recursed type_pos = %d value_pos = %d remaining sig '%s'\n",
+ sub, sub->type_pos, sub->value_pos,
+ _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0));
}
+/**
+ * Skip to the next value on this "level". e.g. the next field in a
+ * struct, the next value in an array, the next key or value in a
+ * dict. Returns FALSE at the end of the current container.
+ *
+ * @param reader the reader
+ * @returns FALSE if nothing more to read at or below this level
+ */
dbus_bool_t
-_dbus_type_reader_next (DBusTypeReader *reader)
+_dbus_type_reader_next (DBusTypeReader *reader)
{
+ int t;
+ /* FIXME handled calling next when there's no next */
+
+ t = _dbus_string_get_byte (reader->type_str, reader->type_pos);
+
+ _dbus_verbose ("type reader %p next() { type_pos = %d value_pos = %d remaining sig '%s'\n",
+ reader, reader->type_pos, reader->value_pos,
+ _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
+
+ switch (t)
+ {
+ case DBUS_STRUCT_BEGIN_CHAR:
+ /* Scan forward over the entire container contents */
+ {
+ DBusTypeReader sub;
+
+ /* Recurse into the struct */
+ _dbus_type_reader_recurse (reader, &sub);
+
+ /* Skip everything in this subreader */
+ while (_dbus_type_reader_next (&sub))
+ {
+ /* nothing */;
+ }
+
+ /* Now we are at the end of this container */
+ reader->type_pos = sub.type_pos;
+ reader->value_pos = sub.value_pos;
+ }
+ break;
+
+ default:
+ /* FIXME for array etc. this is more complicated */
+ _dbus_marshal_skip_basic_type (reader->value_str,
+ t, reader->byte_order,
+ &reader->value_pos);
+ reader->type_pos += 1;
+ break;
+ }
+ _dbus_verbose ("type reader %p } type_pos = %d value_pos = %d remaining sig '%s'\n",
+ reader, reader->type_pos, reader->value_pos,
+ _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0));
+ /* FIXME this is wrong; we need to return FALSE when we finish the
+ * container we've recursed into; even if the signature continues.
+ */
+
+ t = _dbus_string_get_byte (reader->type_str, reader->type_pos);
+
+ if (t == DBUS_STRUCT_END_CHAR)
+ {
+ reader->type_pos += 1;
+ return FALSE;
+ }
+ if (t == DBUS_TYPE_INVALID)
+ return FALSE;
+
+ return TRUE;
}
void
@@ -117,8 +238,12 @@ _dbus_type_writer_init (DBusTypeWriter *writer,
DBusString *value_str,
int value_pos)
{
-
-
+ writer->byte_order = byte_order;
+ writer->type_str = type_str;
+ writer->type_pos = type_pos;
+ writer->value_str = value_str;
+ writer->value_pos = value_pos;
+ writer->container_type = DBUS_TYPE_INVALID;
}
dbus_bool_t
@@ -126,8 +251,38 @@ _dbus_type_writer_write_basic (DBusTypeWriter *writer,
int type,
const void *value)
{
+ dbus_bool_t retval;
+ int old_value_len;
+ old_value_len = _dbus_string_get_length (writer->value_str);
+
+ /* First ensure that our type realloc will succeed */
+ if (!_dbus_string_alloc_space (writer->type_str, 1))
+ return FALSE;
+ retval = FALSE;
+
+ if (!_dbus_marshal_basic_type (writer->value_str,
+ writer->value_pos,
+ type,
+ value,
+ writer->byte_order))
+ goto out;
+
+ writer->value_pos += _dbus_string_get_length (writer->value_str) - old_value_len;
+
+ /* Now insert the type */
+ if (!_dbus_string_insert_byte (writer->type_str,
+ writer->type_pos,
+ type))
+ _dbus_assert_not_reached ("failed to insert byte after prealloc");
+
+ writer->type_pos += 1;
+
+ retval = TRUE;
+
+ out:
+ return retval;
}
dbus_bool_t
@@ -142,17 +297,57 @@ _dbus_type_writer_write_array (DBusTypeWriter *writer,
dbus_bool_t
_dbus_type_writer_recurse (DBusTypeWriter *writer,
- int container_type)
-{
-
-
+ int container_type,
+ DBusTypeWriter *sub)
+{
+ _dbus_type_writer_init (sub,
+ writer->byte_order,
+ writer->type_str,
+ writer->type_pos,
+ writer->value_str,
+ writer->value_pos);
+ sub->container_type = container_type;
+
+ switch (container_type)
+ {
+ case DBUS_TYPE_STRUCT:
+ {
+ if (!_dbus_string_insert_byte (sub->type_str,
+ sub->type_pos,
+ DBUS_STRUCT_BEGIN_CHAR))
+ return FALSE;
+
+ sub->type_pos += 1;
+ }
+ break;
+ default:
+ _dbus_assert_not_reached ("container_type unhandled");
+ break;
+ }
+
+ return TRUE;
}
dbus_bool_t
-_dbus_type_writer_unrecurse (DBusTypeWriter *writer)
+_dbus_type_writer_unrecurse (DBusTypeWriter *writer,
+ DBusTypeWriter *sub)
{
+ _dbus_assert (sub->type_pos > 0); /* can't be recursed if this fails */
+ if (sub->container_type == DBUS_TYPE_STRUCT)
+ {
+ if (!_dbus_string_insert_byte (sub->type_str,
+ sub->type_pos,
+ DBUS_STRUCT_END_CHAR))
+ return FALSE;
+ sub->type_pos += 1;
+ }
+ /* Jump the parent writer to the new location */
+ writer->type_pos = sub->type_pos;
+ writer->value_pos = sub->value_pos;
+
+ return TRUE;
}
/** @} */ /* end of DBusMarshal group */
@@ -266,6 +461,12 @@ check_expected_type (DBusTypeReader *reader,
_dbus_warn ("Read type %s while expecting %s\n",
_dbus_type_to_string (t),
_dbus_type_to_string (expected));
+
+ _dbus_verbose_bytes_of_string (reader->type_str, 0,
+ _dbus_string_get_length (reader->type_str));
+ _dbus_verbose_bytes_of_string (reader->value_str, 0,
+ _dbus_string_get_length (reader->value_str));
+
exit (1);
}
}
@@ -292,15 +493,17 @@ write_struct_with_int32s (DataBlock *block,
{
dbus_int32_t v;
DataBlockState saved;
+ DBusTypeWriter sub;
data_block_save (block, &saved);
if (!_dbus_type_writer_recurse (writer,
- DBUS_TYPE_STRUCT))
+ DBUS_TYPE_STRUCT,
+ &sub))
return FALSE;
v = SAMPLE_INT32;
- if (!_dbus_type_writer_write_basic (writer,
+ if (!_dbus_type_writer_write_basic (&sub,
DBUS_TYPE_INT32,
&v))
{
@@ -309,7 +512,7 @@ write_struct_with_int32s (DataBlock *block,
}
v = SAMPLE_INT32_ALTERNATE;
- if (!_dbus_type_writer_write_basic (writer,
+ if (!_dbus_type_writer_write_basic (&sub,
DBUS_TYPE_INT32,
&v))
{
@@ -317,7 +520,7 @@ write_struct_with_int32s (DataBlock *block,
return FALSE;
}
- if (!_dbus_type_writer_unrecurse (writer))
+ if (!_dbus_type_writer_unrecurse (writer, &sub))
{
data_block_restore (block, &saved);
return FALSE;
@@ -331,27 +534,26 @@ read_struct_with_int32s (DataBlock *block,
DBusTypeReader *reader)
{
dbus_int32_t v;
+ DBusTypeReader sub;
check_expected_type (reader, DBUS_TYPE_STRUCT);
- _dbus_type_reader_recurse (reader);
+ _dbus_type_reader_recurse (reader, &sub);
- check_expected_type (reader, DBUS_TYPE_INT32);
+ check_expected_type (&sub, DBUS_TYPE_INT32);
- _dbus_type_reader_read_basic (reader,
+ _dbus_type_reader_read_basic (&sub,
(dbus_int32_t*) &v);
_dbus_assert (v == SAMPLE_INT32);
- _dbus_type_reader_next (reader);
- check_expected_type (reader, DBUS_TYPE_INT32);
+ _dbus_type_reader_next (&sub);
+ check_expected_type (&sub, DBUS_TYPE_INT32);
- _dbus_type_reader_read_basic (reader,
+ _dbus_type_reader_read_basic (&sub,
(dbus_int32_t*) &v);
_dbus_assert (v == SAMPLE_INT32_ALTERNATE);
-
- _dbus_type_reader_unrecurse (reader);
return TRUE;
}
@@ -361,30 +563,32 @@ write_struct_of_structs (DataBlock *block,
DBusTypeWriter *writer)
{
DataBlockState saved;
+ DBusTypeWriter sub;
data_block_save (block, &saved);
if (!_dbus_type_writer_recurse (writer,
- DBUS_TYPE_STRUCT))
+ DBUS_TYPE_STRUCT,
+ &sub))
return FALSE;
- if (!write_struct_with_int32s (block, writer))
+ if (!write_struct_with_int32s (block, &sub))
{
data_block_restore (block, &saved);
return FALSE;
}
- if (!write_struct_with_int32s (block, writer))
+ if (!write_struct_with_int32s (block, &sub))
{
data_block_restore (block, &saved);
return FALSE;
}
- if (!write_struct_with_int32s (block, writer))
+ if (!write_struct_with_int32s (block, &sub))
{
data_block_restore (block, &saved);
return FALSE;
}
- if (!_dbus_type_writer_unrecurse (writer))
+ if (!_dbus_type_writer_unrecurse (writer, &sub))
{
data_block_restore (block, &saved);
return FALSE;
@@ -397,20 +601,20 @@ static dbus_bool_t
read_struct_of_structs (DataBlock *block,
DBusTypeReader *reader)
{
+ DBusTypeReader sub;
+
check_expected_type (reader, DBUS_TYPE_STRUCT);
- _dbus_type_reader_recurse (reader);
+ _dbus_type_reader_recurse (reader, &sub);
- if (!read_struct_with_int32s (block, reader))
+ if (!read_struct_with_int32s (block, &sub))
return FALSE;
- _dbus_type_reader_next (reader);
- if (!read_struct_with_int32s (block, reader))
+ _dbus_type_reader_next (&sub);
+ if (!read_struct_with_int32s (block, &sub))
return FALSE;
- _dbus_type_reader_next (reader);
- if (!read_struct_with_int32s (block, reader))
+ _dbus_type_reader_next (&sub);
+ if (!read_struct_with_int32s (block, &sub))
return FALSE;
-
- _dbus_type_reader_unrecurse (reader);
return TRUE;
}
@@ -420,25 +624,27 @@ write_struct_of_structs_of_structs (DataBlock *block,
DBusTypeWriter *writer)
{
DataBlockState saved;
+ DBusTypeWriter sub;
data_block_save (block, &saved);
if (!_dbus_type_writer_recurse (writer,
- DBUS_TYPE_STRUCT))
+ DBUS_TYPE_STRUCT,
+ &sub))
return FALSE;
- if (!write_struct_of_structs (block, writer))
+ if (!write_struct_of_structs (block, &sub))
{
data_block_restore (block, &saved);
return FALSE;
}
- if (!write_struct_of_structs (block, writer))
+ if (!write_struct_of_structs (block, &sub))
{
data_block_restore (block, &saved);
return FALSE;
}
- if (!_dbus_type_writer_unrecurse (writer))
+ if (!_dbus_type_writer_unrecurse (writer, &sub))
{
data_block_restore (block, &saved);
return FALSE;
@@ -451,17 +657,17 @@ static dbus_bool_t
read_struct_of_structs_of_structs (DataBlock *block,
DBusTypeReader *reader)
{
+ DBusTypeReader sub;
+
check_expected_type (reader, DBUS_TYPE_STRUCT);
- _dbus_type_reader_recurse (reader);
+ _dbus_type_reader_recurse (reader, &sub);
- if (!read_struct_of_structs (block, reader))
+ if (!read_struct_of_structs (block, &sub))
return FALSE;
- _dbus_type_reader_next (reader);
- if (!read_struct_of_structs (block, reader))
+ _dbus_type_reader_next (&sub);
+ if (!read_struct_of_structs (block, &sub))
return FALSE;
-
- _dbus_type_reader_unrecurse (reader);
return TRUE;
}
@@ -483,16 +689,21 @@ typedef dbus_bool_t (* ReadItemFunc) (DataBlock *block,
typedef struct
{
+ const char *desc;
WhichItem which;
WriteItemFunc write_item_func;
ReadItemFunc read_item_func;
} CheckMarshalItem;
static CheckMarshalItem items[] = {
- { ITEM_INT32, write_int32, read_int32 },
- { ITEM_STRUCT_WITH_INT32S, write_struct_with_int32s, read_struct_with_int32s },
- { ITEM_STRUCT_OF_STRUCTS, write_struct_of_structs, read_struct_of_structs },
- { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS,
+ { "int32",
+ ITEM_INT32, write_int32, read_int32 },
+ { "struct with two int32",
+ ITEM_STRUCT_WITH_INT32S, write_struct_with_int32s, read_struct_with_int32s },
+ { "struct with three structs of two int32",
+ ITEM_STRUCT_OF_STRUCTS, write_struct_of_structs, read_struct_of_structs },
+ { "struct of two structs of three structs of two int32",
+ ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS,
write_struct_of_structs_of_structs,
read_struct_of_structs_of_structs }
};
@@ -559,6 +770,9 @@ perform_one_run (DataBlock *block,
while (run->items[i] != ITEM_INVALID)
{
CheckMarshalItem *item = &items[run->items[i]];
+
+ _dbus_verbose ("writing %s\n", item->desc);
+
if (!(* item->write_item_func) (block, &writer))
goto out;
++i;
@@ -568,6 +782,8 @@ perform_one_run (DataBlock *block,
while (run->items[i] != ITEM_INVALID)
{
CheckMarshalItem *item = &items[run->items[i]];
+
+ _dbus_verbose ("reading %s\n", item->desc);
if (!(* item->read_item_func) (block, &reader))
goto out;
diff --git a/dbus/dbus-marshal-recursive.h b/dbus/dbus-marshal-recursive.h
index 19960ec8..ed70a827 100644
--- a/dbus/dbus-marshal-recursive.h
+++ b/dbus/dbus-marshal-recursive.h
@@ -67,30 +67,28 @@ struct DBusTypeWriter
int type_pos;
DBusString *value_str;
int value_pos;
+ int container_type;
};
typedef struct DBusTypeWriter DBusTypeWriter;
-void _dbus_type_reader_init (DBusTypeReader *reader,
- int byte_order,
- const DBusString *type_str,
- int type_pos,
- const DBusString *value_str,
- int value_pos);
-int _dbus_type_reader_get_value_end (DBusTypeReader *reader);
-int _dbus_type_reader_get_type_end (DBusTypeReader *reader);
-int _dbus_type_reader_get_current_type (DBusTypeReader *reader);
-int _dbus_type_reader_get_array_type (DBusTypeReader *reader);
-void _dbus_type_reader_read_basic (DBusTypeReader *reader,
- void *value);
-dbus_bool_t _dbus_type_reader_read_array (DBusTypeReader *reader,
- int type,
- void **array,
- int *array_len);
-void _dbus_type_reader_recurse (DBusTypeReader *reader);
-void _dbus_type_reader_unrecurse (DBusTypeReader *reader);
-dbus_bool_t _dbus_type_reader_next (DBusTypeReader *reader);
-
+void _dbus_type_reader_init (DBusTypeReader *reader,
+ int byte_order,
+ const DBusString *type_str,
+ int type_pos,
+ const DBusString *value_str,
+ int value_pos);
+int _dbus_type_reader_get_current_type (DBusTypeReader *reader);
+int _dbus_type_reader_get_array_type (DBusTypeReader *reader);
+void _dbus_type_reader_read_basic (DBusTypeReader *reader,
+ void *value);
+dbus_bool_t _dbus_type_reader_read_array_of_basic (DBusTypeReader *reader,
+ int type,
+ void **array,
+ int *array_len);
+void _dbus_type_reader_recurse (DBusTypeReader *reader,
+ DBusTypeReader *subreader);
+dbus_bool_t _dbus_type_reader_next (DBusTypeReader *reader);
void _dbus_type_writer_init (DBusTypeWriter *writer,
int byte_order,
@@ -106,7 +104,9 @@ dbus_bool_t _dbus_type_writer_write_array (DBusTypeWriter *writer,
const void *array,
int array_len);
dbus_bool_t _dbus_type_writer_recurse (DBusTypeWriter *writer,
- int container_type);
-dbus_bool_t _dbus_type_writer_unrecurse (DBusTypeWriter *writer);
+ int container_type,
+ DBusTypeWriter *sub);
+dbus_bool_t _dbus_type_writer_unrecurse (DBusTypeWriter *writer,
+ DBusTypeWriter *sub);
#endif /* DBUS_MARSHAL_RECURSIVE_H */
diff --git a/dbus/dbus-protocol-new.h b/dbus/dbus-protocol-new.h
index b029f0fb..9d8c4b6f 100644
--- a/dbus/dbus-protocol-new.h
+++ b/dbus/dbus-protocol-new.h
@@ -58,7 +58,7 @@ extern "C" {
/* Compound types */
#define DBUS_TYPE_ARRAY ((int) 'a')
-#define DBUS_TYPE_DICT ((int) 'm')
+#define DBUS_TYPE_DICT ((int) 'm') /* not parameterized; always map<string,variant> */
#define DBUS_TYPE_VARIANT ((int) 'v')
/* STRUCT is sort of special since its code can't appear in a type string,
@@ -72,7 +72,6 @@ extern "C" {
/* characters other than typecodes that appear in type signatures */
#define DBUS_STRUCT_BEGIN_CHAR ((int) '(')
#define DBUS_STRUCT_END_CHAR ((int) ')')
-#define DBUS_NAME_DELIMITER_CHAR ((int) '\'')
/* Max length in bytes of a service or interface or member name */
#define DBUS_MAXIMUM_NAME_LENGTH 256
diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c
index 1188c6cb..b4e626b5 100644
--- a/dbus/dbus-string.c
+++ b/dbus/dbus-string.c
@@ -612,6 +612,31 @@ _dbus_string_insert_bytes (DBusString *str,
}
/**
+ * Inserts a single byte at the given position.
+ *
+ * @param str the string
+ * @param i the position
+ * @param byte the value to insert
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+_dbus_string_insert_byte (DBusString *str,
+ int i,
+ unsigned char byte)
+{
+ DBUS_STRING_PREAMBLE (str);
+ _dbus_assert (i <= real->len);
+ _dbus_assert (i >= 0);
+
+ if (!open_gap (1, real, i))
+ return FALSE;
+
+ real->str[i] = byte;
+
+ return TRUE;
+}
+
+/**
* Like _dbus_string_get_data(), but removes the
* gotten data from the original string. The caller
* must free the data returned. This function may
@@ -875,43 +900,68 @@ _dbus_string_set_length (DBusString *str,
}
static dbus_bool_t
-align_length_then_lengthen (DBusString *str,
- int alignment,
- int then_lengthen_by)
+align_insert_point_then_open_gap (DBusString *str,
+ int *insert_at_p,
+ int alignment,
+ int gap_size)
{
unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
+ unsigned long gap_pos;
+ int insert_at;
int delta;
DBUS_STRING_PREAMBLE (str);
_dbus_assert (alignment >= 1);
_dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
- new_len = _DBUS_ALIGN_VALUE (real->len, alignment);
- if (_DBUS_UNLIKELY (new_len > (unsigned long) real->max_length - then_lengthen_by))
+ insert_at = *insert_at_p;
+
+ _dbus_assert (insert_at <= real->len);
+
+ gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
+ new_len = real->len + (gap_pos - insert_at) + gap_size;
+
+ if (_DBUS_UNLIKELY (new_len > (unsigned long) real->max_length))
return FALSE;
- new_len += then_lengthen_by;
delta = new_len - real->len;
_dbus_assert (delta >= 0);
- if (delta == 0)
- return TRUE;
+ if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
+ {
+ _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
+ return TRUE;
+ }
- if (_DBUS_UNLIKELY (!set_length (real, new_len)))
+ if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
+ real, insert_at)))
return FALSE;
- /* delta == padding + then_lengthen_by
- * new_len == old_len + padding + then_lengthen_by
- * nul the padding if we had to add any padding
- */
- if (then_lengthen_by < delta)
+ /* nul the padding if we had to add any padding */
+ if (gap_size < delta)
{
- memset (&real->str[new_len - delta], '\0',
- delta - then_lengthen_by);
+ memset (&real->str[insert_at], '\0',
+ gap_pos - insert_at);
}
-
+
+ *insert_at_p = gap_pos;
+
return TRUE;
}
+static dbus_bool_t
+align_length_then_lengthen (DBusString *str,
+ int alignment,
+ int then_lengthen_by)
+{
+ int insert_at;
+
+ insert_at = _dbus_string_get_length (str);
+
+ return align_insert_point_then_open_gap (str,
+ &insert_at,
+ alignment, then_lengthen_by);
+}
+
/**
* Align the length of a string to a specific alignment (typically 4 or 8)
* by appending nul bytes to the string.
@@ -927,6 +977,26 @@ _dbus_string_align_length (DBusString *str,
return align_length_then_lengthen (str, alignment, 0);
}
+/**
+ * Preallocate extra_bytes such that a future lengthening of the
+ * string by extra_bytes is guaranteed to succeed without an out of
+ * memory error.
+ *
+ * @param str a string
+ * @param extra_bytes bytes to alloc
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_string_alloc_space (DBusString *str,
+ int extra_bytes)
+{
+ if (!_dbus_string_lengthen (str, extra_bytes))
+ return FALSE;
+ _dbus_string_shorten (str, extra_bytes);
+
+ return TRUE;
+}
+
static dbus_bool_t
append (DBusRealString *real,
const char *buffer,
@@ -968,6 +1038,31 @@ _dbus_string_append (DBusString *str,
return append (real, buffer, buffer_len);
}
+#define ASSIGN_4_OCTETS(p, octets) \
+ *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
+
+#ifdef DBUS_HAVE_INT64
+#define ASSIGN_8_OCTETS(p, octets) \
+ *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
+#else
+#define ASSIGN_8_OCTETS(p, octets) \
+do { \
+ unsigned char *b; \
+ \
+ b = p; \
+ \
+ *b++ = octets[0]; \
+ *b++ = octets[1]; \
+ *b++ = octets[2]; \
+ *b++ = octets[3]; \
+ *b++ = octets[4]; \
+ *b++ = octets[5]; \
+ *b++ = octets[6]; \
+ *b++ = octets[7]; \
+ _dbus_assert (b == p + 8); \
+} while (0)
+#endif /* DBUS_HAVE_INT64 */
+
/**
* Appends 4 bytes aligned on a 4 byte boundary
* with any alignment padding initialized to 0.
@@ -980,14 +1075,12 @@ dbus_bool_t
_dbus_string_append_4_aligned (DBusString *str,
const unsigned char octets[4])
{
- dbus_uint32_t *p;
DBUS_STRING_PREAMBLE (str);
if (!align_length_then_lengthen (str, 4, 4))
return FALSE;
- p = (dbus_uint32_t*) (real->str + (real->len - 4));
- *p = *((dbus_uint32_t*)octets);
+ ASSIGN_4_OCTETS (real->str + (real->len - 4), octets);
return TRUE;
}
@@ -997,41 +1090,65 @@ _dbus_string_append_4_aligned (DBusString *str,
* with any alignment padding initialized to 0.
*
* @param str the DBusString
- * @param octets 4 bytes to append
+ * @param octets 8 bytes to append
* @returns #FALSE if not enough memory.
*/
dbus_bool_t
_dbus_string_append_8_aligned (DBusString *str,
const unsigned char octets[8])
{
-#ifdef DBUS_HAVE_INT64
- dbus_uint64_t *p;
DBUS_STRING_PREAMBLE (str);
if (!align_length_then_lengthen (str, 8, 8))
return FALSE;
- p = (dbus_uint64_t*) (real->str + (real->len - 8));
- *p = *((dbus_uint64_t*)octets);
-#else
- unsigned char *p;
+ ASSIGN_8_OCTETS (real->str + (real->len - 8), octets);
+
+ return TRUE;
+}
+
+/**
+ * Inserts 4 bytes aligned on a 4 byte boundary
+ * with any alignment padding initialized to 0.
+ *
+ * @param str the DBusString
+ * @param octets 4 bytes to insert
+ * @returns #FALSE if not enough memory.
+ */
+dbus_bool_t
+_dbus_string_insert_4_aligned (DBusString *str,
+ int insert_at,
+ const unsigned char octets[4])
+{
DBUS_STRING_PREAMBLE (str);
- if (!align_length_then_lengthen (str, 8, 8))
+ if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
return FALSE;
- p = real->str + (real->len - 8);
-
- *p++ = octets[0];
- *p++ = octets[1];
- *p++ = octets[2];
- *p++ = octets[3];
- *p++ = octets[4];
- *p++ = octets[5];
- *p++ = octets[6];
- *p++ = octets[7];
- _dbus_assert (p == (real->str + real->len));
-#endif
+ ASSIGN_4_OCTETS (real->str + insert_at, octets);
+
+ return TRUE;
+}
+
+/**
+ * Inserts 8 bytes aligned on an 8 byte boundary
+ * with any alignment padding initialized to 0.
+ *
+ * @param str the DBusString
+ * @param octets 8 bytes to insert
+ * @returns #FALSE if not enough memory.
+ */
+dbus_bool_t
+_dbus_string_insert_8_aligned (DBusString *str,
+ int insert_at,
+ const unsigned char octets[8])
+{
+ DBUS_STRING_PREAMBLE (str);
+
+ if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
+ return FALSE;
+
+ ASSIGN_8_OCTETS (real->str + insert_at, octets);
return TRUE;
}
diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h
index c30a63fe..2b8b09f5 100644
--- a/dbus/dbus-string.h
+++ b/dbus/dbus-string.h
@@ -90,6 +90,9 @@ dbus_bool_t _dbus_string_insert_bytes (DBusString *str,
int i,
int n_bytes,
unsigned char byte);
+dbus_bool_t _dbus_string_insert_byte (DBusString *str,
+ int i,
+ unsigned char byte);
dbus_bool_t _dbus_string_steal_data (DBusString *str,
char **data_return);
dbus_bool_t _dbus_string_steal_data_len (DBusString *str,
@@ -117,6 +120,8 @@ dbus_bool_t _dbus_string_set_length (DBusString *str,
int length);
dbus_bool_t _dbus_string_align_length (DBusString *str,
int alignment);
+dbus_bool_t _dbus_string_alloc_space (DBusString *str,
+ int extra_bytes);
dbus_bool_t _dbus_string_append (DBusString *str,
const char *buffer);
dbus_bool_t _dbus_string_append_len (DBusString *str,
@@ -142,6 +147,12 @@ dbus_bool_t _dbus_string_append_printf (DBusString *str,
dbus_bool_t _dbus_string_append_printf_valist (DBusString *str,
const char *format,
va_list args);
+dbus_bool_t _dbus_string_insert_4_aligned (DBusString *str,
+ int insert_at,
+ const unsigned char octets[4]);
+dbus_bool_t _dbus_string_insert_8_aligned (DBusString *str,
+ int insert_at,
+ const unsigned char octets[8]);
void _dbus_string_delete (DBusString *str,
int start,
int len);