Commit 0123e6a9 authored by Michael Meeks's avatar Michael Meeks

2004-05-28 Michael Meeks <michael@ximian.com>

	* glib/dbus-gvalue.c (dbus_gvalue_marshal, dbus_gvalue_demarshal):
	fix no int64 case.

	* dbus/dbus-string.c (_dbus_string_parse_basic_type): impl.

	* dbus/dbus-message.c (_dbus_message_iter_get_basic_type),
	(_dbus_message_iter_get_basic_type_array): impl.
	drastically simplify ~all relevant _get methods to use these.
	(_dbus_message_iter_append_basic_array),
	(dbus_message_iter_append_basic): impl
	drastically simplify ~all relevant _append methods to use these.

	* dbus/dbus-message-builder.c (parse_basic_type)
	(parse_basic_array, lookup_basic_type): impl.
	(_dbus_message_data_load): prune scads of duplicate /
	cut & paste coding.

	* dbus/dbus-marshal.c (_dbus_demarshal_basic_type_array)
	(_dbus_demarshal_basic_type): implement,
	(demarshal_and_validate_len/arg): beef up debug.
	(_dbus_marshal_basic_type, _dbus_marshal_basic_type_array): impl.
parent f33553ea
2004-05-28 Michael Meeks <michael@ximian.com>
* glib/dbus-gvalue.c (dbus_gvalue_marshal, dbus_gvalue_demarshal):
fix no int64 case.
* dbus/dbus-string.c (_dbus_string_parse_basic_type): impl.
* dbus/dbus-message.c (_dbus_message_iter_get_basic_type),
(_dbus_message_iter_get_basic_type_array): impl.
drastically simplify ~all relevant _get methods to use these.
(_dbus_message_iter_append_basic_array),
(dbus_message_iter_append_basic): impl
drastically simplify ~all relevant _append methods to use these.
* dbus/dbus-message-builder.c (parse_basic_type)
(parse_basic_array, lookup_basic_type): impl.
(_dbus_message_data_load): prune scads of duplicate /
cut & paste coding.
* dbus/dbus-marshal.c (_dbus_demarshal_basic_type_array)
(_dbus_demarshal_basic_type): implement,
(demarshal_and_validate_len/arg): beef up debug.
(_dbus_marshal_basic_type, _dbus_marshal_basic_type_array): impl.
2004-05-27 Seth Nickell <seth@gnome.org>
* configure.in:
......
......@@ -1067,6 +1067,61 @@ _dbus_demarshal_uint64 (const DBusString *str,
#endif /* DBUS_HAVE_INT64 */
/**
* Demarshals a basic type
*
* @param str the string containing the data
* @param type type of value to demarshal
* @param value pointer to return value data
* @param byte_order the byte order
* @param pos pointer to position in the string,
* updated on return to new position
**/
void
_dbus_demarshal_basic_type (const DBusString *str,
int type,
void *value,
int byte_order,
int *pos)
{
const char *str_data = _dbus_string_get_const_data (str);
switch (type)
{
case DBUS_TYPE_BYTE:
case DBUS_TYPE_BOOLEAN:
*(unsigned char *) value = _dbus_string_get_byte (str, *pos);
(*pos)++;
break;
case DBUS_TYPE_INT32:
case DBUS_TYPE_UINT32:
*pos = _DBUS_ALIGN_VALUE (*pos, 4);
*(dbus_uint32_t *) value = *(dbus_uint32_t *)(str_data + *pos);
if (byte_order != DBUS_COMPILER_BYTE_ORDER)
*(dbus_uint32_t *) value = DBUS_UINT32_SWAP_LE_BE (*(dbus_uint32_t *) value);
*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);
memcpy (value, str_data + *pos, 8);
if (byte_order != DBUS_COMPILER_BYTE_ORDER)
#ifdef DBUS_HAVE_INT64
*(dbus_uint64_t *) value = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t *) value);
#else
swap_bytes (value, 8);
#endif
*pos += 8;
break;
default:
_dbus_assert_not_reached ("not a basic type");
break;
}
}
/**
* Demarshals an UTF-8 string.
*
......@@ -1392,6 +1447,53 @@ _dbus_demarshal_double_array (const DBusString *str,
(DBusOctets8**) array, array_len);
}
/**
* Demarshals an array of basic types
*
* @param str the string containing the data
* @param element_type type of array elements to demarshal
* @param array pointer to pointer to array data
* @param array_len pointer to array length
* @param byte_order the byte order
* @param pos pointer to position in the string,
* updated on return to new position
**/
dbus_bool_t
_dbus_demarshal_basic_type_array (const DBusString *str,
int element_type,
void **array,
int *array_len,
int byte_order,
int *pos)
{
switch (element_type)
{
case DBUS_TYPE_BOOLEAN:
/* FIXME: do we want to post-normalize these ? */
case DBUS_TYPE_BYTE:
return _dbus_demarshal_byte_array (str, byte_order, *pos, pos,
(unsigned char **)array, array_len);
break;
case DBUS_TYPE_INT32:
case DBUS_TYPE_UINT32:
return demarshal_4_octets_array (str, byte_order, *pos, pos,
(dbus_uint32_t *) array, array_len);
break;
#ifdef DBUS_HAVE_INT64
case DBUS_TYPE_INT64:
case DBUS_TYPE_UINT64:
#endif /* DBUS_HAVE_INT64 */
case DBUS_TYPE_DOUBLE:
return demarshal_8_octets_array (str, byte_order, *pos, pos,
(DBusOctets8**) array, array_len);
default:
_dbus_assert_not_reached ("not a basic type");
break;
}
return FALSE;
}
/**
* Demarshals a string array.
*
......@@ -1725,7 +1827,7 @@ demarshal_and_validate_len (const DBusString *str,
if (!_dbus_string_validate_nul (str, pos,
align_4 - pos))
{
_dbus_verbose ("array length alignment padding not initialized to nul\n");
_dbus_verbose ("array length alignment padding not initialized to nul at %d\n", pos);
return -1;
}
......@@ -1740,8 +1842,8 @@ demarshal_and_validate_len (const DBusString *str,
#define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
if (len > MAX_ARRAY_LENGTH)
{
_dbus_verbose ("array length %u exceeds maximum of %u\n",
len, MAX_ARRAY_LENGTH);
_dbus_verbose ("array length %u exceeds maximum of %u at pos %d\n",
len, MAX_ARRAY_LENGTH, pos);
return -1;
}
else
......@@ -2021,7 +2123,7 @@ _dbus_marshal_validate_arg (const DBusString *str,
if (!_dbus_string_validate_nul (str, pos,
align_8 - pos))
{
_dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul\n");
_dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul at %d\n", pos);
return FALSE;
}
......@@ -2191,7 +2293,10 @@ _dbus_marshal_validate_arg (const DBusString *str,
/* Validate element */
if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
dict_type, -1, pos, &pos))
return FALSE;
{
_dbus_verbose ("dict arg invalid at offset %d\n", pos);
return FALSE;
}
}
if (pos > end)
......@@ -2356,6 +2461,93 @@ _dbus_verbose_bytes_of_string (const DBusString *str,
_dbus_verbose_bytes (d, len);
}
/**
* Marshals a basic type
*
* @param str string to marshal to
* @param type type of value
* @param value pointer to value
* @param byte_order byte order
* @returns #TRUE on success
**/
dbus_bool_t
_dbus_marshal_basic_type (DBusString *str,
char type,
void *value,
int byte_order)
{
dbus_bool_t retval;
switch (type)
{
case DBUS_TYPE_BYTE:
case DBUS_TYPE_BOOLEAN:
retval = _dbus_string_append_byte (str, *(unsigned char *)value);
break;
case DBUS_TYPE_INT32:
case DBUS_TYPE_UINT32:
return marshal_4_octets (str, byte_order, *(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);
break;
#endif /* DBUS_HAVE_INT64 */
case DBUS_TYPE_DOUBLE:
retval = _dbus_marshal_double (str, byte_order, *(double *)value);
break;
default:
_dbus_assert_not_reached ("not a basic type");
retval = FALSE;
break;
}
return retval;
}
/**
* Marshals a basic type array
*
* @param str string to marshal to
* @param element_type type of array elements
* @param value pointer to value
* @param len length of value data in elements
* @param byte_order byte order
* @returns #TRUE on success
**/
dbus_bool_t
_dbus_marshal_basic_type_array (DBusString *str,
char element_type,
const void *value,
int len,
int byte_order)
{
switch (element_type)
{
case DBUS_TYPE_BOOLEAN:
/* FIXME: we canonicalize to 0 or 1 for the single boolean case
* should we here too ? */
case DBUS_TYPE_BYTE:
return _dbus_marshal_byte_array (str, byte_order, value, len);
break;
case DBUS_TYPE_INT32:
case DBUS_TYPE_UINT32:
return marshal_4_octets_array (str, byte_order, value, len);
break;
#ifdef DBUS_HAVE_INT64
case DBUS_TYPE_INT64:
case DBUS_TYPE_UINT64:
#endif /* DBUS_HAVE_INT64 */
case DBUS_TYPE_DOUBLE:
return marshal_8_octets_array (str, byte_order, value, len);
break;
default:
_dbus_assert_not_reached ("non basic type in array");
break;
}
return FALSE;
}
/** @} */
#ifdef DBUS_BUILD_TESTS
......
......@@ -184,6 +184,10 @@ dbus_bool_t _dbus_marshal_double (DBusString *str,
dbus_bool_t _dbus_marshal_string (DBusString *str,
int byte_order,
const char *value);
dbus_bool_t _dbus_marshal_basic_type (DBusString *str,
char type,
void *value,
int byte_order);
dbus_bool_t _dbus_marshal_byte_array (DBusString *str,
int byte_order,
const unsigned char *value,
......@@ -210,6 +214,12 @@ 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,
......@@ -241,6 +251,11 @@ dbus_uint64_t _dbus_demarshal_uint64 (const DBusString *str,
int pos,
int *new_pos);
#endif /* DBUS_HAVE_INT64 */
void _dbus_demarshal_basic_type (const DBusString *str,
int type,
void *value,
int byte_order,
int *pos);
char * _dbus_demarshal_string (const DBusString *str,
int byte_order,
int pos,
......@@ -283,6 +298,13 @@ dbus_bool_t _dbus_demarshal_double_array (const DBusString *str,
int *new_pos,
double **array,
int *array_len);
dbus_bool_t _dbus_demarshal_basic_type_array (const DBusString *str,
int type,
void **array,
int *array_len,
int byte_order,
int *pos);
dbus_bool_t _dbus_demarshal_string_array (const DBusString *str,
int byte_order,
int pos,
......
......@@ -335,6 +335,193 @@ append_string_field (DBusString *dest,
return TRUE;
}
static dbus_bool_t
parse_basic_type (DBusString *src, char type,
DBusString *dest, dbus_bool_t *unalign,
int endian)
{
int align;
int align_pad_start, align_pad_end;
unsigned char data[16];
switch (type)
{
case DBUS_TYPE_BYTE:
case DBUS_TYPE_BOOLEAN:
align = 1;
break;
case DBUS_TYPE_UINT32:
case DBUS_TYPE_INT32:
align = 4;
break;
case DBUS_TYPE_DOUBLE:
align = 8;
break;
default:
_dbus_assert_not_reached ("not a basic type");
break;
}
align_pad_start = _dbus_string_get_length (dest);
align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, align);
_dbus_string_delete_first_word (src);
if (!_dbus_string_parse_basic_type (src, type, 0, data, NULL))
{
_dbus_verbose ("failed to parse type '%c'", type);
return FALSE;
}
if (!_dbus_marshal_basic_type (dest, type, data, endian))
{
_dbus_verbose ("failed to marshal type '%c'", type);
return FALSE;
}
if (*unalign)
{
_dbus_string_delete (dest, align_pad_start,
align_pad_end - align_pad_start);
*unalign = FALSE;
}
return TRUE;
}
static dbus_bool_t
parse_basic_array (DBusString *src, char type,
DBusString *dest, dbus_bool_t *unalign,
int endian)
{
int array_align, elem_size;
int i, len, allocated;
unsigned char *values, b;
int values_offset;
int align_pad_start, align_pad_end;
dbus_bool_t retval = FALSE;
array_align = 4; /* length */
switch (type)
{
case DBUS_TYPE_BYTE:
case DBUS_TYPE_BOOLEAN:
elem_size = 1;
break;
case DBUS_TYPE_UINT32:
case DBUS_TYPE_INT32:
elem_size = 4;
break;
case DBUS_TYPE_DOUBLE:
array_align = 8;
elem_size = 8;
break;
default:
_dbus_assert_not_reached ("not a basic type");
break;
}
align_pad_start = _dbus_string_get_length (dest);
align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, array_align);
len = 0;
allocated = 2;
values = NULL;
values_offset = 0;
_dbus_string_delete_first_word (src);
_dbus_string_skip_blank (src, 0, &i);
b = _dbus_string_get_byte (src, i++);
if (b != '{')
goto failed;
while (i < _dbus_string_get_length (src))
{
_dbus_string_skip_blank (src, i, &i);
if (!values || len == allocated - 1)
{
allocated *= 2;
values = dbus_realloc (values, allocated * elem_size);
if (!values)
{
_dbus_warn ("could not allocate memory for '%c' ARRAY\n", type);
goto failed;
}
}
if (!_dbus_string_parse_basic_type (src, type, i, values + values_offset, &i))
{
_dbus_warn ("could not parse integer element %d of '%c' ARRAY\n", len, type);
goto failed;
}
values_offset += elem_size;
len++;
_dbus_string_skip_blank (src, i, &i);
b = _dbus_string_get_byte (src, i++);
if (b == '}')
break;
else if (b != ',')
goto failed;
}
if (!_dbus_marshal_basic_type_array (dest, type, values, len, endian))
{
_dbus_warn ("failed to append '%c' ARRAY\n", type);
goto failed;
}
if (*unalign)
{
_dbus_string_delete (dest, align_pad_start,
align_pad_end - align_pad_start);
*unalign = FALSE;
}
retval = TRUE;
failed:
dbus_free (values);
return retval;
}
static char
lookup_basic_type (const DBusString *str, dbus_bool_t *is_array)
{
int i;
char type = DBUS_TYPE_INVALID;
static struct {
const char *name;
char type;
} name_to_type[] = {
{ "BYTE", DBUS_TYPE_BYTE },
{ "BOOLEAN", DBUS_TYPE_BOOLEAN },
{ "INT32", DBUS_TYPE_INT32 },
{ "UINT32", DBUS_TYPE_UINT32 },
{ "DOUBLE", DBUS_TYPE_DOUBLE }
};
for (i = 0; i < _DBUS_N_ELEMENTS(name_to_type); i++)
{
const char *name = name_to_type[i].name;
if (_dbus_string_starts_with_c_str (str, name))
{
int offset = strlen (name);
type = name_to_type[i].type;
if (is_array)
*is_array = _dbus_string_find (str, offset, "_ARRAY", NULL);
break;
}
}
return type;
}
/**
* Reads the given filename, which should be in "message description
* language" (look at some examples), and builds up the message data
......@@ -399,6 +586,8 @@ _dbus_message_data_load (DBusString *dest,
DBusHashTable *length_hash;
int endian;
DBusHashIter iter;
char type;
dbus_bool_t is_array;
retval = FALSE;
length_hash = NULL;
......@@ -510,7 +699,7 @@ _dbus_message_data_load (DBusString *dest,
goto parse_failed;
/* client serial */
if (!_dbus_marshal_int32 (dest, endian, 1))
if (!_dbus_marshal_uint32 (dest, endian, 1))
{
_dbus_warn ("couldn't append client serial\n");
goto parse_failed;
......@@ -721,16 +910,8 @@ _dbus_message_data_load (DBusString *dest,
code = DBUS_TYPE_INVALID;
else if (_dbus_string_starts_with_c_str (&line, "NIL"))
code = DBUS_TYPE_NIL;
else if (_dbus_string_starts_with_c_str (&line, "BYTE"))
code = DBUS_TYPE_BYTE;
else if (_dbus_string_starts_with_c_str (&line, "BOOLEAN"))
code = DBUS_TYPE_BOOLEAN;
else if (_dbus_string_starts_with_c_str (&line, "INT32"))
code = DBUS_TYPE_INT32;
else if (_dbus_string_starts_with_c_str (&line, "UINT32"))
code = DBUS_TYPE_UINT32;
else if (_dbus_string_starts_with_c_str (&line, "DOUBLE"))
code = DBUS_TYPE_DOUBLE;
else if ((code = lookup_basic_type (&line, NULL)) != DBUS_TYPE_INVALID)
;
else if (_dbus_string_starts_with_c_str (&line, "STRING"))
code = DBUS_TYPE_STRING;
else if (_dbus_string_starts_with_c_str (&line, "OBJECT_PATH"))
......@@ -753,380 +934,6 @@ _dbus_message_data_load (DBusString *dest,
goto parse_failed;
}
}
else if (_dbus_string_starts_with_c_str (&line,
"BYTE_ARRAY"))
{
SAVE_FOR_UNALIGN (dest, 4);
int i, len, allocated;
unsigned char *values;
unsigned char b;
long val;
allocated = 4;
values = dbus_new (unsigned char, allocated);
if (!values)
{
_dbus_warn ("could not allocate memory for BYTE_ARRAY\n");
goto parse_failed;
}
len = 0;
_dbus_string_delete_first_word (&line);
_dbus_string_skip_blank (&line, 0, &i);
b = _dbus_string_get_byte (&line, i++);
if (b != '{')
goto parse_failed;
while (i < _dbus_string_get_length (&line))
{
_dbus_string_skip_blank (&line, i, &i);
if (_dbus_string_get_byte (&line, i) == '\'' &&
_dbus_string_get_length (&line) >= i + 4 &&
_dbus_string_get_byte (&line, i + 1) == '\\' &&
_dbus_string_get_byte (&line, i + 2) == '\'' &&
_dbus_string_get_byte (&line, i + 3) == '\'')
{
val = '\'';
i += 4;
}
else if (_dbus_string_get_byte (&line, i) == '\'' &&
_dbus_string_get_length (&line) >= i + 3 &&
_dbus_string_get_byte (&line, i + 2) == '\'')
{
val = _dbus_string_get_byte (&line, i + 1);
i += 3;
}
else
{
if (!_dbus_string_parse_int (&line, i, &val, &i))
{
_dbus_warn ("Failed to parse integer for BYTE_ARRAY\n");
goto parse_failed;
}
if (val < 0 || val > 255)
{
_dbus_warn ("A byte must be in range 0-255 not %ld\n",
val);
goto parse_failed;
}
}
values[len++] = val;
if (len == allocated)
{
allocated *= 2;
values = dbus_realloc (values, allocated * sizeof (unsigned char));