* @{
*/
-enum
-{
- FIELD_HEADER_LENGTH,
- FIELD_BODY_LENGTH,
- FIELD_CLIENT_SERIAL,
- FIELD_PATH,
- FIELD_INTERFACE,
- FIELD_MEMBER,
- FIELD_ERROR_NAME,
- FIELD_SERVICE,
- FIELD_SENDER_SERVICE,
- FIELD_REPLY_SERIAL,
-
- FIELD_LAST
-};
-
-static dbus_bool_t field_is_named[FIELD_LAST] =
-{
- FALSE, /* FIELD_HEADER_LENGTH */
- FALSE, /* FIELD_BODY_LENGTH */
- FALSE, /* FIELD_CLIENT_SERIAL */
- TRUE, /* FIELD_PATH */
- TRUE, /* FIELD_INTERFACE */
- TRUE, /* FIELD_MEMBER */
- TRUE, /* FIELD_ERROR_NAME */
- TRUE, /* FIELD_SERVICE */
- TRUE, /* FIELD_SENDER_SERVICE */
- TRUE /* FIELD_REPLY_SERIAL */
-};
-
/**
* Cached information about a header field in the message
*/
} HeaderField;
/** Offset to byte order from start of header */
-#define BYTE_ORDER_OFFSET 0
+#define BYTE_ORDER_OFFSET 0
/** Offset to type from start of header */
-#define TYPE_OFFSET 1
+#define TYPE_OFFSET 1
/** Offset to flags from start of header */
-#define FLAGS_OFFSET 2
+#define FLAGS_OFFSET 2
/** Offset to version from start of header */
-#define VERSION_OFFSET 3
+#define VERSION_OFFSET 3
+/** Offset to header length from start of header */
+#define HEADER_LENGTH_OFFSET 4
+/** Offset to body length from start of header */
+#define BODY_LENGTH_OFFSET 8
+/** Offset to client serial from start of header */
+#define CLIENT_SERIAL_OFFSET 12
+
/**
* @brief Internals of DBusMessage
* independently realloc it.
*/
- HeaderField header_fields[FIELD_LAST]; /**< Track the location
- * of each field in "header"
- */
+ HeaderField header_fields[DBUS_HEADER_FIELD_LAST + 1]; /**< Track the location
+ * of each field in "header"
+ */
dbus_uint32_t client_serial; /**< Cached client serial value for speed */
dbus_uint32_t reply_serial; /**< Cached reply serial value for speed */
return;
i = 0;
- while (i < FIELD_LAST)
+ while (i <= DBUS_HEADER_FIELD_LAST)
{
if (message->header_fields[i].offset > offsets_after)
message->header_fields[i].offset += delta;
{
int offset;
- _dbus_assert (field < FIELD_LAST);
+ _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
offset = message->header_fields[field].offset;
{
int offset;
- _dbus_assert (field < FIELD_LAST);
+ _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
offset = message->header_fields[field].offset;
offset = message->header_fields[field].offset;
- _dbus_assert (field < FIELD_LAST);
+ _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
if (offset < 0)
return NULL;
offset = message->header_fields[field].offset;
- _dbus_assert (field < FIELD_LAST);
+ _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
if (offset < 0)
{
static dbus_bool_t
append_int_field (DBusMessage *message,
int field,
- const char *name,
int value)
{
int orig_len;
if (!_dbus_string_align_length (&message->header, 4))
goto failed;
- if (!_dbus_string_append_len (&message->header, name, 4))
+ if (!_dbus_string_append_byte (&message->header, field))
goto failed;
if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
static dbus_bool_t
append_uint_field (DBusMessage *message,
int field,
- const char *name,
- int value)
+ int value)
{
int orig_len;
if (!_dbus_string_align_length (&message->header, 4))
goto failed;
- if (!_dbus_string_append_len (&message->header, name, 4))
+ if (!_dbus_string_append_byte (&message->header, field))
goto failed;
if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_UINT32))
append_string_field (DBusMessage *message,
int field,
int type,
- const char *name,
const char *value)
{
int orig_len;
if (!_dbus_string_align_length (&message->header, 4))
goto failed;
- if (!_dbus_string_append_len (&message->header, name, 4))
+ if (!_dbus_string_append_byte (&message->header, field))
goto failed;
if (!_dbus_string_append_byte (&message->header, type))
int offset = message->header_fields[field].offset;
_dbus_assert (!message->locked);
- _dbus_assert (field_is_named[field]);
if (offset < 0)
return;
clear_header_padding (message);
- /* The field typecode and name take up 8 bytes */
+ /* The field typecode and name take up 4 bytes */
_dbus_string_delete (&message->header,
- offset - 8,
- 12);
+ offset - 4,
+ 8);
message->header_fields[field].offset = -1;
adjust_field_offsets (message,
- offset - 8,
- - 12);
+ offset - 4,
+ - 8);
append_header_padding (message);
}
int delete_len;
_dbus_assert (!message->locked);
- _dbus_assert (field_is_named[field]);
if (offset < 0)
return;
get_string_field (message, field, &len);
- /* The field typecode and name take up 8 bytes, and the nul
+ /* The field typecode and name take up 4 bytes, and the nul
* termination is 1 bytes, string length integer is 4 bytes
*/
- delete_len = 8 + 4 + 1 + len;
+ delete_len = 4 + 4 + 1 + len;
_dbus_string_delete (&message->header,
- offset - 8,
+ offset - 4,
delete_len);
message->header_fields[field].offset = -1;
adjust_field_offsets (message,
- offset - 8,
+ offset - 4,
- delete_len);
append_header_padding (message);
switch (field)
{
- case FIELD_REPLY_SERIAL:
- return append_uint_field (message, field,
- DBUS_HEADER_FIELD_REPLY,
- value);
+ case DBUS_HEADER_FIELD_REPLY_SERIAL:
+ return append_uint_field (message, field, value);
+
default:
_dbus_assert_not_reached ("appending a uint field we don't support appending");
return FALSE;
switch (field)
{
- case FIELD_PATH:
- return append_string_field (message, field, type,
- DBUS_HEADER_FIELD_PATH,
- value);
- case FIELD_SENDER_SERVICE:
- return append_string_field (message, field, type,
- DBUS_HEADER_FIELD_SENDER_SERVICE,
- value);
- case FIELD_INTERFACE:
- return append_string_field (message, field, type,
- DBUS_HEADER_FIELD_INTERFACE,
- value);
- case FIELD_MEMBER:
- return append_string_field (message, field, type,
- DBUS_HEADER_FIELD_MEMBER,
- value);
- case FIELD_ERROR_NAME:
- return append_string_field (message, field, type,
- DBUS_HEADER_FIELD_ERROR_NAME,
- value);
- case FIELD_SERVICE:
- return append_string_field (message, field, type,
- DBUS_HEADER_FIELD_SERVICE,
- value);
+ case DBUS_HEADER_FIELD_PATH:
+ case DBUS_HEADER_FIELD_SENDER_SERVICE:
+ case DBUS_HEADER_FIELD_INTERFACE:
+ case DBUS_HEADER_FIELD_MEMBER:
+ case DBUS_HEADER_FIELD_ERROR_NAME:
+ case DBUS_HEADER_FIELD_SERVICE:
+ return append_string_field (message, field, type, value);
+
default:
_dbus_assert_not_reached ("appending a string field we don't support appending");
return FALSE;
{
_dbus_assert (!message->locked);
_dbus_assert (dbus_message_get_serial (message) == 0);
-
- set_uint_field (message, FIELD_CLIENT_SERIAL,
- serial);
+
+ _dbus_marshal_set_uint32 (&message->header,
+ message->byte_order,
+ CLIENT_SERIAL_OFFSET,
+ serial);
+
message->client_serial = serial;
}
{
_dbus_assert (!message->locked);
- if (set_uint_field (message, FIELD_REPLY_SERIAL,
+ if (set_uint_field (message,
+ DBUS_HEADER_FIELD_REPLY_SERIAL,
reply_serial))
{
message->reply_serial = reply_serial;
if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION))
return FALSE;
- message->header_fields[FIELD_HEADER_LENGTH].offset = 4;
if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
return FALSE;
- message->header_fields[FIELD_BODY_LENGTH].offset = 8;
if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
return FALSE;
- message->header_fields[FIELD_CLIENT_SERIAL].offset = 12;
if (!_dbus_marshal_int32 (&message->header, message->byte_order, -1))
return FALSE;
if (path != NULL)
{
if (!append_string_field (message,
- FIELD_PATH, DBUS_TYPE_OBJECT_PATH,
DBUS_HEADER_FIELD_PATH,
+ DBUS_TYPE_OBJECT_PATH,
path))
return FALSE;
}
if (service != NULL)
{
if (!append_string_field (message,
- FIELD_SERVICE, DBUS_TYPE_STRING,
DBUS_HEADER_FIELD_SERVICE,
+ DBUS_TYPE_STRING,
service))
return FALSE;
}
if (interface != NULL)
{
if (!append_string_field (message,
- FIELD_INTERFACE, DBUS_TYPE_STRING,
DBUS_HEADER_FIELD_INTERFACE,
+ DBUS_TYPE_STRING,
interface))
return FALSE;
}
if (member != NULL)
{
if (!append_string_field (message,
- FIELD_MEMBER, DBUS_TYPE_STRING,
DBUS_HEADER_FIELD_MEMBER,
+ DBUS_TYPE_STRING,
member))
return FALSE;
}
if (error_name != NULL)
{
if (!append_string_field (message,
- FIELD_ERROR_NAME, DBUS_TYPE_STRING,
DBUS_HEADER_FIELD_ERROR_NAME,
+ DBUS_TYPE_STRING,
error_name))
return FALSE;
}
if (!message->locked)
{
/* Fill in our lengths */
- set_uint_field (message,
- FIELD_HEADER_LENGTH,
- _dbus_string_get_length (&message->header));
+ _dbus_marshal_set_uint32 (&message->header,
+ message->byte_order,
+ HEADER_LENGTH_OFFSET,
+ _dbus_string_get_length (&message->header));
- set_uint_field (message,
- FIELD_BODY_LENGTH,
- _dbus_string_get_length (&message->body));
+ _dbus_marshal_set_uint32 (&message->header,
+ message->byte_order,
+ BODY_LENGTH_OFFSET,
+ _dbus_string_get_length (&message->body));
message->locked = TRUE;
}
_dbus_data_slot_list_init (&message->slot_list);
i = 0;
- while (i < FIELD_LAST)
+ while (i <= DBUS_HEADER_FIELD_LAST)
{
message->header_fields[i].offset = -1;
++i;
_dbus_return_val_if_fail (method_call != NULL, NULL);
sender = get_string_field (method_call,
- FIELD_SENDER_SERVICE, NULL);
+ DBUS_HEADER_FIELD_SENDER_SERVICE,
+ NULL);
/* sender is allowed to be null here in peer-to-peer case */
_dbus_return_val_if_fail (error_name != NULL, NULL);
sender = get_string_field (reply_to,
- FIELD_SENDER_SERVICE, NULL);
+ DBUS_HEADER_FIELD_SENDER_SERVICE,
+ NULL);
/* sender may be NULL for non-message-bus case or
* when the message bus is dealing with an unregistered
return NULL;
}
- for (i = 0; i < FIELD_LAST; i++)
+ for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
{
retval->header_fields[i].offset = message->header_fields[i].offset;
}
if (object_path == NULL)
{
- delete_string_field (message, FIELD_PATH);
+ delete_string_field (message, DBUS_HEADER_FIELD_PATH);
return TRUE;
}
else
{
return set_string_field (message,
- FIELD_PATH,
+ DBUS_HEADER_FIELD_PATH,
DBUS_TYPE_OBJECT_PATH,
object_path);
}
{
_dbus_return_val_if_fail (message != NULL, NULL);
- return get_string_field (message, FIELD_PATH, NULL);
+ return get_string_field (message, DBUS_HEADER_FIELD_PATH, NULL);
}
/**
_dbus_return_val_if_fail (message != NULL, FALSE);
_dbus_return_val_if_fail (path != NULL, FALSE);
- return get_path_field_decomposed (message, FIELD_PATH,
+ return get_path_field_decomposed (message,
+ DBUS_HEADER_FIELD_PATH,
path);
}
if (interface == NULL)
{
- delete_string_field (message, FIELD_INTERFACE);
+ delete_string_field (message, DBUS_HEADER_FIELD_INTERFACE);
return TRUE;
}
else
{
return set_string_field (message,
- FIELD_INTERFACE,
+ DBUS_HEADER_FIELD_INTERFACE,
DBUS_TYPE_STRING,
interface);
}
{
_dbus_return_val_if_fail (message != NULL, NULL);
- return get_string_field (message, FIELD_INTERFACE, NULL);
+ return get_string_field (message, DBUS_HEADER_FIELD_INTERFACE, NULL);
}
/**
if (member == NULL)
{
- delete_string_field (message, FIELD_MEMBER);
+ delete_string_field (message, DBUS_HEADER_FIELD_MEMBER);
return TRUE;
}
else
{
return set_string_field (message,
- FIELD_MEMBER,
+ DBUS_HEADER_FIELD_MEMBER,
DBUS_TYPE_STRING,
member);
}
{
_dbus_return_val_if_fail (message != NULL, NULL);
- return get_string_field (message, FIELD_MEMBER, NULL);
+ return get_string_field (message,
+ DBUS_HEADER_FIELD_MEMBER,
+ NULL);
}
/**
if (error_name == NULL)
{
- delete_string_field (message, FIELD_ERROR_NAME);
+ delete_string_field (message,
+ DBUS_HEADER_FIELD_ERROR_NAME);
return TRUE;
}
else
{
return set_string_field (message,
- FIELD_ERROR_NAME,
+ DBUS_HEADER_FIELD_ERROR_NAME,
DBUS_TYPE_STRING,
error_name);
}
{
_dbus_return_val_if_fail (message != NULL, NULL);
- return get_string_field (message, FIELD_ERROR_NAME, NULL);
+ return get_string_field (message,
+ DBUS_HEADER_FIELD_ERROR_NAME,
+ NULL);
}
/**
if (destination == NULL)
{
- delete_string_field (message, FIELD_SERVICE);
+ delete_string_field (message, DBUS_HEADER_FIELD_SERVICE);
return TRUE;
}
else
{
return set_string_field (message,
- FIELD_SERVICE,
+ DBUS_HEADER_FIELD_SERVICE,
DBUS_TYPE_STRING,
destination);
}
{
_dbus_return_val_if_fail (message != NULL, NULL);
- return get_string_field (message, FIELD_SERVICE, NULL);
+ return get_string_field (message,
+ DBUS_HEADER_FIELD_SERVICE,
+ NULL);
}
/**
if (sender == NULL)
{
- delete_string_field (message, FIELD_SENDER_SERVICE);
+ delete_string_field (message,
+ DBUS_HEADER_FIELD_SENDER_SERVICE);
return TRUE;
}
else
{
return set_string_field (message,
- FIELD_SENDER_SERVICE,
+ DBUS_HEADER_FIELD_SENDER_SERVICE,
DBUS_TYPE_STRING,
sender);
}
{
_dbus_return_val_if_fail (message != NULL, NULL);
- return get_string_field (message, FIELD_SENDER_SERVICE, NULL);
+ return get_string_field (message,
+ DBUS_HEADER_FIELD_SENDER_SERVICE,
+ NULL);
}
static dbus_bool_t
*/
#define DBUS_MINIMUM_HEADER_SIZE 16
-/** Pack four characters as in "abcd" into a uint32 */
-#define FOUR_CHARS_TO_UINT32(a, b, c, d) \
- ((((dbus_uint32_t)a) << 24) | \
- (((dbus_uint32_t)b) << 16) | \
- (((dbus_uint32_t)c) << 8) | \
- ((dbus_uint32_t)d))
-
-/** DBUS_HEADER_FIELD_PATH packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_PATH_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('p', 'a', 't', 'h')
-
-/** DBUS_HEADER_FIELD_INTERFACE packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_INTERFACE_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('i', 'f', 'c', 'e')
-
-/** DBUS_HEADER_FIELD_MEMBER packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_MEMBER_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('m', 'e', 'b', 'r')
-
-/** DBUS_HEADER_FIELD_ERROR_NAME packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_ERROR_NAME_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('e', 'r', 'n', 'm')
-
-/** DBUS_HEADER_FIELD_SERVICE packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_SERVICE_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('s', 'r', 'v', 'c')
-
-/** DBUS_HEADER_FIELD_REPLY packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_REPLY_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('r', 'p', 'l', 'y')
-
-/** DBUS_HEADER_FIELD_SENDER_SERVICE Packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_SENDER_SERVICE_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('s', 'd', 'r', 's')
-
static dbus_bool_t
decode_string_field (const DBusString *data,
- HeaderField fields[FIELD_LAST],
+ int field,
+ HeaderField *header_field,
+ DBusString *field_data,
int pos,
- int type,
- int field,
- const char *field_name)
+ int type)
{
- DBusString tmp;
int string_data_pos;
+
+ _dbus_assert (header_field != NULL);
+ _dbus_assert (field_data != NULL);
- if (fields[field].offset >= 0)
+ if (header_field->offset >= 0)
{
_dbus_verbose ("%s field provided twice\n",
- field_name);
+ _dbus_header_field_to_string (field));
return FALSE;
}
if (type != DBUS_TYPE_STRING)
{
_dbus_verbose ("%s field has wrong type %s\n",
- field_name, _dbus_type_to_string (type));
+ _dbus_header_field_to_string (field),
+ _dbus_type_to_string (type));
return FALSE;
}
string_data_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
_dbus_assert (string_data_pos < _dbus_string_get_length (data));
- _dbus_string_init_const (&tmp,
+ _dbus_string_init_const (field_data,
_dbus_string_get_const_data (data) + string_data_pos);
- if (field == FIELD_INTERFACE)
- {
- if (!_dbus_string_validate_interface (&tmp, 0, _dbus_string_get_length (&tmp)))
- {
- _dbus_verbose ("%s field has invalid content \"%s\"\n",
- field_name, _dbus_string_get_const_data (&tmp));
- return FALSE;
- }
-
- if (_dbus_string_equal_c_str (&tmp,
- DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL))
- {
- _dbus_verbose ("Message is on the local interface\n");
- return FALSE;
- }
- }
- else if (field == FIELD_MEMBER)
- {
- if (!_dbus_string_validate_member (&tmp, 0, _dbus_string_get_length (&tmp)))
- {
- _dbus_verbose ("%s field has invalid content \"%s\"\n",
- field_name, _dbus_string_get_const_data (&tmp));
- return FALSE;
- }
- }
- else if (field == FIELD_ERROR_NAME)
- {
- if (!_dbus_string_validate_error_name (&tmp, 0, _dbus_string_get_length (&tmp)))
- {
- _dbus_verbose ("%s field has invalid content \"%s\"\n",
- field_name, _dbus_string_get_const_data (&tmp));
- return FALSE;
- }
- }
- else if (field == FIELD_SERVICE ||
- field == FIELD_SENDER_SERVICE)
- {
- if (!_dbus_string_validate_service (&tmp, 0, _dbus_string_get_length (&tmp)))
- {
- _dbus_verbose ("%s field has invalid content \"%s\"\n",
- field_name, _dbus_string_get_const_data (&tmp));
- return FALSE;
- }
- }
- else
- {
- _dbus_assert_not_reached ("Unknown field\n");
- }
-
- fields[field].offset = _DBUS_ALIGN_VALUE (pos, 4);
+ header_field->offset = _DBUS_ALIGN_VALUE (pos, 4);
#if 0
- _dbus_verbose ("Found field %s name at offset %d\n",
- field_name, fields[field].offset);
+ _dbus_verbose ("Found field %s at offset %d\n",
+ _dbus_header_field_to_string (field),
+ header_field->offset);
#endif
return TRUE;
int header_len,
int byte_order,
int message_type,
- HeaderField fields[FIELD_LAST],
+ HeaderField fields[DBUS_HEADER_FIELD_LAST + 1],
int *message_padding)
{
- const char *field;
+ DBusString field_data;
int pos, new_pos;
int i;
+ int field;
int type;
if (header_len < 16)
}
i = 0;
- while (i < FIELD_LAST)
+ while (i <= DBUS_HEADER_FIELD_LAST)
{
fields[i].offset = -1;
++i;
}
- fields[FIELD_HEADER_LENGTH].offset = 4;
- fields[FIELD_BODY_LENGTH].offset = 8;
- fields[FIELD_CLIENT_SERIAL].offset = 12;
-
- /* Now handle the named fields. A real named field is at least 4
- * bytes for the name, plus a type code (1 byte) plus padding. So
- * if we have less than 8 bytes left, it must be alignment padding,
- * not a field. While >= 8 bytes can't be entirely alignment
- * padding.
+ /* Now handle the named fields. A real named field is at least 1
+ * byte for the name, plus a type code (1 byte) plus padding, plus
+ * the field value. So if we have less than 8 bytes left, it must
+ * be alignment padding, not a field. While >= 8 bytes can't be
+ * entirely alignment padding.
*/
pos = 16;
while ((pos + 7) < header_len)
{
pos = _DBUS_ALIGN_VALUE (pos, 4);
- if ((pos + 4) > header_len)
+ if ((pos + 1) > header_len)
{
_dbus_verbose ("not enough space remains in header for header field value\n");
return FALSE;
}
- field = _dbus_string_get_const_data_len (data, pos, 4);
- pos += 4;
+ field = _dbus_string_get_byte (data, pos);
+ pos += 1;
- _dbus_assert (_DBUS_ALIGN_ADDRESS (field, 4) == field);
-
if (!_dbus_marshal_validate_type (data, pos, &type, &pos))
{
_dbus_verbose ("Failed to validate type of named header field\n");
return FALSE;
}
- switch (DBUS_UINT32_FROM_BE (*(int*)field))
+ switch (field)
{
- case DBUS_HEADER_FIELD_SERVICE_AS_UINT32:
- if (!decode_string_field (data, fields, pos, type,
- FIELD_SERVICE,
- DBUS_HEADER_FIELD_SERVICE))
+ case DBUS_HEADER_FIELD_SERVICE:
+ if (!decode_string_field (data, field, &fields[field],
+ &field_data, pos, type))
return FALSE;
+
+ if (!_dbus_string_validate_service (&field_data, 0,
+ _dbus_string_get_length (&field_data)))
+ {
+ _dbus_verbose ("service field has invalid content \"%s\"\n",
+ _dbus_string_get_const_data (&field_data));
+ return FALSE;
+ }
break;
- case DBUS_HEADER_FIELD_INTERFACE_AS_UINT32:
- if (!decode_string_field (data, fields, pos, type,
- FIELD_INTERFACE,
- DBUS_HEADER_FIELD_INTERFACE))
+ case DBUS_HEADER_FIELD_INTERFACE:
+ if (!decode_string_field (data, field, &fields[field],
+ &field_data, pos, type))
return FALSE;
+
+ if (!_dbus_string_validate_interface (&field_data, 0,
+ _dbus_string_get_length (&field_data)))
+ {
+ _dbus_verbose ("interface field has invalid content \"%s\"\n",
+ _dbus_string_get_const_data (&field_data));
+ return FALSE;
+ }
+
+ if (_dbus_string_equal_c_str (&field_data,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL))
+ {
+ _dbus_verbose ("Message is on the local interface\n");
+ return FALSE;
+ }
break;
- case DBUS_HEADER_FIELD_MEMBER_AS_UINT32:
- if (!decode_string_field (data, fields, pos, type,
- FIELD_MEMBER,
- DBUS_HEADER_FIELD_MEMBER))
+ case DBUS_HEADER_FIELD_MEMBER:
+ if (!decode_string_field (data, field, &fields[field],
+ &field_data, pos, type))
return FALSE;
+
+ if (!_dbus_string_validate_member (&field_data, 0,
+ _dbus_string_get_length (&field_data)))
+ {
+ _dbus_verbose ("member field has invalid content \"%s\"\n",
+ _dbus_string_get_const_data (&field_data));
+ return FALSE;
+ }
break;
- case DBUS_HEADER_FIELD_ERROR_NAME_AS_UINT32:
- if (!decode_string_field (data, fields, pos, type,
- FIELD_ERROR_NAME,
- DBUS_HEADER_FIELD_ERROR_NAME))
+ case DBUS_HEADER_FIELD_ERROR_NAME:
+ if (!decode_string_field (data, field, &fields[field],
+ &field_data, pos, type))
return FALSE;
+
+ if (!_dbus_string_validate_error_name (&field_data, 0,
+ _dbus_string_get_length (&field_data)))
+ {
+ _dbus_verbose ("error-name field has invalid content \"%s\"\n",
+ _dbus_string_get_const_data (&field_data));
+ return FALSE;
+ }
break;
- case DBUS_HEADER_FIELD_SENDER_SERVICE_AS_UINT32:
- if (!decode_string_field (data, fields, pos, type,
- FIELD_SENDER_SERVICE,
- DBUS_HEADER_FIELD_SENDER_SERVICE))
+ case DBUS_HEADER_FIELD_SENDER_SERVICE:
+ if (!decode_string_field (data, field, &fields[field],
+ &field_data, pos, type))
return FALSE;
+
+ if (!_dbus_string_validate_service (&field_data, 0,
+ _dbus_string_get_length (&field_data)))
+ {
+ _dbus_verbose ("sender-service field has invalid content \"%s\"\n",
+ _dbus_string_get_const_data (&field_data));
+ return FALSE;
+ }
break;
- case DBUS_HEADER_FIELD_PATH_AS_UINT32:
+ case DBUS_HEADER_FIELD_PATH:
/* Path was already validated as part of standard
* type validation, since there's an OBJECT_PATH
* type.
*/
- if (fields[FIELD_PATH].offset >= 0)
+ if (fields[field].offset >= 0)
{
- _dbus_verbose ("%s field provided twice\n",
- DBUS_HEADER_FIELD_PATH);
+ _dbus_verbose ("path field provided twice\n");
return FALSE;
}
if (type != DBUS_TYPE_OBJECT_PATH)
{
- _dbus_verbose ("%s field has wrong type\n", DBUS_HEADER_FIELD_PATH);
+ _dbus_verbose ("path field has wrong type\n");
return FALSE;
}
- fields[FIELD_PATH].offset = _DBUS_ALIGN_VALUE (pos, 4);
+ fields[field].offset = _DBUS_ALIGN_VALUE (pos, 4);
/* No forging signals from the local path */
{
const char *s;
s = _dbus_string_get_const_data_len (data,
- fields[FIELD_PATH].offset,
+ fields[field].offset,
_dbus_string_get_length (data) -
- fields[FIELD_PATH].offset);
+ fields[field].offset);
if (strcmp (s, DBUS_PATH_ORG_FREEDESKTOP_LOCAL) == 0)
{
_dbus_verbose ("Message is on the local path\n");
}
_dbus_verbose ("Found path at offset %d\n",
- fields[FIELD_PATH].offset);
+ fields[field].offset);
break;
- case DBUS_HEADER_FIELD_REPLY_AS_UINT32:
- if (fields[FIELD_REPLY_SERIAL].offset >= 0)
+ case DBUS_HEADER_FIELD_REPLY_SERIAL:
+ if (fields[field].offset >= 0)
{
- _dbus_verbose ("%s field provided twice\n",
- DBUS_HEADER_FIELD_REPLY);
+ _dbus_verbose ("reply field provided twice\n");
return FALSE;
}
if (type != DBUS_TYPE_UINT32)
{
- _dbus_verbose ("%s field has wrong type\n", DBUS_HEADER_FIELD_REPLY);
+ _dbus_verbose ("reply field has wrong type\n");
return FALSE;
}
- fields[FIELD_REPLY_SERIAL].offset = _DBUS_ALIGN_VALUE (pos, 4);
+ fields[field].offset = _DBUS_ALIGN_VALUE (pos, 4);
_dbus_verbose ("Found reply serial at offset %d\n",
- fields[FIELD_REPLY_SERIAL].offset);
+ fields[field].offset);
break;
default:
- _dbus_verbose ("Ignoring an unknown header field: %.4s at offset %d\n",
+ _dbus_verbose ("Ignoring an unknown header field: %d at offset %d\n",
field, pos);
}
{
case DBUS_MESSAGE_TYPE_SIGNAL:
case DBUS_MESSAGE_TYPE_METHOD_CALL:
- if (fields[FIELD_PATH].offset < 0)
+ if (fields[DBUS_HEADER_FIELD_PATH].offset < 0)
{
- _dbus_verbose ("No %s field provided\n",
- DBUS_HEADER_FIELD_PATH);
+ _dbus_verbose ("No path field provided\n");
return FALSE;
}
/* FIXME make this optional, at least for method calls */
- if (fields[FIELD_INTERFACE].offset < 0)
+ if (fields[DBUS_HEADER_FIELD_INTERFACE].offset < 0)
{
- _dbus_verbose ("No %s field provided\n",
- DBUS_HEADER_FIELD_INTERFACE);
+ _dbus_verbose ("No interface field provided\n");
return FALSE;
}
- if (fields[FIELD_MEMBER].offset < 0)
+ if (fields[DBUS_HEADER_FIELD_MEMBER].offset < 0)
{
- _dbus_verbose ("No %s field provided\n",
- DBUS_HEADER_FIELD_MEMBER);
+ _dbus_verbose ("No member field provided\n");
return FALSE;
}
break;
case DBUS_MESSAGE_TYPE_ERROR:
- if (fields[FIELD_ERROR_NAME].offset < 0)
+ if (fields[DBUS_HEADER_FIELD_ERROR_NAME].offset < 0)
{
- _dbus_verbose ("No %s field provided\n",
- DBUS_HEADER_FIELD_ERROR_NAME);
+ _dbus_verbose ("No error-name field provided\n");
return FALSE;
}
break;
if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
{
- HeaderField fields[FIELD_LAST];
+ HeaderField fields[DBUS_HEADER_FIELD_LAST + 1];
int i;
int next_arg;
/* Copy in the offsets we found */
i = 0;
- while (i < FIELD_LAST)
+ while (i <= DBUS_HEADER_FIELD_LAST)
{
message->header_fields[i] = fields[i];
++i;
* earlier)
*/
message->reply_serial = get_uint_field (message,
- FIELD_REPLY_SERIAL);
- message->client_serial = get_uint_field (message,
- FIELD_CLIENT_SERIAL);
+ DBUS_HEADER_FIELD_REPLY_SERIAL);
+
+ message->client_serial = _dbus_demarshal_uint32 (&message->header,
+ message->byte_order,
+ CLIENT_SERIAL_OFFSET,
+ NULL);
_dbus_verbose ("Loaded message %p\n", message);
}
client_serial = dbus_message_get_serial (message);
/* can't use set_serial due to the assertions at the start of it */
- set_uint_field (message, FIELD_CLIENT_SERIAL,
- client_serial);
+ _dbus_marshal_set_uint32 (&message->header,
+ message->byte_order,
+ CLIENT_SERIAL_OFFSET,
+ client_serial);
if (client_serial != dbus_message_get_serial (message))
{
In addition to the required header information mentioned
in <xref linkend="message-protocol-header-encoding">,
the header may contain zero or more named
- header fields. These fields are named to allow
- future versions of this protocol specification to
- add new fields; implementations must ignore fields
- they do not understand. Implementations must not
- invent their own header fields; only changes to
+ header fields. Future versions of this protocol
+ specification may add new fields. Implementations must
+ ignore fields they do not understand. Implementations
+ must not invent their own header fields; only changes to
this specification may introduce new header fields.
</para>
<para>
- Header field names MUST consist of 4 non-nul bytes. The field name is
- NOT nul terminated; it occupies exactly 4 bytes. Following the name, the
- field MUST have a type code represented as a single unsigned byte, and
- then a properly-aligned value of that type. See <xref
- linkend="message-protocol-arguments"> for a description of how each type
- is encoded. If an implementation sees a header field name that it does
- not understand, it MUST ignore that field.
+ Header fields MUST be aligned to a 4-byte boundary. Header field
+ names MUST consist of a single byte, possible values of which are
+ defined below. Following the name, the field MUST have a type code
+ represented as a single unsigned byte, and then a properly-aligned
+ value of that type. See <xref
+ linkend="message-protocol-arguments"> for a description of how each
+ type is encoded. If an implementation sees a header field name that
+ it does not understand, it MUST ignore that field.
</para>
<para>
<tgroup cols=3>
<thead>
<row>
- <entry>Name</entry>
+ <entry>Conventional Name</entry>
+ <entry>Decimal Value</entry>
<entry>Type</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
- <entry>path</entry>
+ <entry>INVALID</entry>
+ <entry>0</entry>
+ <entry>INVALID</entry>
+ <entry>Not a valid field name (error if it appears in a message)</entry>
+ </row>
+ <row>
+ <entry>PATH</entry>
+ <entry>1</entry>
<entry>STRING</entry>
<entry>The object to send the message to; objects are identified by
a path, "/foo/bar"</entry>
</row>
<row>
- <entry>ifce</entry>
+ <entry>INTERFACE</entry>
+ <entry>2</entry>
<entry>STRING</entry>
<entry>The interface to invoke a method call on, or
that a signal is emitted from. e.g. "org.freedesktop.Introspectable"</entry>
</row>
<row>
- <entry>mebr</entry>
+ <entry>MEMBER</entry>
+ <entry>3</entry>
<entry>STRING</entry>
<entry>The member, either the method name or signal name.
e.g. "Frobate"</entry>
</row>
<row>
- <entry>ernm</entry>
+ <entry>ERROR_NAME</entry>
+ <entry>4</entry>
<entry>STRING</entry>
<entry>The name of the error that occurred, for errors</entry>
</row>
<row>
- <entry>rply</entry>
+ <entry>REPLY_SERIAL</entry>
+ <entry>5</entry>
<entry>UINT32</entry>
<entry>The serial number of the message this message is a reply
to. (The serial number is one of the mandatory header fields,
see <xref linkend="message-protocol-header-encoding">.)</entry>
</row>
<row>
- <entry>srvc</entry>
+ <entry>SERVICE</entry>
+ <entry>6</entry>
<entry>STRING</entry>
<entry>The name of the service this message should be routed to.
Only used in combination with the message bus, see
<xref linkend="message-bus">.</entry>
</row>
<row>
- <entry>sdrs</entry>
+ <entry>SENDER_SERVICE</entry>
+ <entry>7</entry>
<entry>STRING</entry>
<entry>Sender service. The name of the base service that sent
this message. The message bus fills in this field; the field is
messages map naturally to methods on objects in a typical program.
</para>
<para>
- A method call message is expected to have a 'mebr' header field
+ A method call message is expected to have a MEMBER header field
indicating the name of the method. Optionally, the message has an
- 'ifce' field giving the interface the method is a part of. In the
- absence of an 'ifce' field, if two interfaces on the same object have
+ INTERFACE field giving the interface the method is a part of. In the
+ absence of an INTERFACE field, if two interfaces on the same object have
a method with the same name, it is undefined which of the two methods
will be invoked. Implementations may also choose to return an error in
this ambiguous case. However, if a method name is unique
implementations should not require an interface field.
</para>
<para>
- Method call messages also include a 'path' field indicating the
+ Method call messages also include a PATH field indicating the
object to invoke the method on. If the call is passing through
- a message bus, the message will also have a 'srvc' field giving
+ a message bus, the message will also have a SERVICE field giving
the service to receive the message.
</para>
<para>
When an application handles a method call message, it is expected to
- return a reply. The reply is identified by a 'rply' header field
+ return a reply. The reply is identified by a REPLY_SERIAL header field
indicating the serial number of the METHOD_CALL being replied to. The
reply can have one of two types; either METHOD_RETURN or ERROR.
</para>
<para>
Unlike method calls, signal emissions have no replies.
A signal emission is simply a single message of type SIGNAL.
- It must have three header fields: 'path' giving the object
- the signal was emitted from, plus 'ifce' and 'mebr' giving the
- fully-qualified name of the signal.
+ It must have three header fields: PATH giving the object
+ the signal was emitted from, plus INTERFACE and MEMBER giving
+ the fully-qualified name of the signal.
</para>
</sect3>
org.freedesktop.DBus.ActivateService (in STRING service_name, in UINT32 flags,
out UINT32 resultcode)
</programlisting>
- This means ifce = org.freedesktop.DBus, mebr = ActivateService,
+ This means INTERFACE = org.freedesktop.DBus, MEMBER = ActivateService,
METHOD_CALL arguments are STRING and UINT32, METHOD_RETURN argument
- is UINT32. Remember that the 'mebr' field can't contain any '.' (period)
+ is UINT32. Remember that the MEMBER field can't contain any '.' (period)
characters so it's known that the last part of the name in
the "IDL" is the member name.
</para>
the new owner of the service.
</para>
<para>
- Messages may have a <literal>srvc</literal> field (see <xref
+ Messages may have a <literal>SERVICE</literal> field (see <xref
linkend="message-protocol-header-fields">). When the message bus
- receives a message, if the <literal>srvc</literal> field is absent, the
+ receives a message, if the <literal>SERVICE</literal> field is absent, the
message is taken to be a standard peer-to-peer message and interpreted
by the message bus itself. For example, sending
an <literal>org.freedesktop.Peer.Ping</literal> message with no
- <literal>srvc</literal> will cause the message bus itself to reply
+ <literal>SERVICE</literal> will cause the message bus itself to reply
to the ping immediately; the message bus would never make
this message visible to other applications.
</para>
<para>
- If the <literal>srvc</literal> field is present, then it indicates a
+ If the <literal>SERVICE</literal> field is present, then it indicates a
request for the message bus to route the message. In the usual case,
messages are routed to the owner of the named service.
Messages may also be <firstterm>broadcast</firstterm>
</para>
<para>
Continuing the <literal>org.freedesktop.Peer.Ping</literal> example, if
- the ping message were sent with a <literal>srvc</literal> name of
+ the ping message were sent with a <literal>SERVICE</literal> name of
<literal>com.yoyodyne.Screensaver</literal>, then the ping would be
forwarded, and the Yoyodyne Corporation screensaver application would be
expected to reply to the ping. If