dbus-message.c revision 8ab042b9571dda44a5afcfe50e0d29dc9b58ecae
15a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington/* -*- mode: C; c-file-style: "gnu" -*- */
25a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington/* dbus-message.c  DBusMessage object
35a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
4502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * Copyright (C) 2002, 2003  Red Hat Inc.
51b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Copyright (C) 2002, 2003  CodeFactory AB
65a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
75a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * Licensed under the Academic Free License version 1.2
85a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
95a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * This program is free software; you can redistribute it and/or modify
105a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * it under the terms of the GNU General Public License as published by
115a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * the Free Software Foundation; either version 2 of the License, or
125a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * (at your option) any later version.
135a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
145a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * This program is distributed in the hope that it will be useful,
155a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * but WITHOUT ANY WARRANTY; without even the implied warranty of
165a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
175a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * GNU General Public License for more details.
185a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
195a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * You should have received a copy of the GNU General Public License
205a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * along with this program; if not, write to the Free Software
215a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
225a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
235a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington */
245a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington
25041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-internals.h"
265175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson#include "dbus-marshal.h"
275a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington#include "dbus-message.h"
28041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-message-internal.h"
29041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-memory.h"
30041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-list.h"
3105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington#include "dbus-message-builder.h"
32041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include <string.h>
335a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington
3493f222c1d8ed748994f74662671d003495b16d43Havoc Pennington/**
3555de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @defgroup DBusMessageInternals DBusMessage implementation details
3655de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @ingroup DBusInternals
3755de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @brief DBusMessage private implementation details.
3893f222c1d8ed748994f74662671d003495b16d43Havoc Pennington *
3955de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * The guts of DBusMessage and its methods.
4093f222c1d8ed748994f74662671d003495b16d43Havoc Pennington *
4193f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * @{
4293f222c1d8ed748994f74662671d003495b16d43Havoc Pennington */
4393f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
4450c25505f62786756519ef1e194883360eda82e0Havoc Penningtonenum
4550c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
4650c25505f62786756519ef1e194883360eda82e0Havoc Pennington  FIELD_HEADER_LENGTH,
4750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  FIELD_BODY_LENGTH,
4850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  FIELD_CLIENT_SERIAL,
4950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  FIELD_NAME,
5050c25505f62786756519ef1e194883360eda82e0Havoc Pennington  FIELD_SERVICE,
5150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  FIELD_SENDER,
5250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  FIELD_REPLY_SERIAL,
5350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
5450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  FIELD_LAST
5550c25505f62786756519ef1e194883360eda82e0Havoc Pennington};
5650c25505f62786756519ef1e194883360eda82e0Havoc Pennington
578ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Penningtonstatic dbus_bool_t field_is_named[FIELD_LAST] =
588ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington{
598ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  FALSE, /* FIELD_HEADER_LENGTH */
608ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  FALSE, /* FIELD_BODY_LENGTH */
618ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  FALSE, /* FIELD_CLIENT_SERIAL */
628ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  TRUE,  /* FIELD_NAME */
638ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  TRUE,  /* FIELD_SERVICE */
648ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  TRUE,  /* FIELD_SENDER */
658ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  TRUE   /* FIELD_REPLY_SERIAL */
668ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington};
678ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
6850c25505f62786756519ef1e194883360eda82e0Havoc Penningtontypedef struct
6950c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
7050c25505f62786756519ef1e194883360eda82e0Havoc Pennington  int offset; /**< Offset to start of field (location of name of field
7150c25505f62786756519ef1e194883360eda82e0Havoc Pennington               * for named fields)
7250c25505f62786756519ef1e194883360eda82e0Havoc Pennington               */
7350c25505f62786756519ef1e194883360eda82e0Havoc Pennington} HeaderField;
7450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
751428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
76f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington * @brief Internals of DBusMessage
77f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington *
781428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Object representing a message received from or to be sent to
7955de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * another application. This is an opaque object, all members
8055de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * are private.
811428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
825a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Penningtonstruct DBusMessage
835a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington{
841428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int refcount; /**< Reference count */
85041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
86271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  DBusString header; /**< Header network data, stored
87271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                      * separately from body so we can
88271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                      * independently realloc it.
89271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                      */
90041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
9150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  HeaderField header_fields[FIELD_LAST]; /**< Track the location
9250c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                           * of each field in "header"
9350c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                           */
947ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  int header_padding; /**< bytes of alignment in header */
9550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
96271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  DBusString body;   /**< Body network data. */
97041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
981b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  char byte_order; /**< Message byte order. */
99502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
100502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  DBusCounter *size_counter; /**< Counter for the size of the message, or #NULL */
101502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  long size_counter_delta;   /**< Size we incremented the size counter by. */
1021b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
103041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
1045a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington};
1055a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington
106993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington/**
107993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * @brief Internals of DBusMessageIter
108993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington *
109993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * Object representing a position in a message. All fields are internal.
110993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington */
1111b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssonstruct DBusMessageIter
1121b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
1131b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  int refcount; /**< Reference count */
1141b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
1151b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  int pos; /**< Current position in the string */
1161b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
1171b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  DBusMessage *message; /**< Message used */
1181b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson};
1191b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
120041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
121041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Gets the data to be sent over the network for this message.
122041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * The header and then the body should be written out.
123041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * This function is guaranteed to always return the same
124041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * data once a message is locked (with _dbus_message_lock()).
125041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
126041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param message the message.
127041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param header return location for message header data.
128041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param body return location for message body data.
129041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
130041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonvoid
131041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_get_network_data (DBusMessage          *message,
132271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                                const DBusString    **header,
133271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                                const DBusString    **body)
134041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
135041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_assert (message->locked);
136041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
137271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  *header = &message->header;
138271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  *body = &message->body;
139041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
140041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
14150c25505f62786756519ef1e194883360eda82e0Havoc Penningtonstatic void
1427ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Penningtonclear_header_padding (DBusMessage *message)
1437ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington{
1447ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  _dbus_string_shorten (&message->header,
1457ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                        message->header_padding);
1467ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  message->header_padding = 0;
1477ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington}
1487ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
1497ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Penningtonstatic dbus_bool_t
1507ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Penningtonappend_header_padding (DBusMessage *message)
1517ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington{
1527ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  int old_len;
1537ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  old_len = _dbus_string_get_length (&message->header);
1547ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (!_dbus_string_align_length (&message->header, 8))
1557ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    return FALSE;
1567ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
1577ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  message->header_padding = _dbus_string_get_length (&message->header) - old_len;
1587ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
1597ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  return TRUE;
1607ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington}
1617ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
1627ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Penningtonstatic void
16350c25505f62786756519ef1e194883360eda82e0Havoc Penningtonadjust_field_offsets (DBusMessage *message,
16450c25505f62786756519ef1e194883360eda82e0Havoc Pennington                      int          offsets_after,
16550c25505f62786756519ef1e194883360eda82e0Havoc Pennington                      int          delta)
16650c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
16750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  int i;
16850c25505f62786756519ef1e194883360eda82e0Havoc Pennington
16950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (delta == 0)
17050c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return;
17150c25505f62786756519ef1e194883360eda82e0Havoc Pennington
17250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  i = 0;
17350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  while (i < FIELD_LAST)
17450c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
17550c25505f62786756519ef1e194883360eda82e0Havoc Pennington      if (message->header_fields[i].offset > offsets_after)
17650c25505f62786756519ef1e194883360eda82e0Havoc Pennington        message->header_fields[i].offset += delta;
17750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
17850c25505f62786756519ef1e194883360eda82e0Havoc Pennington      ++i;
17950c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
18050c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
18150c25505f62786756519ef1e194883360eda82e0Havoc Pennington
18250c25505f62786756519ef1e194883360eda82e0Havoc Penningtonstatic const char*
18350c25505f62786756519ef1e194883360eda82e0Havoc Penningtonget_string_field (DBusMessage *message,
18450c25505f62786756519ef1e194883360eda82e0Havoc Pennington                  int          field,
18550c25505f62786756519ef1e194883360eda82e0Havoc Pennington                  int         *len)
18650c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
18750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  int offset = message->header_fields[field].offset;
18850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  const char *data;
18950c25505f62786756519ef1e194883360eda82e0Havoc Pennington
19050c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (offset < 0)
19150c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return NULL;
19250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
19350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  /* offset points to string length, string data follows it */
19450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  /* FIXME _dbus_demarshal_const_string() that returned
19550c25505f62786756519ef1e194883360eda82e0Havoc Pennington   * a reference to the string plus its len might be nice.
19650c25505f62786756519ef1e194883360eda82e0Havoc Pennington   */
19750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
19850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (len)
1998ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington    *len = _dbus_demarshal_uint32 (&message->header,
2008ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                                   message->byte_order,
2018ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                                   offset,
2028ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                                   NULL);
20350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
20450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_string_get_const_data (&message->header,
20550c25505f62786756519ef1e194883360eda82e0Havoc Pennington                               &data);
20650c25505f62786756519ef1e194883360eda82e0Havoc Pennington
20750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return data + (offset + 4);
20850c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
20950c25505f62786756519ef1e194883360eda82e0Havoc Pennington
21050c25505f62786756519ef1e194883360eda82e0Havoc Penningtonstatic dbus_int32_t
21150c25505f62786756519ef1e194883360eda82e0Havoc Penningtonget_int_field (DBusMessage *message,
21250c25505f62786756519ef1e194883360eda82e0Havoc Pennington                     int          field)
21350c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
21450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  int offset = message->header_fields[field].offset;
21550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
21650c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (offset < 0)
21750c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return -1; /* useless if -1 is a valid value of course */
21850c25505f62786756519ef1e194883360eda82e0Havoc Pennington
21950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return _dbus_demarshal_int32 (&message->header,
22050c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                message->byte_order,
22150c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                offset,
22250c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                NULL);
22350c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
22450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
22550c25505f62786756519ef1e194883360eda82e0Havoc Penningtonstatic dbus_bool_t
22650c25505f62786756519ef1e194883360eda82e0Havoc Penningtonappend_int_field (DBusMessage *message,
22750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                  int          field,
22850c25505f62786756519ef1e194883360eda82e0Havoc Pennington                  const char  *name,
22950c25505f62786756519ef1e194883360eda82e0Havoc Pennington                  int          value)
23050c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
23150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  int orig_len;
23250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
23350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (!message->locked);
2347ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
2357ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  clear_header_padding (message);
23650c25505f62786756519ef1e194883360eda82e0Havoc Pennington
23750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  orig_len = _dbus_string_get_length (&message->header);
23850c25505f62786756519ef1e194883360eda82e0Havoc Pennington
23950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_align_length (&message->header, 4))
24050c25505f62786756519ef1e194883360eda82e0Havoc Pennington    goto failed;
24150c25505f62786756519ef1e194883360eda82e0Havoc Pennington
24250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_append_len (&message->header, name, 4))
24350c25505f62786756519ef1e194883360eda82e0Havoc Pennington    goto failed;
24450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
24550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
24650c25505f62786756519ef1e194883360eda82e0Havoc Pennington    goto failed;
24750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
24850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_align_length (&message->header, 4))
24950c25505f62786756519ef1e194883360eda82e0Havoc Pennington    goto failed;
25050c25505f62786756519ef1e194883360eda82e0Havoc Pennington
25150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message->header_fields[FIELD_REPLY_SERIAL].offset =
25250c25505f62786756519ef1e194883360eda82e0Havoc Pennington    _dbus_string_get_length (&message->header);
25350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
2547ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (!_dbus_marshal_int32 (&message->header, message->byte_order,
25550c25505f62786756519ef1e194883360eda82e0Havoc Pennington                            value))
25650c25505f62786756519ef1e194883360eda82e0Havoc Pennington    goto failed;
25750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
2587ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (!append_header_padding (message))
2597ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    goto failed;
2607ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
26150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return TRUE;
26250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
26350c25505f62786756519ef1e194883360eda82e0Havoc Pennington failed:
26450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message->header_fields[field].offset = -1;
26550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_string_set_length (&message->header, orig_len);
2667ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
2677ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  /* this must succeed because it was allocated on function entry and
2687ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington   * DBusString doesn't ever realloc smaller
2697ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington   */
2707ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (!append_header_padding (message))
2717ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    _dbus_assert_not_reached ("failed to reappend header padding");
27250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return FALSE;
27350c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
27450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
27550c25505f62786756519ef1e194883360eda82e0Havoc Penningtonstatic dbus_bool_t
27650c25505f62786756519ef1e194883360eda82e0Havoc Penningtonappend_string_field (DBusMessage *message,
27750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                     int          field,
27850c25505f62786756519ef1e194883360eda82e0Havoc Pennington                     const char  *name,
27950c25505f62786756519ef1e194883360eda82e0Havoc Pennington                     const char  *value)
28050c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
28150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  int orig_len;
28250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
28350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (!message->locked);
2847ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
2857ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  clear_header_padding (message);
28650c25505f62786756519ef1e194883360eda82e0Havoc Pennington
28750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  orig_len = _dbus_string_get_length (&message->header);
28850c25505f62786756519ef1e194883360eda82e0Havoc Pennington
28950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_align_length (&message->header, 4))
29050c25505f62786756519ef1e194883360eda82e0Havoc Pennington    goto failed;
29150c25505f62786756519ef1e194883360eda82e0Havoc Pennington
29250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_append_len (&message->header, name, 4))
29350c25505f62786756519ef1e194883360eda82e0Havoc Pennington    goto failed;
29450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
29550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_STRING))
29650c25505f62786756519ef1e194883360eda82e0Havoc Pennington    goto failed;
29750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
29850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_align_length (&message->header, 4))
29950c25505f62786756519ef1e194883360eda82e0Havoc Pennington    goto failed;
30050c25505f62786756519ef1e194883360eda82e0Havoc Pennington
30150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message->header_fields[field].offset =
30250c25505f62786756519ef1e194883360eda82e0Havoc Pennington    _dbus_string_get_length (&message->header);
30350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
3047ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (!_dbus_marshal_string (&message->header, message->byte_order,
30550c25505f62786756519ef1e194883360eda82e0Havoc Pennington                             value))
30650c25505f62786756519ef1e194883360eda82e0Havoc Pennington    goto failed;
30750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
3087ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (!append_header_padding (message))
3097ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    goto failed;
3107ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
31150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return TRUE;
31250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
31350c25505f62786756519ef1e194883360eda82e0Havoc Pennington failed:
31450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message->header_fields[field].offset = -1;
31550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_string_set_length (&message->header, orig_len);
3167ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
3177ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  /* this must succeed because it was allocated on function entry and
3187ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington   * DBusString doesn't ever realloc smaller
3197ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington   */
3207ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (!append_header_padding (message))
3217ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    _dbus_assert_not_reached ("failed to reappend header padding");
3227ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
32350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return FALSE;
32450c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
32550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
3268ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Penningtonstatic void
3278ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Penningtondelete_int_field (DBusMessage *message,
3288ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                  int          field)
3298ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington{
3308ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  int offset = message->header_fields[field].offset;
3318ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3328ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  _dbus_assert (!message->locked);
3338ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  _dbus_assert (field_is_named[field]);
3348ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3358ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  if (offset < 0)
3368ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington    return;
3378ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3387ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  clear_header_padding (message);
3397ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
3408ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  /* The field typecode and name take up 8 bytes */
3418ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  _dbus_string_delete (&message->header,
3428ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                       offset - 8,
3438ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                       12);
3448ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3458ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  message->header_fields[field].offset = -1;
3468ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3478ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  adjust_field_offsets (message,
3488ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                        offset - 8,
3498ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                        - 12);
3507ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
3517ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  append_header_padding (message);
3528ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington}
3538ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3548ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Penningtonstatic void
3558ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Penningtondelete_string_field (DBusMessage *message,
3568ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                     int          field)
3578ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington{
3588ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  int offset = message->header_fields[field].offset;
3598ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  int len;
3608ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  int delete_len;
3618ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3628ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  _dbus_assert (!message->locked);
3638ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  _dbus_assert (field_is_named[field]);
3648ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3658ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  if (offset < 0)
3668ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington    return;
3678ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3687ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  clear_header_padding (message);
3697ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
3708ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  get_string_field (message, field, &len);
3718ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3728ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  /* The field typecode and name take up 8 bytes, and the nul
3738ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington   * termination is 1 bytes, string length integer is 4 bytes
3748ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington   */
3758ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  delete_len = 8 + 4 + 1 + len;
3768ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3778ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  _dbus_string_delete (&message->header,
3788ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                       offset - 8,
3798ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                       delete_len);
3808ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3818ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  message->header_fields[field].offset = -1;
3828ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
3838ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington  adjust_field_offsets (message,
3848ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                        offset - 8,
3858ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington                        - delete_len);
3867ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
3877ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  append_header_padding (message);
3888ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington}
3898ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington
39050c25505f62786756519ef1e194883360eda82e0Havoc Penningtonstatic dbus_bool_t
39150c25505f62786756519ef1e194883360eda82e0Havoc Penningtonset_int_field (DBusMessage *message,
39250c25505f62786756519ef1e194883360eda82e0Havoc Pennington               int          field,
39350c25505f62786756519ef1e194883360eda82e0Havoc Pennington               int          value)
39450c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
39550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  int offset = message->header_fields[field].offset;
39650c25505f62786756519ef1e194883360eda82e0Havoc Pennington
39750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (!message->locked);
39850c25505f62786756519ef1e194883360eda82e0Havoc Pennington
39950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (offset < 0)
40050c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
40150c25505f62786756519ef1e194883360eda82e0Havoc Pennington      /* need to append the field */
40250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
40350c25505f62786756519ef1e194883360eda82e0Havoc Pennington      switch (field)
40450c25505f62786756519ef1e194883360eda82e0Havoc Pennington        {
40550c25505f62786756519ef1e194883360eda82e0Havoc Pennington        case FIELD_REPLY_SERIAL:
40650c25505f62786756519ef1e194883360eda82e0Havoc Pennington          return append_int_field (message, field,
40750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                   DBUS_HEADER_FIELD_REPLY,
40850c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                   value);
40950c25505f62786756519ef1e194883360eda82e0Havoc Pennington        default:
41050c25505f62786756519ef1e194883360eda82e0Havoc Pennington          _dbus_assert_not_reached ("appending an int field we don't support appending");
41150c25505f62786756519ef1e194883360eda82e0Havoc Pennington          return FALSE;
41250c25505f62786756519ef1e194883360eda82e0Havoc Pennington        }
41350c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
41450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  else
41550c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
41650c25505f62786756519ef1e194883360eda82e0Havoc Pennington      _dbus_marshal_set_int32 (&message->header,
41750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                               message->byte_order,
41850c25505f62786756519ef1e194883360eda82e0Havoc Pennington                               offset, value);
41950c25505f62786756519ef1e194883360eda82e0Havoc Pennington
42050c25505f62786756519ef1e194883360eda82e0Havoc Pennington      return TRUE;
42150c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
42250c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
42350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
42450c25505f62786756519ef1e194883360eda82e0Havoc Penningtonstatic dbus_bool_t
425482dab2076282ef1195564fa60dd25c1ffb77682Havoc Penningtonset_uint_field (DBusMessage  *message,
426482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington                int           field,
427482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington                dbus_uint32_t value)
428482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington{
429482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington  int offset = message->header_fields[field].offset;
430482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington
431482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington  _dbus_assert (!message->locked);
432482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington
433482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington  if (offset < 0)
434482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington    {
435482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      /* need to append the field */
436482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington
437482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      switch (field)
438482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington        {
439482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington        default:
440482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington          _dbus_assert_not_reached ("appending a uint field we don't support appending");
441482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington          return FALSE;
442482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington        }
443482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington    }
444482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington  else
445482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington    {
446482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      _dbus_marshal_set_uint32 (&message->header,
447482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington                                message->byte_order,
448482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington                                offset, value);
449482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington
450482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      return TRUE;
451482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington    }
452482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington}
453482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington
454482dab2076282ef1195564fa60dd25c1ffb77682Havoc Penningtonstatic dbus_bool_t
45550c25505f62786756519ef1e194883360eda82e0Havoc Penningtonset_string_field (DBusMessage *message,
45650c25505f62786756519ef1e194883360eda82e0Havoc Pennington                  int          field,
45750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                  const char  *value)
45850c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
45950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  int offset = message->header_fields[field].offset;
46050c25505f62786756519ef1e194883360eda82e0Havoc Pennington
46150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (!message->locked);
46250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (value != NULL);
46350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
46450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (offset < 0)
46550c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
46650c25505f62786756519ef1e194883360eda82e0Havoc Pennington      /* need to append the field */
46750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
46850c25505f62786756519ef1e194883360eda82e0Havoc Pennington      switch (field)
46950c25505f62786756519ef1e194883360eda82e0Havoc Pennington        {
47050c25505f62786756519ef1e194883360eda82e0Havoc Pennington        case FIELD_SENDER:
47150c25505f62786756519ef1e194883360eda82e0Havoc Pennington          return append_string_field (message, field,
47250c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                      DBUS_HEADER_FIELD_SENDER,
47350c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                      value);
47450c25505f62786756519ef1e194883360eda82e0Havoc Pennington        default:
47550c25505f62786756519ef1e194883360eda82e0Havoc Pennington          _dbus_assert_not_reached ("appending a string field we don't support appending");
47650c25505f62786756519ef1e194883360eda82e0Havoc Pennington          return FALSE;
47750c25505f62786756519ef1e194883360eda82e0Havoc Pennington        }
47850c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
47950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  else
48050c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
48150c25505f62786756519ef1e194883360eda82e0Havoc Pennington      DBusString v;
48250c25505f62786756519ef1e194883360eda82e0Havoc Pennington      int old_len;
48350c25505f62786756519ef1e194883360eda82e0Havoc Pennington      int new_len;
48450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
48550c25505f62786756519ef1e194883360eda82e0Havoc Pennington      old_len = _dbus_string_get_length (&message->header);
48650c25505f62786756519ef1e194883360eda82e0Havoc Pennington
48750c25505f62786756519ef1e194883360eda82e0Havoc Pennington      _dbus_string_init_const_len (&v, value,
48850c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                   strlen (value) + 1); /* include nul */
48950c25505f62786756519ef1e194883360eda82e0Havoc Pennington      if (!_dbus_marshal_set_string (&message->header,
49050c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                     message->byte_order,
49150c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                     offset, &v))
49250c25505f62786756519ef1e194883360eda82e0Havoc Pennington        return FALSE;
49350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
49450c25505f62786756519ef1e194883360eda82e0Havoc Pennington      new_len = _dbus_string_get_length (&message->header);
49550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
49650c25505f62786756519ef1e194883360eda82e0Havoc Pennington      adjust_field_offsets (message,
49750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                            offset,
49850c25505f62786756519ef1e194883360eda82e0Havoc Pennington                            new_len - old_len);
49950c25505f62786756519ef1e194883360eda82e0Havoc Pennington
50050c25505f62786756519ef1e194883360eda82e0Havoc Pennington      return TRUE;
50150c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
50250c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
50350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
504041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
5051b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Sets the client serial of a message.
5061b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * This can only be done once on a message.
5071b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
508bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington * @todo client_serial should be called simply
509bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington * "serial"; it's in outgoing messages for both
510bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington * the client and the server, it's only client-specific
511bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington * in the message bus case. It's more like origin_serial
512bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington * or something.
513bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington *
5141b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param message the message
5151b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param client_serial the client serial
5161b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
5171b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssonvoid
5181b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson_dbus_message_set_client_serial (DBusMessage  *message,
5191b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson				 dbus_int32_t  client_serial)
5201b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
52150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (!message->locked);
52250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (_dbus_message_get_client_serial (message) < 0);
52350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
52450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  set_int_field (message, FIELD_CLIENT_SERIAL,
52550c25505f62786756519ef1e194883360eda82e0Havoc Pennington                 client_serial);
52650c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
52750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
52850c25505f62786756519ef1e194883360eda82e0Havoc Pennington/**
52950c25505f62786756519ef1e194883360eda82e0Havoc Pennington * Sets the reply serial of a message (the client serial
53050c25505f62786756519ef1e194883360eda82e0Havoc Pennington * of the message this is a reply to).
53150c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
53250c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param message the message
53350c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param reply_serial the client serial
53450c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @returns #FALSE if not enough memory
53550c25505f62786756519ef1e194883360eda82e0Havoc Pennington */
53650c25505f62786756519ef1e194883360eda82e0Havoc Penningtondbus_bool_t
53750c25505f62786756519ef1e194883360eda82e0Havoc Pennington_dbus_message_set_reply_serial (DBusMessage  *message,
53850c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                dbus_int32_t  reply_serial)
53950c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
54050c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (!message->locked);
54150c25505f62786756519ef1e194883360eda82e0Havoc Pennington
54250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return set_int_field (message, FIELD_REPLY_SERIAL,
54350c25505f62786756519ef1e194883360eda82e0Havoc Pennington                        reply_serial);
5441b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
5451b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
546502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington/**
547a2a681582929ada667de5d05d5168f8a1f313800Anders Carlsson * Returns the client serial of a message or
548a2a681582929ada667de5d05d5168f8a1f313800Anders Carlsson * -1 if none has been specified.
549a2a681582929ada667de5d05d5168f8a1f313800Anders Carlsson *
550bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington * @todo see note in _dbus_message_set_client_serial()
551bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington * about how client_serial is a misnomer
552bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington *
553bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington * @todo this function should be public, after renaming it.
554bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington *
555a2a681582929ada667de5d05d5168f8a1f313800Anders Carlsson * @param message the message
556a2a681582929ada667de5d05d5168f8a1f313800Anders Carlsson * @returns the client serial
557a2a681582929ada667de5d05d5168f8a1f313800Anders Carlsson */
558a2a681582929ada667de5d05d5168f8a1f313800Anders Carlssondbus_int32_t
559a2a681582929ada667de5d05d5168f8a1f313800Anders Carlsson_dbus_message_get_client_serial (DBusMessage *message)
560a2a681582929ada667de5d05d5168f8a1f313800Anders Carlsson{
56150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return get_int_field (message, FIELD_CLIENT_SERIAL);
562a2a681582929ada667de5d05d5168f8a1f313800Anders Carlsson}
563a2a681582929ada667de5d05d5168f8a1f313800Anders Carlsson
564a2a681582929ada667de5d05d5168f8a1f313800Anders Carlsson/**
5654a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson * Returns the serial that the message is
56650c25505f62786756519ef1e194883360eda82e0Havoc Pennington * a reply to or -1 if none.
5674a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson *
5684a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson * @param message the message
5694a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson * @returns the reply serial
5704a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson */
5714a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlssondbus_int32_t
5724a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson_dbus_message_get_reply_serial  (DBusMessage *message)
5734a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson{
57450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return get_int_field (message, FIELD_REPLY_SERIAL);
5754a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson}
5764a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
5774a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson/**
578502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * Adds a counter to be incremented immediately with the
579502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * size of this message, and decremented by the size
580502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * of this message when this message if finalized.
581502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington *
582502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * @param message the message
583502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * @param counter the counter
584502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington */
585502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Penningtonvoid
586502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington_dbus_message_add_size_counter (DBusMessage *message,
587502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington                                DBusCounter *counter)
588502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington{
589502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  _dbus_assert (message->size_counter == NULL); /* If this fails we may need to keep a list of
590502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington                                                 * counters instead of just one
591502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington                                                 */
592502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
593502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  message->size_counter = counter;
594502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  _dbus_counter_ref (message->size_counter);
595502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
596502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  /* When we can change message size, we may want to
597502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington   * update this each time we do so, or we may want to
598502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington   * just KISS like this.
599502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington   */
600502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  message->size_counter_delta =
601502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington    _dbus_string_get_length (&message->header) +
602502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington    _dbus_string_get_length (&message->body);
603502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
604502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  _dbus_verbose ("message has size %ld\n",
605502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington                 message->size_counter_delta);
606502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
607502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  _dbus_counter_adjust (message->size_counter, message->size_counter_delta);
608502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington}
609502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
61050c25505f62786756519ef1e194883360eda82e0Havoc Penningtonstatic dbus_bool_t
61150c25505f62786756519ef1e194883360eda82e0Havoc Penningtondbus_message_create_header (DBusMessage *message,
61250c25505f62786756519ef1e194883360eda82e0Havoc Pennington                            const char  *service,
61350c25505f62786756519ef1e194883360eda82e0Havoc Pennington                            const char  *name)
614482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington{
615482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington  unsigned int flags;
616482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington
6177ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (!_dbus_string_append_byte (&message->header, message->byte_order))
61850c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return FALSE;
619482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington
620482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington  flags = 0;
621482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington  if (!_dbus_string_append_byte (&message->header, flags))
622482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington    return FALSE;
623482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington
624482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington  if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION))
625482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington    return FALSE;
626482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington
627482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington  if (!_dbus_string_append_byte (&message->header, 0))
62850c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return FALSE;
6291b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
63050c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message->header_fields[FIELD_HEADER_LENGTH].offset = 4;
631482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington  if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
63250c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return FALSE;
6331b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
63450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message->header_fields[FIELD_BODY_LENGTH].offset = 8;
635482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington  if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
63650c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return FALSE;
6371b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
63850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message->header_fields[FIELD_CLIENT_SERIAL].offset = 12;
63950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_marshal_int32 (&message->header, message->byte_order, -1))
64050c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return FALSE;
64150c25505f62786756519ef1e194883360eda82e0Havoc Pennington
6421b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  /* Marshal message service */
64350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (service != NULL)
6441b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    {
64550c25505f62786756519ef1e194883360eda82e0Havoc Pennington      if (!append_string_field (message,
64650c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                FIELD_SERVICE,
64750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                DBUS_HEADER_FIELD_SERVICE,
64850c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                service))
64950c25505f62786756519ef1e194883360eda82e0Havoc Pennington        return FALSE;
6501b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    }
6514a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
65250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (name != NULL);
65350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!append_string_field (message,
65450c25505f62786756519ef1e194883360eda82e0Havoc Pennington                            FIELD_NAME,
65550c25505f62786756519ef1e194883360eda82e0Havoc Pennington                            DBUS_HEADER_FIELD_NAME,
65650c25505f62786756519ef1e194883360eda82e0Havoc Pennington                            name))
65750c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return FALSE;
6587ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
65950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return TRUE;
6601b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
6611b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
6621b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
663041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Locks a message. Allows checking that applications don't keep a
664041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * reference to a message in the outgoing queue and change it
665041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * underneath us. Messages are locked when they enter the outgoing
666041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * queue (dbus_connection_send_message()), and the library complains
667041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * if the message is modified while locked.
668041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
669041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param message the message to lock.
670041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
671041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonvoid
6721b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson_dbus_message_lock (DBusMessage  *message)
673041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
6741b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (!message->locked)
67550c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
67650c25505f62786756519ef1e194883360eda82e0Havoc Pennington      /* Fill in our lengths */
677482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      set_uint_field (message,
678482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington                      FIELD_HEADER_LENGTH,
679482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington                      _dbus_string_get_length (&message->header));
68050c25505f62786756519ef1e194883360eda82e0Havoc Pennington
681482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      set_uint_field (message,
682482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington                      FIELD_BODY_LENGTH,
683482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington                      _dbus_string_get_length (&message->body));
68450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
68550c25505f62786756519ef1e194883360eda82e0Havoc Pennington      message->locked = TRUE;
68650c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
687041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
688041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
68955de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington/** @} */
69055de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington
69155de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington/**
69255de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @defgroup DBusMessage DBusMessage
69355de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @ingroup  DBus
694041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @brief Message to be sent or received over a DBusConnection.
69555de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington *
696041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * A DBusMessage is the most basic unit of communication over a
697041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * DBusConnection. A DBusConnection represents a stream of messages
698041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * received from a remote application, and a stream of messages
699041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * sent to a remote application.
70055de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington *
70155de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @{
70255de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington */
70355de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington
70455de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington/**
70555de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @typedef DBusMessage
70655de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington *
70755de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * Opaque data type representing a message received from or to be
70855de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * sent to another application.
70955de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington */
71055de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington
71150c25505f62786756519ef1e194883360eda82e0Havoc Penningtonstatic DBusMessage*
71250c25505f62786756519ef1e194883360eda82e0Havoc Penningtondbus_message_new_empty_header (void)
71350c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
71450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  DBusMessage *message;
71550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  int i;
71650c25505f62786756519ef1e194883360eda82e0Havoc Pennington
71750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message = dbus_new0 (DBusMessage, 1);
71850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (message == NULL)
71950c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return NULL;
72050c25505f62786756519ef1e194883360eda82e0Havoc Pennington
72150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message->refcount = 1;
72250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message->byte_order = DBUS_COMPILER_BYTE_ORDER;
72350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
72450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  i = 0;
72550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  while (i < FIELD_LAST)
72650c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
72750c25505f62786756519ef1e194883360eda82e0Havoc Pennington      message->header_fields[i].offset = -1;
72850c25505f62786756519ef1e194883360eda82e0Havoc Pennington      ++i;
72950c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
73050c25505f62786756519ef1e194883360eda82e0Havoc Pennington
73150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_init (&message->header, _DBUS_INT_MAX))
73250c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
73350c25505f62786756519ef1e194883360eda82e0Havoc Pennington      dbus_free (message);
73450c25505f62786756519ef1e194883360eda82e0Havoc Pennington      return NULL;
73550c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
73650c25505f62786756519ef1e194883360eda82e0Havoc Pennington
73750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_init (&message->body, _DBUS_INT_MAX))
73850c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
73950c25505f62786756519ef1e194883360eda82e0Havoc Pennington      _dbus_string_free (&message->header);
74050c25505f62786756519ef1e194883360eda82e0Havoc Pennington      dbus_free (message);
74150c25505f62786756519ef1e194883360eda82e0Havoc Pennington      return NULL;
74250c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
74350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
74450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return message;
74550c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
74650c25505f62786756519ef1e194883360eda82e0Havoc Pennington
74750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
74893f222c1d8ed748994f74662671d003495b16d43Havoc Pennington/**
749041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Constructs a new message. Returns #NULL if memory
750041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * can't be allocated for the message.
7511b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
752993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * @todo use DBusString internally to store service and name.
753993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington *
7541b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param service service that the message should be sent to
7551b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param name name of the message
7561b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @returns a new DBusMessage, free with dbus_message_unref()
75793f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * @see dbus_message_unref()
75893f222c1d8ed748994f74662671d003495b16d43Havoc Pennington */
7595a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc PenningtonDBusMessage*
7601b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_message_new (const char *service,
7611b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson		  const char *name)
7625a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington{
763041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusMessage *message;
764041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
76550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message = dbus_message_new_empty_header ();
766041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (message == NULL)
767041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    return NULL;
7685a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington
76950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!dbus_message_create_header (message, service, name))
770271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington    {
77150c25505f62786756519ef1e194883360eda82e0Havoc Pennington      dbus_message_unref (message);
772271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      return NULL;
773271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington    }
774271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
775041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  return message;
7765a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington}
77793f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
7784a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson/**
7794a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson * Constructs a message that is a reply to some other
7804a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson * message. Returns #NULL if memory can't be allocated
7814a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson * for the message.
7824a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson *
7834a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson * @param name the name of the message
7844a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson * @param original_message the message which the created
7854a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson * message is a reply to.
7864a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson * @returns a new DBusMessage, free with dbus_message_unref()
7874a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson * @see dbus_message_new(), dbus_message_unref()
7884a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson */
7894a85d321b4516c6a663e8bdd530ba59018c974dfAnders CarlssonDBusMessage*
7904a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlssondbus_message_new_reply (const char  *name,
7914a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson			DBusMessage *original_message)
7924a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson{
7934a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson  DBusMessage *message;
79450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  const char *sender;
79550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
79650c25505f62786756519ef1e194883360eda82e0Havoc Pennington  sender = get_string_field (original_message,
79750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                             FIELD_SENDER, NULL);
7984a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
79950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (sender != NULL);
8004a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
80150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  message = dbus_message_new (sender, name);
8024a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
8034a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson  if (message == NULL)
8044a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson    return NULL;
8054a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
80650c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_message_set_reply_serial (message,
80750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                       _dbus_message_get_client_serial (original_message)))
80850c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
80950c25505f62786756519ef1e194883360eda82e0Havoc Pennington      dbus_message_unref (message);
81050c25505f62786756519ef1e194883360eda82e0Havoc Pennington      return NULL;
81150c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
8124a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
8134a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson  return message;
8144a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson}
8154a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
8165ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson/**
8175ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * Creates a new message that is an exact replica of the message
8185ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * specified, except that its refcount is set to 1.
8195ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson *
8205ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param message the message.
8215ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @returns the new message.
822487f3c1f91d7197d05605b880f1c9f6246b60d3dAnders Carlsson */
823dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders CarlssonDBusMessage *
824dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlssondbus_message_new_from_message (const DBusMessage *message)
825dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson{
826dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  DBusMessage *retval;
827dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  int i;
828dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson
829dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  retval = dbus_new0 (DBusMessage, 1);
830dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  if (retval == NULL)
831dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson    return NULL;
832dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson
833dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  retval->refcount = 1;
834dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  retval->byte_order = message->byte_order;
835dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson
836dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  if (!_dbus_string_init (&retval->header, _DBUS_INT_MAX))
837dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson    {
838dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      dbus_free (retval);
839dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      return NULL;
840dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson    }
841dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson
842dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  if (!_dbus_string_init (&retval->body, _DBUS_INT_MAX))
843dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson    {
844dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      _dbus_string_free (&retval->header);
845dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      dbus_free (retval);
846dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      return NULL;
847dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson    }
848dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson
849dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  if (!_dbus_string_copy (&message->header, 0,
850dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson			  &retval->header, 0))
851dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson    {
852dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      _dbus_string_free (&retval->header);
853dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      _dbus_string_free (&retval->body);
854dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      dbus_free (retval);
855dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson
856dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      return NULL;
857dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson    }
858dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson
859dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  if (!_dbus_string_copy (&message->body, 0,
860dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson			  &retval->body, 0))
861dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson    {
862dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      _dbus_string_free (&retval->header);
863dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      _dbus_string_free (&retval->body);
864dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      dbus_free (retval);
865dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson
866dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      return NULL;
867dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson    }
868dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson
869dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  for (i = 0; i < FIELD_LAST; i++)
870dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson    {
871dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson      retval->header_fields[i].offset = message->header_fields[i].offset;
872dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson    }
873dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson
874dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson  return retval;
875dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson}
876dec1fa3bd5f106ba5b2c749372231e3dd4bf9e7bAnders Carlsson
87793f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
87893f222c1d8ed748994f74662671d003495b16d43Havoc Pennington/**
87993f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * Increments the reference count of a DBusMessage.
88093f222c1d8ed748994f74662671d003495b16d43Havoc Pennington *
8818164139fa6259257817898b3d389d96bd60f8c13Havoc Pennington * @param message The message
88293f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * @see dbus_message_unref
88393f222c1d8ed748994f74662671d003495b16d43Havoc Pennington */
88493f222c1d8ed748994f74662671d003495b16d43Havoc Penningtonvoid
88593f222c1d8ed748994f74662671d003495b16d43Havoc Penningtondbus_message_ref (DBusMessage *message)
88693f222c1d8ed748994f74662671d003495b16d43Havoc Pennington{
8871b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  _dbus_assert (message->refcount > 0);
8881b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
889041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  message->refcount += 1;
89093f222c1d8ed748994f74662671d003495b16d43Havoc Pennington}
89193f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
89293f222c1d8ed748994f74662671d003495b16d43Havoc Pennington/**
89393f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * Decrements the reference count of a DBusMessage.
89493f222c1d8ed748994f74662671d003495b16d43Havoc Pennington *
8958164139fa6259257817898b3d389d96bd60f8c13Havoc Pennington * @param message The message
89693f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * @see dbus_message_ref
89793f222c1d8ed748994f74662671d003495b16d43Havoc Pennington */
89893f222c1d8ed748994f74662671d003495b16d43Havoc Penningtonvoid
89993f222c1d8ed748994f74662671d003495b16d43Havoc Penningtondbus_message_unref (DBusMessage *message)
90093f222c1d8ed748994f74662671d003495b16d43Havoc Pennington{
901041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_assert (message->refcount > 0);
902041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
903041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  message->refcount -= 1;
904041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (message->refcount == 0)
905041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
906502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington      if (message->size_counter != NULL)
907502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington        {
908502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington          _dbus_counter_adjust (message->size_counter,
909502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington                                - message->size_counter_delta);
910502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington          _dbus_counter_unref (message->size_counter);
911502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington        }
912502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
913271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      _dbus_string_free (&message->header);
914271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      _dbus_string_free (&message->body);
91550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
916041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      dbus_free (message);
917041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
918041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
919041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
92017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington/**
92117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * Gets the name of a message.
9225175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson *
92317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * @param message the message
92417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * @returns the message name (should not be freed)
92517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington */
92617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Penningtonconst char*
92717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Penningtondbus_message_get_name (DBusMessage *message)
92817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington{
92950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return get_string_field (message, FIELD_NAME, NULL);
93017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington}
93117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
9325175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson/**
933f0dbc1bdd06e1cb4f32b7fe05ee1287ae5f9df85Anders Carlsson * Gets the destination service of a message.
934f0dbc1bdd06e1cb4f32b7fe05ee1287ae5f9df85Anders Carlsson *
935f0dbc1bdd06e1cb4f32b7fe05ee1287ae5f9df85Anders Carlsson * @param message the message
936f0dbc1bdd06e1cb4f32b7fe05ee1287ae5f9df85Anders Carlsson * @returns the message destination service (should not be freed)
937f0dbc1bdd06e1cb4f32b7fe05ee1287ae5f9df85Anders Carlsson */
938f0dbc1bdd06e1cb4f32b7fe05ee1287ae5f9df85Anders Carlssonconst char*
939f0dbc1bdd06e1cb4f32b7fe05ee1287ae5f9df85Anders Carlssondbus_message_get_service (DBusMessage *message)
940f0dbc1bdd06e1cb4f32b7fe05ee1287ae5f9df85Anders Carlsson{
94150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return get_string_field (message, FIELD_SERVICE, NULL);
942f0dbc1bdd06e1cb4f32b7fe05ee1287ae5f9df85Anders Carlsson}
943f0dbc1bdd06e1cb4f32b7fe05ee1287ae5f9df85Anders Carlsson
944f0dbc1bdd06e1cb4f32b7fe05ee1287ae5f9df85Anders Carlsson/**
9451f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * Appends fields to a message given a variable argument
9461f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * list. The variable argument list should contain the type
9471f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * of the field followed by the value to add.
9481f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * The list is terminated with 0.
9491f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson *
9501f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * @param message the message
951502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * @param first_field_type type of the first field
952993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * @param ... value of first field, list of additional type-value pairs
9531f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * @returns #TRUE on success
9541f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson */
9551f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlssondbus_bool_t
9561f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlssondbus_message_append_fields (DBusMessage *message,
957993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                            int first_field_type,
9581f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson			    ...)
9591f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson{
9601f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  dbus_bool_t retval;
9611f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  va_list var_args;
9621f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
963993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  va_start (var_args, first_field_type);
964993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  retval = dbus_message_append_fields_valist (message,
965993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                                              first_field_type,
966993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                                              var_args);
9671f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  va_end (var_args);
9681f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
9691f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  return retval;
9701f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson}
9711f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
9721f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson/**
9731f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * This function takes a va_list for use by language bindings
9741f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson *
9751f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * @see dbus_message_append_fields.
9761f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * @param message the message
977993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * @param first_field_type type of first field
978993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * @param var_args value of first field, then list of type/value pairs
9791f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * @returns #TRUE on success
9801f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson */
9811f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlssondbus_bool_t
9821f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlssondbus_message_append_fields_valist (DBusMessage *message,
983993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                                   int          first_field_type,
9841f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson				   va_list      var_args)
9851f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson{
9861f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  int type, old_len;
9871f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
9881f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  old_len = _dbus_string_get_length (&message->body);
9891f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
990993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  type = first_field_type;
9911f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
9921f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  while (type != 0)
9931f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson    {
9941f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson      switch (type)
9951f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	{
9961f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	case DBUS_TYPE_INT32:
9971f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  if (!dbus_message_append_int32 (message, va_arg (var_args, dbus_int32_t)))
9981f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    goto enomem;
9991f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  break;
10001f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	case DBUS_TYPE_UINT32:
10011f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  if (!dbus_message_append_uint32 (message, va_arg (var_args, dbus_uint32_t)))
10021f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    goto enomem;
10031f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  break;
10041f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	case DBUS_TYPE_DOUBLE:
10051f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  if (!dbus_message_append_double (message, va_arg (var_args, double)))
10061f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    goto enomem;
10071f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  break;
10081f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	case DBUS_TYPE_STRING:
10091f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  if (!dbus_message_append_string (message, va_arg (var_args, const char *)))
10101f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    goto enomem;
10111f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  break;
10121f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	case DBUS_TYPE_BYTE_ARRAY:
10131f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  {
10141f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    int len;
10151f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    unsigned char *data;
10161f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
10171f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    data = va_arg (var_args, unsigned char *);
10181f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    len = va_arg (var_args, int);
10191f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
10201f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    if (!dbus_message_append_byte_array (message, data, len))
10211f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	      goto enomem;
10221f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  }
1023993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington          break;
1024dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	case DBUS_TYPE_STRING_ARRAY:
1025dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	  {
1026dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    int len;
1027dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    const char **data;
1028dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
1029dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    data = va_arg (var_args, const char **);
1030dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    len = va_arg (var_args, int);
1031dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
1032dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    if (!dbus_message_append_string_array (message, data, len))
1033dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	      goto enomem;
1034dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	  }
1035dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	  break;
1036dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
10371f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	default:
10381f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  _dbus_warn ("Unknown field type %d\n", type);
10391f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	}
10401f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
10411f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson      type = va_arg (var_args, int);
10421f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson    }
10431f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
10441f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  return TRUE;
10451f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
10461f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson enomem:
10471f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  _dbus_string_set_length (&message->body, old_len);
10481f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  return FALSE;
10491f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson}
10501f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
10511f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson/**
10525175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * Appends a 32 bit signed integer to the message.
10535175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson *
10545175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @param message the message
10555175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @param value the integer value
10565175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @returns #TRUE on success
10575175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson */
10585175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlssondbus_bool_t
10595175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlssondbus_message_append_int32 (DBusMessage  *message,
10605175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson			   dbus_int32_t  value)
10615175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson{
10625175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  _dbus_assert (!message->locked);
10635175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
10645175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_INT32))
10653d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson    {
10663d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson      _dbus_string_shorten (&message->body, 1);
10673d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson      return FALSE;
10683d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson    }
10695175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
10705175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  return _dbus_marshal_int32 (&message->body,
10717ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington			      message->byte_order, value);
10725175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson}
10735175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
10745175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson/**
10755175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * Appends a 32 bit unsigned integer to the message.
10765175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson *
10775175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @param message the message
10785175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @param value the integer value
10795175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @returns #TRUE on success
10805175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson */
10815175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlssondbus_bool_t
10825175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlssondbus_message_append_uint32 (DBusMessage   *message,
10835175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson			    dbus_uint32_t  value)
10845175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson{
10855175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  _dbus_assert (!message->locked);
10865175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
10875175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_UINT32))
10883d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson    {
10893d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson      _dbus_string_shorten (&message->body, 1);
10903d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson      return FALSE;
10913d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson    }
10925175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
10935175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  return _dbus_marshal_uint32 (&message->body,
10947ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington			       message->byte_order, value);
10955175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson}
10965175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
10975175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson/**
10985175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * Appends a double value to the message.
10995175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson *
11005175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @param message the message
11015175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @param value the double value
11025175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @returns #TRUE on success
11035175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson */
11045175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlssondbus_bool_t
11055175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlssondbus_message_append_double (DBusMessage *message,
11065175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson			    double       value)
11075175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson{
11085175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  _dbus_assert (!message->locked);
11095175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
11101b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_DOUBLE))
11113d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson    {
11123d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson      _dbus_string_shorten (&message->body, 1);
11133d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson      return FALSE;
11143d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson    }
11155175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
11165175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  return _dbus_marshal_double (&message->body,
11177ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington			       message->byte_order, value);
11185175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson}
11195175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
11205175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson/**
11215175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * Appends a UTF-8 string to the message.
11225175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson *
11235175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @param message the message
11245175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @param value the string
11255175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @returns #TRUE on success
11265175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson */
11275175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlssondbus_bool_t
11285175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlssondbus_message_append_string (DBusMessage *message,
11295175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson			    const char  *value)
11305175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson{
11315175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  _dbus_assert (!message->locked);
11325175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
11331b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_STRING))
11343d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson    {
11353d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson      _dbus_string_shorten (&message->body, 1);
11363d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson      return FALSE;
11373d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson    }
11385175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
11395175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  return _dbus_marshal_string (&message->body,
11407ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington			       message->byte_order, value);
11415175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson}
11425175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
11435175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson/**
11445175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * Appends a byte array to the message.
11455175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson *
11465175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @param message the message
11475175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @param value the array
11485175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @param len the length of the array
11495175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson * @returns #TRUE on success
11505175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson */
11515175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlssondbus_bool_t
11525175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlssondbus_message_append_byte_array (DBusMessage         *message,
11535175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson				unsigned const char *value,
11545175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson				int                 len)
11555175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson{
11565175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  _dbus_assert (!message->locked);
11575175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
11585175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_BYTE_ARRAY))
11593d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson    {
11603d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson      _dbus_string_shorten (&message->body, 1);
11613d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson      return FALSE;
11623d2dee2a7ff006d95a8f1225db80d49883b13a76Anders Carlsson    }
11635175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
11645175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson  return _dbus_marshal_byte_array (&message->body,
11657ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington				   message->byte_order, value, len);
11665175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson}
11675175ad00e1d648a89efdf8d397b31bf84fd203c8Anders Carlsson
11681b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
1169dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * Appends a string array to the message.
1170dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson *
1171dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * @param message the message
1172dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * @param value the array
1173dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * @param len the length of the array
1174dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * @returns #TRUE on success
1175dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson */
1176dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlssondbus_bool_t
1177dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlssondbus_message_append_string_array (DBusMessage *message,
1178dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson				  const char **value,
1179dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson				  int          len)
1180dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson{
1181dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson  _dbus_assert (!message->locked);
1182dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
1183dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson  if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_STRING_ARRAY))
1184dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson    {
1185dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson      _dbus_string_shorten (&message->body, 1);
1186dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson      return FALSE;
1187dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson    }
1188dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
1189dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson  return _dbus_marshal_string_array (&message->body,
11907ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington				     message->byte_order, value, len);
1191dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson}
1192dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
1193dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson/**
11941f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * Gets fields from a message given a variable argument list.
11951f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * The variable argument list should contain the type of the
11961f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * field followed by a pointer to where the value should be
11971f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * stored. The list is terminated with 0.
11981f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson *
119950c25505f62786756519ef1e194883360eda82e0Havoc Pennington *  @todo rename get_args to avoid confusion with header fields
120050c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
12011f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * @param message the message
1202993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * @param first_field_type the first field type
1203993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * @param ... location for first field value, then list of type-location pairs
12041b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson * @returns result code
12051f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson */
12061b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders CarlssonDBusResultCode
12071f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlssondbus_message_get_fields (DBusMessage *message,
1208993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                         int          first_field_type,
12091f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson			 ...)
12101f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson{
12111b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson  DBusResultCode retval;
12121f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  va_list var_args;
12131f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
1214993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  va_start (var_args, first_field_type);
1215993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  retval = dbus_message_get_fields_valist (message, first_field_type, var_args);
12161f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  va_end (var_args);
12171f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12181f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  return retval;
12191f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson}
12201f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12211f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson/**
12221f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * This function takes a va_list for use by language bindings
12231f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson *
1224993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * @todo this function (or some lower-level non-convenience function)
1225993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * needs better error handling; should allow the application to
1226993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * distinguish between out of memory, and bad data from the remote
1227993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * app. It also needs to not leak a bunch of args when it gets
1228993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * to the arg that's bad, as that would be a security hole
1229993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * (allow one app to force another to leak memory)
1230993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington *
12311b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson * @todo We need to free the field data when an error occurs.
12321b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson *
123350c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @todo rename get_args_valist to avoid confusion with header fields
123450c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
12351f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * @see dbus_message_get_fields
12361f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson * @param message the message
1237993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * @param first_field_type type of the first field
1238993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * @param var_args return location for first field, followed by list of type/location pairs
12391b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson * @returns result code
12401f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson */
12411b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders CarlssonDBusResultCode
12421f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlssondbus_message_get_fields_valist (DBusMessage *message,
1243993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                                int          first_field_type,
12441f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson				va_list      var_args)
12451f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson{
12461f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  int spec_type, msg_type, i;
12471f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  DBusMessageIter *iter;
12481f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12491f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  iter = dbus_message_get_fields_iter (message);
12501f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12511f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  if (iter == NULL)
1252dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson    return DBUS_RESULT_NO_MEMORY;
12531f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
1254993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  spec_type = first_field_type;
12551f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  i = 0;
12561f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12571f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  while (spec_type != 0)
12581f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson    {
12591f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson      msg_type = dbus_message_iter_get_field_type (iter);
1260000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson
12611f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson      if (msg_type != spec_type)
12621f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	{
12631b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson	  _dbus_verbose ("Field %d is specified to be of type \"%s\", but "
12641b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson			 "is actually of type \"%s\"\n", i,
12651b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson			 _dbus_type_to_string (spec_type),
12661b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson			 _dbus_type_to_string (msg_type));
12671f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  dbus_message_iter_unref (iter);
12681f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12691b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson	  return DBUS_RESULT_INVALID_FIELDS;
12701f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	}
12711f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12721f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson      switch (spec_type)
12731f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	{
12741f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	case DBUS_TYPE_INT32:
12751f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  {
12761f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    dbus_int32_t *ptr;
12771f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12781f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    ptr = va_arg (var_args, dbus_int32_t *);
12791f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12801f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    *ptr = dbus_message_iter_get_int32 (iter);
12811f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    break;
12821f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  }
12831f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	case DBUS_TYPE_UINT32:
12841f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  {
12851f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    dbus_uint32_t *ptr;
12861f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12871f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    ptr = va_arg (var_args, dbus_uint32_t *);
12881f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12891f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    *ptr = dbus_message_iter_get_uint32 (iter);
12901f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    break;
12911f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  }
12921f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12931f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	case DBUS_TYPE_DOUBLE:
12941f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  {
12951f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    double *ptr;
12961f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12971f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    ptr = va_arg (var_args, double *);
12981f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
12991f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    *ptr = dbus_message_iter_get_double (iter);
13001f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    break;
13011f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  }
13021f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
13031f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	case DBUS_TYPE_STRING:
13041f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  {
13051f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    char **ptr;
13061f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
13071f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    ptr = va_arg (var_args, char **);
13081f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
13091f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    *ptr = dbus_message_iter_get_string (iter);
13101b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson
13111b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson	    if (!*ptr)
13121b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson	      return DBUS_RESULT_NO_MEMORY;
13131b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson
13141f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	    break;
13151f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  }
1316000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson
1317000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson	case DBUS_TYPE_BYTE_ARRAY:
1318000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson	  {
1319dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    unsigned char **ptr;
1320000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson	    int *len;
1321000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson
1322dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    ptr = va_arg (var_args, unsigned char **);
1323000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson	    len = va_arg (var_args, int *);
1324000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson
1325000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson	    *ptr = dbus_message_iter_get_byte_array (iter, len);
13261b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson
13271b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson	    if (!*ptr)
13281b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson	      return DBUS_RESULT_NO_MEMORY;
13291b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson
1330000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson	    break;
1331000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson	  }
1332dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	case DBUS_TYPE_STRING_ARRAY:
1333dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	  {
1334dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    char ***ptr;
1335dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    int *len;
1336dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
1337dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    ptr = va_arg (var_args, char ***);
1338dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    len = va_arg (var_args, int *);
1339dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
1340dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    *ptr = dbus_message_iter_get_string_array (iter, len);
1341dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
1342dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    if (!*ptr)
1343dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	      return DBUS_RESULT_NO_MEMORY;
1344dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
1345dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	    break;
1346dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson	  }
1347000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson	default:
13481f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	  _dbus_warn ("Unknown field type %d\n", spec_type);
13491f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	}
13501f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
13511f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson      spec_type = va_arg (var_args, int);
13521f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson      if (spec_type != 0 && !dbus_message_iter_next (iter))
13531f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	{
135450c25505f62786756519ef1e194883360eda82e0Havoc Pennington	  _dbus_verbose ("More fields than exist in the message were specified or field is corrupt\n");
13551f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
1356993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington	  dbus_message_iter_unref (iter);
13571b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson	  return DBUS_RESULT_INVALID_FIELDS;
13581f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson	}
13591f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson      i++;
13601f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson    }
13611f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
13621f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  dbus_message_iter_unref (iter);
13631b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson  return DBUS_RESULT_SUCCESS;
13641f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson}
13651f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
13661f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson/**
13671b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Returns a DBusMessageIter representing the fields of the
13681b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * message passed in.
13691b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
1370993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * @todo IMO the message iter should follow the GtkTextIter pattern,
1371993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * a static object with a "stamp" value used to detect invalid
1372993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * iter uses (uninitialized or after changing the message).
1373993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * ref/unref is kind of annoying to deal with, and slower too.
1374993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington * This implies not ref'ing the message from the iter.
1375993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington *
137650c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @todo rename get_args_iter to avoid confusion with header fields
137750c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
13781b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param message the message
13791b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @returns a new iter.
13801b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
13811b53cbcce333381754b0568b740ece550a8f6ac9Anders CarlssonDBusMessageIter *
13821b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_message_get_fields_iter (DBusMessage *message)
13831b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
13841b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  DBusMessageIter *iter;
13851b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
13861b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  iter = dbus_new (DBusMessageIter, 1);
13871b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
13881b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  dbus_message_ref (message);
13891b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
13901b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  iter->refcount = 1;
13911b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  iter->message = message;
13921b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  iter->pos = 0;
13931b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
13941b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  return iter;
13951b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
13961b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
13971b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
13981b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Increments the reference count of a DBusMessageIter.
13991b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
14001b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param iter the message iter
14011b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @see dbus_message_iter_unref
14021b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
14031b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssonvoid
14041b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_message_iter_ref (DBusMessageIter *iter)
14051b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
14061b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  _dbus_assert (iter->refcount > 0);
14071b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14081b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  iter->refcount += 1;
14091b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
14101b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14111b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
14121b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Decrements the reference count of a DBusMessageIter.
14131b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
14141b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param iter The message iter
14151b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @see dbus_message_iter_ref
14161b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
14171b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssonvoid
14181b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_message_iter_unref (DBusMessageIter *iter)
14191b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
14201b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  _dbus_assert (iter->refcount > 0);
14211b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14221b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  iter->refcount -= 1;
14231b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14241b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (iter->refcount == 0)
14251b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    {
14261b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      dbus_message_unref (iter->message);
14271b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14281b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      dbus_free (iter);
14291b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    }
14301b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
14311b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14321b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
14331b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Checks if an iterator has any more fields.
14341b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
14351b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param iter the message iter
14361b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @returns #TRUE if there are more fields
14371b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * following
14381b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
14391b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_bool_t
14401b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_message_iter_has_next (DBusMessageIter *iter)
14411b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
14421b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  int end_pos;
14431b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14447ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (!_dbus_marshal_get_arg_end_pos (&iter->message->body,
14457ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                                      iter->message->byte_order,
14467ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                                      iter->pos, &end_pos))
14471b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    return FALSE;
14481b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14491b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (end_pos >= _dbus_string_get_length (&iter->message->body))
14501b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    return FALSE;
14511b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14521b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  return TRUE;
14531b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
14541b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14551b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
14561b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Moves the iterator to the next field.
14571b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
14581b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param iter The message iter
14591b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @returns #TRUE if the iterator was moved to the next field
14601b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
14611b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_bool_t
14621b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_message_iter_next (DBusMessageIter *iter)
14631b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
14641b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  int end_pos;
14651b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14667ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (!_dbus_marshal_get_arg_end_pos (&iter->message->body,
14677ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                                      iter->message->byte_order,
14687ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                                      iter->pos, &end_pos))
14691b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    return FALSE;
14701b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14711b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (end_pos >= _dbus_string_get_length (&iter->message->body))
14721b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    return FALSE;
14731b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14741b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  iter->pos = end_pos;
14751b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14761b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  return TRUE;
14771b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
14781b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14791b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
14801b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Returns the field type of the field that the
14811b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * message iterator points at.
14821b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
14831b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param iter the message iter
14841b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @returns the field type
14851b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
14861b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssonint
14871b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_message_iter_get_field_type (DBusMessageIter *iter)
14881b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
14891b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  const char *data;
1490000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson
14911b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (iter->pos >= _dbus_string_get_length (&iter->message->body))
14921b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    return DBUS_TYPE_INVALID;
14931b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14941b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  _dbus_string_get_const_data_len (&iter->message->body, &data, iter->pos, 1);
14951b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
1496dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson  if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_STRING_ARRAY)
14971b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    return *data;
14981b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
14991b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  return DBUS_TYPE_INVALID;
15001b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
15011b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
15021b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
15031b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Returns the string value that an iterator may point to.
15041b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Note that you need to check that the iterator points to
15051b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * a string value before using this function.
15061b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
15071b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @see dbus_message_iter_get_field_type
15081b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param iter the message iter
15091b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @returns the string
15101b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
15111b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssonchar *
15121b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_message_iter_get_string (DBusMessageIter *iter)
15131b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
15141b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  _dbus_assert (dbus_message_iter_get_field_type (iter) == DBUS_TYPE_STRING);
15151b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
15161b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  return _dbus_demarshal_string (&iter->message->body, iter->message->byte_order,
1517993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                                 iter->pos + 1, NULL);
15181b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
15191b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
15201b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
15211b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Returns the 32 bit signed integer value that an iterator may point to.
15221b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Note that you need to check that the iterator points to
15231b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * a string value before using this function.
15241b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
15251b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @see dbus_message_iter_get_field_type
15261b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param iter the message iter
15271b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @returns the integer
15281b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
15291b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssonint
15301b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_message_iter_get_int32 (DBusMessageIter *iter)
15311b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
15321b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  return _dbus_demarshal_int32 (&iter->message->body, iter->message->byte_order,
15331b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson				iter->pos + 1, NULL);
15341b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
15351b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
15361b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
15371b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Returns the 32 bit unsigned integer value that an iterator may point to.
15381b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Note that you need to check that the iterator points to
15391b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * a string value before using this function.
15401b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
15411b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @see dbus_message_iter_get_field_type
15421b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param iter the message iter
15431b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @returns the integer
15441b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
15451b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssonint
15461b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_message_iter_get_uint32 (DBusMessageIter *iter)
15471b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
15481b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  return _dbus_demarshal_uint32 (&iter->message->body, iter->message->byte_order,
15491b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson				 iter->pos + 1, NULL);
15501b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
15511b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
15521b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
15531b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Returns the double value that an iterator may point to.
15541b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Note that you need to check that the iterator points to
15551b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * a string value before using this function.
15561b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
15571b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @see dbus_message_iter_get_field_type
15581b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @param iter the message iter
15591b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @returns the double
15601b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
15611b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondouble
15621b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_message_iter_get_double (DBusMessageIter *iter)
15631b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
15641b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  return _dbus_demarshal_double (&iter->message->body, iter->message->byte_order,
15651b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson				 iter->pos + 1, NULL);
15661b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
15671b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
1568502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington/**
1569502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * Returns the byte array that the iterator may point to.
1570502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * Note that you need to check that the iterator points
1571502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * to a byte array prior to using this function.
1572502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington *
1573502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * @todo this function should probably take "unsigned char **" as
1574502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * an out param argument, and return boolean or result code.
1575502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington *
1576502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * @param iter the iterator
1577502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * @param len return location for length of byte array
1578502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * @returns the byte array
1579502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington */
1580000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlssonunsigned char *
1581502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Penningtondbus_message_iter_get_byte_array (DBusMessageIter *iter,
1582502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington                                  int             *len)
1583000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson{
1584000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson  _dbus_assert (dbus_message_iter_get_field_type (iter) == DBUS_TYPE_BYTE_ARRAY);
1585000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson
1586000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson  return _dbus_demarshal_byte_array (&iter->message->body, iter->message->byte_order,
1587000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson				     iter->pos + 1, NULL, len);
1588000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson}
1589000d29a283b06517f0cfb599516a390e3afbf25cAnders Carlsson
1590dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson/**
1591dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * Returns the string array that the iterator may point to.
1592dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * Note that you need to check that the iterator points
1593dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * to a byte array prior to using this function.
1594dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson *
1595dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * @todo this function should probably take "char **" as
1596dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * an out param argument, and return boolean or result code.
1597dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson *
1598dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * @param iter the iterator
1599dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * @param len return location for length of byte array
1600dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * @returns the byte array
1601dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson */
1602dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlssonchar **
1603dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlssondbus_message_iter_get_string_array (DBusMessageIter *iter,
1604dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson				    int             *len)
1605dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson{
1606dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson  _dbus_assert (dbus_message_iter_get_field_type (iter) == DBUS_TYPE_STRING_ARRAY);
1607dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
1608dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson  return _dbus_demarshal_string_array (&iter->message->body, iter->message->byte_order,
1609dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson				       iter->pos + 1, NULL, len);
1610dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson}
1611dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
1612dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson/**
161350c25505f62786756519ef1e194883360eda82e0Havoc Pennington * Sets the message sender.
161450c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
1615dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * @param message the message
1616dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson * @param sender the sender
161750c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @returns #FALSE if not enough memory
1618dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson */
161950c25505f62786756519ef1e194883360eda82e0Havoc Penningtondbus_bool_t
1620dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlssondbus_message_set_sender (DBusMessage  *message,
162150c25505f62786756519ef1e194883360eda82e0Havoc Pennington                         const char   *sender)
1622dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson{
162350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (!message->locked);
1624dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
162550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (sender == NULL)
162650c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
16278ca39d9925df6cce64688a2315a2a424beb7bd55Havoc Pennington      delete_string_field (message, FIELD_SENDER);
162850c25505f62786756519ef1e194883360eda82e0Havoc Pennington      return TRUE;
162950c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
163050c25505f62786756519ef1e194883360eda82e0Havoc Pennington  else
163150c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
163250c25505f62786756519ef1e194883360eda82e0Havoc Pennington      return set_string_field (message,
163350c25505f62786756519ef1e194883360eda82e0Havoc Pennington                               FIELD_SENDER,
163450c25505f62786756519ef1e194883360eda82e0Havoc Pennington                               sender);
163550c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
1636dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson}
1637dc6a61a15b2d9cdc6504753fa9eb0a718f99d6d8Anders Carlsson
16388ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlssonvoid
16398ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlssondbus_message_set_is_error_reply (DBusMessage *message,
16408ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson				 dbus_bool_t  is_error_reply)
16418ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson{
16428ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson  char *header;
16438ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson
16448ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson  _dbus_assert (!message->locked);
16458ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson
16468ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson  _dbus_string_get_data_len (&message->header, &header, 1, 1);
16478ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson
16488ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson  if (is_error_reply)
16498ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson    *header |= DBUS_HEADER_FLAG_IS_ERROR_REPLY;
16508ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson  else
16518ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson    *header &= ~DBUS_HEADER_FLAG_IS_ERROR_REPLY;
16528ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson
16538ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson}
16548ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson
16558ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlssondbus_bool_t
16568ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlssondbus_message_get_is_error_reply (DBusMessage *message)
16578ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson{
16588ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson  const char *header;
16598ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson
16608ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson  _dbus_string_get_data_len (&message->header, &header, 1, 1);
16618ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson
16628ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson  return (*header & DBUS_HEADER_FLAG_IS_ERROR_REPLY) != 0;
16638ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson}
16648ab042b9571dda44a5afcfe50e0d29dc9b58ecaeAnders Carlsson
16652f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington/**
16662f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * Gets the service which originated this message,
16672f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * or #NULL if unknown or inapplicable.
16682f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington *
16692f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * @param message the message
16702f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * @returns the service name or #NULL
16712f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington */
1672fdddf7246da9ea6ce841146e2befe843aede0466Anders Carlssonconst char*
1673fdddf7246da9ea6ce841146e2befe843aede0466Anders Carlssondbus_message_get_sender (DBusMessage *message)
1674fdddf7246da9ea6ce841146e2befe843aede0466Anders Carlsson{
167550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return get_string_field (message, FIELD_SENDER, NULL);
1676fdddf7246da9ea6ce841146e2befe843aede0466Anders Carlsson}
1677fdddf7246da9ea6ce841146e2befe843aede0466Anders Carlsson
1678041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/** @} */
1679041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1680041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
1681041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @addtogroup DBusMessageInternals
1682041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
1683041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @{
1684041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
1685041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
1686041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @typedef DBusMessageLoader
1687041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
1688041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * The DBusMessageLoader object encapsulates the process of converting
1689041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * a byte stream into a series of DBusMessage. It buffers the incoming
1690041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * bytes as efficiently as possible, and generates a queue of
1691041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * messages. DBusMessageLoader is typically used as part of a
1692041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * DBusTransport implementation. The DBusTransport then hands off
1693041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * the loaded messages to a DBusConnection, making the messages
1694041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * visible to the application.
1695041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
1696041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
1697041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
16987ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington/* we definitely use signed ints for sizes, so don't exceed
16997ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * _DBUS_INT_MAX; and add 16 for paranoia, since a message
17007ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * over 128M is pretty nuts anyhow.
17017ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington */
17025ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
17035ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson/**
17045ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * The maximum sane message size.
17055ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson */
17067ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington#define MAX_SANE_MESSAGE_SIZE (_DBUS_INT_MAX/16)
17077ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
1708041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
1709041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Implementation details of DBusMessageLoader.
1710041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * All members are private.
1711041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
1712041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonstruct DBusMessageLoader
1713041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
1714041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  int refcount;        /**< Reference count. */
1715041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1716271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  DBusString data;     /**< Buffered data */
1717271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
1718041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusList *messages;  /**< Complete messages. */
1719502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
1720502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  long max_message_size; /**< Maximum size of a message */
1721041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1722041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  unsigned int buffer_outstanding : 1; /**< Someone is using the buffer to read */
1723ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
1724ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  unsigned int corrupted : 1; /**< We got broken data, and are no longer working */
1725041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington};
1726041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1727041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
1728041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * The initial buffer size of the message loader.
1729041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
1730041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @todo this should be based on min header size plus some average
1731041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * body size, or something. Or rather, the min header size only, if we
1732041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * want to try to read only the header, store that in a DBusMessage,
1733041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * then read only the body and store that, etc., depends on
1734041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * how we optimize _dbus_message_loader_get_buffer() and what
1735041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * the exact message format is.
1736041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
1737041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#define INITIAL_LOADER_DATA_LEN 32
1738041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1739041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
1740041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Creates a new message loader. Returns #NULL if memory can't
1741041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * be allocated.
1742041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
1743041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @returns new loader, or #NULL.
1744041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
1745041b0767b284034aee09e9a0de2a3844b8cc546aHavoc PenningtonDBusMessageLoader*
1746041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_new (void)
1747041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
1748041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusMessageLoader *loader;
1749041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1750041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  loader = dbus_new0 (DBusMessageLoader, 1);
1751041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (loader == NULL)
1752041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    return NULL;
1753041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1754502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  loader->refcount = 1;
1755271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
1756502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  /* Try to cap message size at something that won't *totally* hose
1757502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington   * the system if we have a couple of them.
1758502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington   */
1759502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
1760502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
1761271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  if (!_dbus_string_init (&loader->data, _DBUS_INT_MAX))
1762271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington    {
1763271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      dbus_free (loader);
1764271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      return NULL;
1765271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington    }
1766271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
1767271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  /* preallocate the buffer for speed, ignore failure */
1768ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
1769ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_string_set_length (&loader->data, 0);
1770041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1771041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  return loader;
1772041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
1773041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1774041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
1775041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Increments the reference count of the loader.
1776041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
1777041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param loader the loader.
1778041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
1779041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonvoid
1780041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_ref (DBusMessageLoader *loader)
1781041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
1782041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  loader->refcount += 1;
1783041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
1784041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1785041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
1786041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Decrements the reference count of the loader and finalizes the
1787041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * loader when the count reaches zero.
1788041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
1789041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param loader the loader.
1790041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
1791041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonvoid
1792041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_unref (DBusMessageLoader *loader)
1793041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
1794041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  loader->refcount -= 1;
1795041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (loader->refcount == 0)
1796041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
1797041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_list_foreach (&loader->messages,
1798041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                          (DBusForeachFunction) dbus_message_unref,
1799041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                          NULL);
1800041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_list_clear (&loader->messages);
1801271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      _dbus_string_free (&loader->data);
1802041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      dbus_free (loader);
1803041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
1804041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
1805041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1806041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
1807041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Gets the buffer to use for reading data from the network.  Network
1808041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * data is read directly into an allocated buffer, which is then used
1809041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * in the DBusMessage, to avoid as many extra memcpy's as possible.
1810041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * The buffer must always be returned immediately using
1811041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * _dbus_message_loader_return_buffer(), even if no bytes are
1812041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * successfully read.
1813041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
1814041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @todo this function can be a lot more clever. For example
1815041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * it can probably always return a buffer size to read exactly
1816041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * the body of the next message, thus avoiding any memory wastage
1817041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * or reallocs.
1818041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
1819041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param loader the message loader.
1820271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington * @param buffer the buffer
1821041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
1822271fa7fc335f332bb2be3beeef735334546c4957Havoc Penningtonvoid
1823041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_get_buffer (DBusMessageLoader  *loader,
1824271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                                 DBusString        **buffer)
1825041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
1826041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_assert (!loader->buffer_outstanding);
1827041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1828271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  *buffer = &loader->data;
1829041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1830041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  loader->buffer_outstanding = TRUE;
1831041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
1832041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
1833041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
18341b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * The smallest header size that can occur.
18351b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * (It won't be valid)
18361b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
18371b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson#define DBUS_MINIMUM_HEADER_SIZE 16
18381b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
1839993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington/** Pack four characters as in "abcd" into a uint32 */
1840993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington#define FOUR_CHARS_TO_UINT32(a, b, c, d)                \
1841993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                      ((((dbus_uint32_t)a) << 24) |     \
1842993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                       (((dbus_uint32_t)b) << 16) |     \
1843993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                       (((dbus_uint32_t)c) << 8)  |     \
1844993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                       ((dbus_uint32_t)d))
1845993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
1846993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington/** DBUS_HEADER_FIELD_NAME packed into a dbus_uint32_t */
1847993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington#define DBUS_HEADER_FIELD_NAME_AS_UINT32    \
1848993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  FOUR_CHARS_TO_UINT32 ('n', 'a', 'm', 'e')
1849993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
1850993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington/** DBUS_HEADER_FIELD_SERVICE packed into a dbus_uint32_t */
1851993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington#define DBUS_HEADER_FIELD_SERVICE_AS_UINT32 \
1852993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  FOUR_CHARS_TO_UINT32 ('s', 'r', 'v', 'c')
1853993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
1854993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington/** DBUS_HEADER_FIELD_REPLY packed into a dbus_uint32_t */
1855993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington#define DBUS_HEADER_FIELD_REPLY_AS_UINT32   \
1856993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  FOUR_CHARS_TO_UINT32 ('r', 'p', 'l', 'y')
1857993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
18584a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson/** DBUS_HEADER_FIELD_SENDER Packed into a dbus_uint32_t */
18594a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson#define DBUS_HEADER_FIELD_SENDER_AS_UINT32  \
18604a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson  FOUR_CHARS_TO_UINT32 ('s', 'n', 'd', 'r')
18614a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
18621b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssonstatic dbus_bool_t
18637ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Penningtondecode_header_data (const DBusString   *data,
18647ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington		    int		        header_len,
18657ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington		    int                 byte_order,
18667ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                    HeaderField         fields[FIELD_LAST])
18671b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
18681b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  const char *field;
18691b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  int pos, new_pos;
187050c25505f62786756519ef1e194883360eda82e0Havoc Pennington  int i;
18711b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
187250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (header_len < 16)
187350c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return FALSE;
18747ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
187550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  i = 0;
187650c25505f62786756519ef1e194883360eda82e0Havoc Pennington  while (i < FIELD_LAST)
187750c25505f62786756519ef1e194883360eda82e0Havoc Pennington    {
187850c25505f62786756519ef1e194883360eda82e0Havoc Pennington      fields[i].offset = -1;
187950c25505f62786756519ef1e194883360eda82e0Havoc Pennington      ++i;
188050c25505f62786756519ef1e194883360eda82e0Havoc Pennington    }
188150c25505f62786756519ef1e194883360eda82e0Havoc Pennington
188250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  fields[FIELD_HEADER_LENGTH].offset = 4;
188350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  fields[FIELD_BODY_LENGTH].offset = 8;
188450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  fields[FIELD_CLIENT_SERIAL].offset = 12;
188550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
18867ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  /* Now handle the named fields. A real named field is at least 4
18877ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington   * bytes for the name, plus a type code (1 byte) plus padding.  So
18887ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington   * if we have less than 8 bytes left, it must be alignment padding,
18897ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington   * not a field. While >= 8 bytes can't be entirely alignment
18907ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington   * padding.
18917ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington   */
189250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  pos = 16;
18937ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  while ((pos + 7) < header_len)
18941b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    {
1895993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington      pos = _DBUS_ALIGN_VALUE (pos, 4);
1896993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
1897993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington      if ((pos + 4) > header_len)
1898993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington        return FALSE;
1899993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
19001b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      _dbus_string_get_const_data_len (data, &field, pos, 4);
19011b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      pos += 4;
19021b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
1903993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington      _dbus_assert (_DBUS_ALIGN_ADDRESS (field, 4) == field);
1904993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
1905993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington      /* I believe FROM_BE is right, but if not we'll find out
1906993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington       * I guess. ;-)
1907993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington       */
1908993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington      switch (DBUS_UINT32_FROM_BE (*(int*)field))
1909993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington        {
1910993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington        case DBUS_HEADER_FIELD_SERVICE_AS_UINT32:
191150c25505f62786756519ef1e194883360eda82e0Havoc Pennington          if (fields[FIELD_SERVICE].offset >= 0)
1912993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington            {
1913993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington              _dbus_verbose ("%s field provided twice\n",
1914993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                             DBUS_HEADER_FIELD_SERVICE);
191550c25505f62786756519ef1e194883360eda82e0Havoc Pennington              return FALSE;
1916993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington            }
1917993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
191850c25505f62786756519ef1e194883360eda82e0Havoc Pennington          fields[FIELD_SERVICE].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
191950c25505f62786756519ef1e194883360eda82e0Havoc Pennington          _dbus_verbose ("Found service name at offset %d\n",
192050c25505f62786756519ef1e194883360eda82e0Havoc Pennington                         fields[FIELD_SERVICE].offset);
1921993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington          break;
192250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
1923993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington        case DBUS_HEADER_FIELD_NAME_AS_UINT32:
192450c25505f62786756519ef1e194883360eda82e0Havoc Pennington          if (fields[FIELD_NAME].offset >= 0)
1925993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington            {
1926993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington              _dbus_verbose ("%s field provided twice\n",
1927993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                             DBUS_HEADER_FIELD_NAME);
192850c25505f62786756519ef1e194883360eda82e0Havoc Pennington              return FALSE;
1929993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington            }
1930993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
193150c25505f62786756519ef1e194883360eda82e0Havoc Pennington          fields[FIELD_NAME].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
193250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
193350c25505f62786756519ef1e194883360eda82e0Havoc Pennington          _dbus_verbose ("Found message name at offset %d\n",
193450c25505f62786756519ef1e194883360eda82e0Havoc Pennington                         fields[FIELD_NAME].offset);
1935993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington          break;
19364a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson	case DBUS_HEADER_FIELD_SENDER_AS_UINT32:
193750c25505f62786756519ef1e194883360eda82e0Havoc Pennington          if (fields[FIELD_SENDER].offset >= 0)
193850c25505f62786756519ef1e194883360eda82e0Havoc Pennington            {
193950c25505f62786756519ef1e194883360eda82e0Havoc Pennington              _dbus_verbose ("%s field provided twice\n",
194050c25505f62786756519ef1e194883360eda82e0Havoc Pennington                             DBUS_HEADER_FIELD_SENDER);
194150c25505f62786756519ef1e194883360eda82e0Havoc Pennington              return FALSE;
194250c25505f62786756519ef1e194883360eda82e0Havoc Pennington            }
194350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
194450c25505f62786756519ef1e194883360eda82e0Havoc Pennington          fields[FIELD_SENDER].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
19454a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
194650c25505f62786756519ef1e194883360eda82e0Havoc Pennington          _dbus_verbose ("Found sender name at offset %d\n",
194750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                         fields[FIELD_NAME].offset);
19484a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson	  break;
194950c25505f62786756519ef1e194883360eda82e0Havoc Pennington
19504a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson	case DBUS_HEADER_FIELD_REPLY_AS_UINT32:
195150c25505f62786756519ef1e194883360eda82e0Havoc Pennington          if (fields[FIELD_REPLY_SERIAL].offset >= 0)
195250c25505f62786756519ef1e194883360eda82e0Havoc Pennington            {
195350c25505f62786756519ef1e194883360eda82e0Havoc Pennington              _dbus_verbose ("%s field provided twice\n",
195450c25505f62786756519ef1e194883360eda82e0Havoc Pennington                             DBUS_HEADER_FIELD_REPLY);
195550c25505f62786756519ef1e194883360eda82e0Havoc Pennington              return FALSE;
195650c25505f62786756519ef1e194883360eda82e0Havoc Pennington            }
195750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
195850c25505f62786756519ef1e194883360eda82e0Havoc Pennington          fields[FIELD_REPLY_SERIAL].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
19594a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
196050c25505f62786756519ef1e194883360eda82e0Havoc Pennington          _dbus_verbose ("Found reply serial at offset %d\n",
196150c25505f62786756519ef1e194883360eda82e0Havoc Pennington                         fields[FIELD_REPLY_SERIAL].offset);
19624a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson	  break;
196350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
1964993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington        default:
1965993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington	  _dbus_verbose ("Ignoring an unknown header field: %c%c%c%c\n",
19661b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson			 field[0], field[1], field[2], field[3]);
19671b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	}
19681b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
19697ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington      if (!_dbus_marshal_validate_arg (data, byte_order, pos, &new_pos))
197050c25505f62786756519ef1e194883360eda82e0Havoc Pennington        return FALSE;
197150c25505f62786756519ef1e194883360eda82e0Havoc Pennington
19721b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      if (new_pos > header_len)
19731b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	return FALSE;
19741b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
19751b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      pos = new_pos;
19761b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    }
19777ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
19787ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (pos < header_len)
19797ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    {
19807ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington      /* Alignment padding, verify that it's nul */
19817ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington      _dbus_assert ((header_len - pos) < 8);
19827ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
19837ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington      if (!_dbus_string_validate_nul (data,
19847ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                                      pos, (header_len - pos)))
19857ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington        {
19867ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          _dbus_verbose ("header alignment padding is not nul\n");
19877ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          return FALSE;
19887ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington        }
19897ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    }
19901b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
19911b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  return TRUE;
19921b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
19931b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
19941b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
1995041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Returns a buffer obtained from _dbus_message_loader_get_buffer(),
1996041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * indicating to the loader how many bytes of the buffer were filled
1997041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * in. This function must always be called, even if no bytes were
1998041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * successfully read.
1999041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
2000041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param loader the loader.
2001041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param buffer the buffer.
2002041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param bytes_read number of bytes that were read into the buffer.
2003041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
2004041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonvoid
2005041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
2006271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                                    DBusString         *buffer,
2007041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                                    int                 bytes_read)
2008041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
2009041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_assert (loader->buffer_outstanding);
2010271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  _dbus_assert (buffer == &loader->data);
201193f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
2012041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  loader->buffer_outstanding = FALSE;
2013041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
2014ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  if (loader->corrupted)
2015ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    return;
20161b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
20171b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  while (_dbus_string_get_length (&loader->data) >= 16)
2018041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
20191b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      DBusMessage *message;
20201b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      const char *header_data;
20211b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      int byte_order, header_len, body_len;
2022482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      dbus_uint32_t header_len_unsigned, body_len_unsigned;
2023041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
20241b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      _dbus_string_get_const_data_len (&loader->data, &header_data, 0, 16);
2025993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
2026993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington      _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
2027993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
20281b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      byte_order = header_data[0];
2029041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
20301b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      if (byte_order != DBUS_LITTLE_ENDIAN &&
20311b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	  byte_order != DBUS_BIG_ENDIAN)
20321b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	{
2033993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington          _dbus_verbose ("Message with bad byte order '%c' received\n",
2034993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington                         byte_order);
20351b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	  loader->corrupted = TRUE;
20361b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	  return;
20371b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	}
2038041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
2039482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      header_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 4);
2040482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      body_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 8);
20411b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
2042482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      if (header_len_unsigned < 16)
20437ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington        {
2044482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington          _dbus_verbose ("Message had broken too-small header length %u\n",
2045482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington                         header_len_unsigned);
20467ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          loader->corrupted = TRUE;
20477ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          return;
20487ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington        }
20497ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
2050482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      if (header_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE ||
2051482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington          body_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE)
2052482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington        {
2053482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington          _dbus_verbose ("Header or body length too large (%u %u)\n",
2054482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington                         header_len_unsigned,
2055482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington                         body_len_unsigned);
2056482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington          loader->corrupted = TRUE;
2057482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington          return;
2058482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington        }
2059482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington
2060482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      /* Now that we know the values are in signed range, get
2061482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington       * rid of stupid unsigned, just causes bugs
2062482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington       */
2063482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      header_len = header_len_unsigned;
2064482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      body_len = body_len_unsigned;
2065482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington
2066482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned)
20677ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington        {
20687ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          _dbus_verbose ("header length %d is not aligned to 8 bytes\n",
20697ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                         header_len);
20707ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          loader->corrupted = TRUE;
20717ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          return;
20727ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington        }
20737ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
2074502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington      if (header_len + body_len > loader->max_message_size)
20751b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	{
2076993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington          _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %d\n",
2077502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington                         header_len, body_len, loader->max_message_size);
20781b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	  loader->corrupted = TRUE;
20791b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	  return;
20801b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	}
20811b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
2082482dab2076282ef1195564fa60dd25c1ffb77682Havoc Pennington      if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
20831b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	{
208450c25505f62786756519ef1e194883360eda82e0Havoc Pennington          HeaderField fields[FIELD_LAST];
208550c25505f62786756519ef1e194883360eda82e0Havoc Pennington          int i;
20867ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          int next_arg;
20877ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
2088993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington 	  if (!decode_header_data (&loader->data, header_len, byte_order,
208950c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                   fields))
20901b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	    {
20911b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	      loader->corrupted = TRUE;
20921b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	      return;
20931b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	    }
20947ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
20957ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          next_arg = header_len;
20967ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          while (next_arg < (header_len + body_len))
20977ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington            {
20987ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington              int prev = next_arg;
20997ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
21007ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington              if (!_dbus_marshal_validate_arg (&loader->data,
21017ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                                               byte_order,
21027ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                                               next_arg,
21037ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                                               &next_arg))
21047ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                {
21057ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                  loader->corrupted = TRUE;
21067ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                  return;
21077ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                }
21087ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
21097ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington              _dbus_assert (next_arg > prev);
21107ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington            }
21117ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
21127ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          if (next_arg > (header_len + body_len))
21137ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington            {
21147ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington              _dbus_verbose ("end of last arg at %d but message has len %d+%d=%d\n",
21157ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                             next_arg, header_len, body_len,
21167ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                             header_len + body_len);
21177ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington              loader->corrupted = TRUE;
21187ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington              return;
21197ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington            }
21201b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
212150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  	  message = dbus_message_new_empty_header ();
21221b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	  if (message == NULL)
2123993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington            break; /* ugh, postpone this I guess. */
212450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
21257ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington          message->byte_order = byte_order;
21267ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
212750c25505f62786756519ef1e194883360eda82e0Havoc Pennington          /* Copy in the offsets we found */
212850c25505f62786756519ef1e194883360eda82e0Havoc Pennington          i = 0;
212950c25505f62786756519ef1e194883360eda82e0Havoc Pennington          while (i < FIELD_LAST)
213050c25505f62786756519ef1e194883360eda82e0Havoc Pennington            {
213150c25505f62786756519ef1e194883360eda82e0Havoc Pennington              message->header_fields[i] = fields[i];
213250c25505f62786756519ef1e194883360eda82e0Havoc Pennington              ++i;
213350c25505f62786756519ef1e194883360eda82e0Havoc Pennington            }
213450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
2135502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington	  if (!_dbus_list_append (&loader->messages, message))
2136502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington            {
2137502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington              dbus_message_unref (message);
2138502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington              break;
2139502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington            }
21401b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
2141502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington          _dbus_assert (_dbus_string_get_length (&message->header) == 0);
2142502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington          _dbus_assert (_dbus_string_get_length (&message->body) == 0);
21434a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
214450c25505f62786756519ef1e194883360eda82e0Havoc Pennington          _dbus_assert (_dbus_string_get_length (&loader->data) >=
214550c25505f62786756519ef1e194883360eda82e0Havoc Pennington                        (header_len + body_len));
214650c25505f62786756519ef1e194883360eda82e0Havoc Pennington
214750c25505f62786756519ef1e194883360eda82e0Havoc Pennington	  if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0))
214850c25505f62786756519ef1e194883360eda82e0Havoc Pennington            {
214950c25505f62786756519ef1e194883360eda82e0Havoc Pennington              _dbus_list_remove_last (&loader->messages, message);
215050c25505f62786756519ef1e194883360eda82e0Havoc Pennington              dbus_message_unref (message);
215150c25505f62786756519ef1e194883360eda82e0Havoc Pennington              break;
215250c25505f62786756519ef1e194883360eda82e0Havoc Pennington            }
215350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
2154502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington	  if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0))
2155502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington            {
2156502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington              dbus_bool_t result;
2157502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
2158502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington              /* put the header back, we'll try again later */
2159502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington              result = _dbus_string_copy_len (&message->header, 0, header_len,
2160502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington                                              &loader->data, 0);
2161502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington              _dbus_assert (result); /* because DBusString never reallocs smaller */
21621b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
2163502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington              _dbus_list_remove_last (&loader->messages, message);
2164502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington              dbus_message_unref (message);
2165502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington              break;
2166502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington            }
2167502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
216850c25505f62786756519ef1e194883360eda82e0Havoc Pennington          _dbus_assert (_dbus_string_get_length (&message->header) == header_len);
2169502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington          _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
217042788678e83ec1d82f048f86aff04017b58f072eAnders Carlsson
217150c25505f62786756519ef1e194883360eda82e0Havoc Pennington	  _dbus_verbose ("Loaded message %p\n", message);
21721b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	}
21731b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      else
21741b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson	break;
2175041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
2176041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
2177041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
2178041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
2179041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Pops a loaded message (passing ownership of the message
2180041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * to the caller). Returns #NULL if no messages have been
2181041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * loaded.
2182041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
2183041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param loader the loader.
2184041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @returns the next message, or #NULL if none.
2185041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
2186041b0767b284034aee09e9a0de2a3844b8cc546aHavoc PenningtonDBusMessage*
2187041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_pop_message (DBusMessageLoader *loader)
2188041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
2189041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  return _dbus_list_pop_first (&loader->messages);
219093f222c1d8ed748994f74662671d003495b16d43Havoc Pennington}
219193f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
2192ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2193ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington/**
2194ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * Checks whether the loader is confused due to bad data.
2195ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * If messages are received that are invalid, the
2196ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * loader gets confused and gives up permanently.
2197ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * This state is called "corrupted."
2198ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington *
2199ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @param loader the loader
2200ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @returns #TRUE if the loader is hosed.
2201ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington */
2202ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Penningtondbus_bool_t
2203ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington_dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
2204ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington{
2205ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  return loader->corrupted;
2206ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington}
2207ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2208502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington/**
2209502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * Sets the maximum size message we allow.
2210502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington *
2211502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * @param loader the loader
2212502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * @param size the max message size in bytes
2213502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington */
2214502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Penningtonvoid
2215502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington_dbus_message_loader_set_max_message_size (DBusMessageLoader  *loader,
2216502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington                                           long                size)
2217502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington{
22187ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  if (size > MAX_SANE_MESSAGE_SIZE)
22197ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    {
22207ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington      _dbus_verbose ("clamping requested max message size %ld to %d\n",
22217ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                     size, MAX_SANE_MESSAGE_SIZE);
22227ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington      size = MAX_SANE_MESSAGE_SIZE;
22237ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    }
2224502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  loader->max_message_size = size;
2225502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington}
2226502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
2227502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington/**
2228502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * Gets the maximum allowed message size in bytes.
2229502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington *
2230502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * @param loader the loader
2231502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington * @returns max size in bytes
2232502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington */
2233502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Penningtonlong
2234502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington_dbus_message_loader_get_max_message_size (DBusMessageLoader  *loader)
2235502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington{
2236502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington  return loader->max_message_size;
2237502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington}
2238502fbda2201a4e7e50d687f42af29c82e66299bbHavoc Pennington
223993f222c1d8ed748994f74662671d003495b16d43Havoc Pennington/** @} */
22401b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson#ifdef DBUS_BUILD_TESTS
22411b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson#include "dbus-test.h"
22421b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson#include <stdio.h>
22431b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22441b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssonstatic void
22451b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssonmessage_iter_test (DBusMessage *message)
22461b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
22471b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  DBusMessageIter *iter;
22481b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  char *str;
22491b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22501b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  iter = dbus_message_get_fields_iter (message);
22511b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22521b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  /* String tests */
22531b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_STRING)
22541b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Field type isn't string");
22551b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22561b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  str = dbus_message_iter_get_string (iter);
22571b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (strcmp (str, "Test string") != 0)
22581b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Strings differ");
22591b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  dbus_free (str);
22601b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22611b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (!dbus_message_iter_next (iter))
22621b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Reached end of fields");
22631b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22641b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  /* Signed integer tests */
22651b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_INT32)
22661b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Field type isn't int32");
22671b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22681b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (dbus_message_iter_get_int32 (iter) != -0x12345678)
22691b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Signed integers differ");
22701b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22711b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (!dbus_message_iter_next (iter))
22721b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Reached end of fields");
22731b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22741b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  /* Unsigned integer tests */
22751b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_UINT32)
22761b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Field type isn't int32");
22771b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22781b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (dbus_message_iter_get_int32 (iter) != 0xedd1e)
22791b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Unsigned integers differ");
22801b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22811b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (!dbus_message_iter_next (iter))
22821b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Reached end of fields");
22831b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22841b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  /* Double tests */
22851b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_DOUBLE)
22861b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Field type isn't double");
22871b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22881b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (dbus_message_iter_get_double (iter) != 3.14159)
22891b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Doubles differ");
22901b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22911b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (dbus_message_iter_next (iter))
22921b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("Didn't reach end of fields");
22931b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
22941b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  dbus_message_iter_unref (iter);
22951b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
22961b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
229705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtonstatic dbus_bool_t
2298bec3c093cab742a953e39f1726c37345873990dcHavoc Penningtoncheck_message_handling (DBusMessage *message)
2299bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington{
2300bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  DBusMessageIter *iter;
2301bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  int type;
2302bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  dbus_bool_t retval;
2303bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  dbus_int32_t client_serial;
2304bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington
2305bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  retval = FALSE;
2306bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  iter = NULL;
2307bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington
2308bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  client_serial = _dbus_message_get_client_serial (message);
23098fdd8915bd7424cdf90bf59a018838a1290ac0c4Havoc Pennington
23108fdd8915bd7424cdf90bf59a018838a1290ac0c4Havoc Pennington  /* can't use set_client_serial due to the assertions at the start of it */
23118fdd8915bd7424cdf90bf59a018838a1290ac0c4Havoc Pennington  set_int_field (message, FIELD_CLIENT_SERIAL,
23128fdd8915bd7424cdf90bf59a018838a1290ac0c4Havoc Pennington                 client_serial);
2313bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington
2314bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  if (client_serial != _dbus_message_get_client_serial (message))
2315bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington    {
2316bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington      _dbus_warn ("get/set cycle for client_serial did not succeed\n");
2317bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington      goto failed;
2318bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington    }
2319bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington
2320bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  /* If we implement message_set_field (message, n, value)
2321bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington   * then we would want to test it here
2322bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington   */
2323bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington
2324bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  iter = dbus_message_get_fields_iter (message);
2325bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  while ((type = dbus_message_iter_get_field_type (iter)) != DBUS_TYPE_INVALID)
2326bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington    {
2327bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington      switch (type)
2328bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington        {
2329bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington        case DBUS_TYPE_STRING:
2330bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington          {
2331bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington            char *str;
2332bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington            str = dbus_message_iter_get_string (iter);
2333bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington            dbus_free (str);
2334bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington          }
2335bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington          break;
2336bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington        }
2337bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington
2338bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington      if (!dbus_message_iter_next (iter))
2339bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington        break;
2340bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington    }
2341bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington
2342bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  retval = TRUE;
2343bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington
2344bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington failed:
2345bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  if (iter)
2346bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington    dbus_message_iter_unref (iter);
2347bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington
2348bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  return retval;
2349bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington}
2350bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington
2351bec3c093cab742a953e39f1726c37345873990dcHavoc Penningtonstatic dbus_bool_t
235205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtoncheck_have_valid_message (DBusMessageLoader *loader)
235305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington{
235405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusMessage *message;
235505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  dbus_bool_t retval;
235605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
235705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  message = NULL;
235805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = FALSE;
235905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
236005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (_dbus_message_loader_get_is_corrupted (loader))
236105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
236205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_warn ("loader corrupted on message that was expected to be valid\n");
236305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      goto failed;
236405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
236505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
236605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  message = _dbus_message_loader_pop_message (loader);
236705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (message == NULL)
236805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
236905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n");
237005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      goto failed;
237105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
237205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
237305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (_dbus_string_get_length (&loader->data) > 0)
237405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
237505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n");
237605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      goto failed;
237705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
237805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
2379bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  /* Verify that we're able to properly deal with the message.
2380bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington   * For example, this would detect improper handling of messages
2381bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington   * in nonstandard byte order.
2382bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington   */
2383bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington  if (!check_message_handling (message))
2384bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington    goto failed;
2385bec3c093cab742a953e39f1726c37345873990dcHavoc Pennington
238605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = TRUE;
238705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
238805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington failed:
238905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (message)
239005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    dbus_message_unref (message);
239105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  return retval;
239205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington}
239305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
239405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtonstatic dbus_bool_t
239505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtoncheck_invalid_message (DBusMessageLoader *loader)
239605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington{
239705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  dbus_bool_t retval;
239805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
239905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = FALSE;
240005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
240105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!_dbus_message_loader_get_is_corrupted (loader))
240205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
240305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_warn ("loader not corrupted on message that was expected to be invalid\n");
240405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      goto failed;
240505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
240605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
240705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = TRUE;
240805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
240905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington failed:
241005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  return retval;
241105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington}
241205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
241305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtonstatic dbus_bool_t
241405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtoncheck_incomplete_message (DBusMessageLoader *loader)
241505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington{
241605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusMessage *message;
241705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  dbus_bool_t retval;
241805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
241905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  message = NULL;
242005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = FALSE;
242105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
242205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (_dbus_message_loader_get_is_corrupted (loader))
242305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
242405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete)\n");
242505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      goto failed;
242605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
242705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
242805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  message = _dbus_message_loader_pop_message (loader);
242905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (message != NULL)
243005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
243105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_warn ("loaded message that was expected to be incomplete\n");
243205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      goto failed;
243305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
243405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
243505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = TRUE;
243605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
243705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington failed:
243805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (message)
243905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    dbus_message_unref (message);
244005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  return retval;
244105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington}
244205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
244305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtontypedef enum
244405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington{
244505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  MESSAGE_VALID,
244605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  MESSAGE_INVALID,
244705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  MESSAGE_INCOMPLETE
244805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington} ExpectedMessageValidity;
244905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
245005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtonstatic dbus_bool_t
245105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtoncheck_loader_results (DBusMessageLoader      *loader,
245205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                      ExpectedMessageValidity validity)
245305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington{
245405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  switch (validity)
245505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
245605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    case MESSAGE_VALID:
245705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      return check_have_valid_message (loader);
245805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    case MESSAGE_INVALID:
245905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      return check_invalid_message (loader);
246005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    case MESSAGE_INCOMPLETE:
246105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      return check_incomplete_message (loader);
246205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
246305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
246405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_assert_not_reached ("bad ExpectedMessageValidity");
246505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  return FALSE;
246605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington}
246705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
246805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtonstatic dbus_bool_t
246905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtontry_message (const DBusString       *filename,
247005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington             ExpectedMessageValidity validity)
247105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington{
247205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusString data;
247305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusMessageLoader *loader;
247405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  dbus_bool_t retval;
247505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  int len;
247605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  int i;
247705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  const char *filename_c;
247805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
247905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_string_get_const_data (filename, &filename_c);
248005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
248105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!_dbus_string_ends_with_c_str (filename, ".message"))
248205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
248305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_verbose ("Skipping non-.message file %s\n",
248405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                     filename_c);
248505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      return TRUE;
248605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
248705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
248805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  {
248905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    const char *s;
249005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    _dbus_string_get_const_data (filename, &s);
249105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    printf ("    %s\n", s);
249205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  }
249305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
249405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_verbose (" expecting %s\n",
249505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                 validity == MESSAGE_VALID ? "valid" :
249605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                 (validity == MESSAGE_INVALID ? "invalid" : "incomplete"));
249705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
249805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  loader = NULL;
249905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = FALSE;
250005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
250105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!_dbus_string_init (&data, _DBUS_INT_MAX))
250205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    _dbus_assert_not_reached ("could not allocate string\n");
250305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
250405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!_dbus_message_data_load (&data, filename))
250505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
250605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      const char *s;
250705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_string_get_const_data (filename, &s);
250805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_warn ("Could not load message file %s\n", s);
250905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      goto failed;
251005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
251105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
251205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  /* Write the data one byte at a time */
251305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
251405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  loader = _dbus_message_loader_new ();
251505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
251605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  len = _dbus_string_get_length (&data);
251705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  for (i = 0; i < len; i++)
251805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
251905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      DBusString *buffer;
252005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
252105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_message_loader_get_buffer (loader, &buffer);
252205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_string_append_byte (buffer,
252305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                                _dbus_string_get_byte (&data, i));
252405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_message_loader_return_buffer (loader, buffer, 1);
252505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
252605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
252705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!check_loader_results (loader, validity))
252805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    goto failed;
252905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
253005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_message_loader_unref (loader);
253105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  loader = NULL;
253205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
253305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  /* Write the data all at once */
253405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
253505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  loader = _dbus_message_loader_new ();
253605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
253705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  {
253805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    DBusString *buffer;
253905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
254005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    _dbus_message_loader_get_buffer (loader, &buffer);
254105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    _dbus_string_copy (&data, 0, buffer,
254205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                       _dbus_string_get_length (buffer));
254305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    _dbus_message_loader_return_buffer (loader, buffer, 1);
254405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  }
254505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
254605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!check_loader_results (loader, validity))
254705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    goto failed;
254805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
254905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_message_loader_unref (loader);
255005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  loader = NULL;
255105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
255205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  /* Write the data 2 bytes at a time */
255305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
255405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  loader = _dbus_message_loader_new ();
255505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
255605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  len = _dbus_string_get_length (&data);
255705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  for (i = 0; i < len; i += 2)
255805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
255905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      DBusString *buffer;
256005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
256105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_message_loader_get_buffer (loader, &buffer);
256205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_string_append_byte (buffer,
256305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                                _dbus_string_get_byte (&data, i));
256405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      if ((i+1) < len)
256505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington        _dbus_string_append_byte (buffer,
256605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                                  _dbus_string_get_byte (&data, i+1));
256705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_message_loader_return_buffer (loader, buffer, 1);
256805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
256905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
257005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!check_loader_results (loader, validity))
257105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    goto failed;
257205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
257305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_message_loader_unref (loader);
257405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  loader = NULL;
257505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
257605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = TRUE;
257705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
257805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington failed:
257905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!retval)
258005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
258105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      const char *s;
258205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
258305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      if (_dbus_string_get_length (&data) > 0)
258405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington        _dbus_verbose_bytes_of_string (&data, 0,
258505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                                       _dbus_string_get_length (&data));
258605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
258705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_string_get_const_data (filename, &s);
258805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_warn ("Failed message loader test on %s\n",
258905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                  s);
259005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
259105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
259205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (loader)
259305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    _dbus_message_loader_unref (loader);
259405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_string_free (&data);
259505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
259605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  return retval;
259705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington}
259805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
259905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtonstatic dbus_bool_t
260005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtonprocess_test_subdir (const DBusString       *test_base_dir,
260105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                     const char             *subdir,
260205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                     ExpectedMessageValidity validity)
260305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington{
260405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusString test_directory;
260505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusString filename;
260605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusDirIter *dir;
260705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  dbus_bool_t retval;
260805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusResultCode result;
260905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
261005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = FALSE;
261105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  dir = NULL;
261205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
261305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!_dbus_string_init (&test_directory, _DBUS_INT_MAX))
261405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    _dbus_assert_not_reached ("didn't allocate test_directory\n");
261505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
261605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_string_init_const (&filename, subdir);
261705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
261805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!_dbus_string_copy (test_base_dir, 0,
261905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                          &test_directory, 0))
262005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
262105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
262205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!_dbus_concat_dir_and_file (&test_directory, &filename))
262305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    _dbus_assert_not_reached ("could't allocate full path");
262405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
262505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_string_free (&filename);
262605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!_dbus_string_init (&filename, _DBUS_INT_MAX))
262705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    _dbus_assert_not_reached ("didn't allocate filename string\n");
262805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
262905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  dir = _dbus_directory_open (&test_directory, &result);
263005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (dir == NULL)
263105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
263205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      const char *s;
263305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_string_get_const_data (&test_directory, &s);
263405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_warn ("Could not open %s: %s\n", s,
263505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                  dbus_result_to_string (result));
263605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      goto failed;
263705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
263805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
263905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  printf ("Testing:\n");
264005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
264105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  result = DBUS_RESULT_SUCCESS;
264205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  while (_dbus_directory_get_next_file (dir, &filename, &result))
264305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
264405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      DBusString full_path;
264505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
264605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      if (!_dbus_string_init (&full_path, _DBUS_INT_MAX))
264705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington        _dbus_assert_not_reached ("couldn't init string");
264805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
264905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
265005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington        _dbus_assert_not_reached ("couldn't copy dir to full_path");
265105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
265205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      if (!_dbus_concat_dir_and_file (&full_path, &filename))
265305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington        _dbus_assert_not_reached ("couldn't concat file to dir");
265405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
265505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      if (!try_message (&full_path, validity))
265605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington        {
265705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington          _dbus_string_free (&full_path);
265805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington          goto failed;
265905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington        }
266005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      else
266105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington        _dbus_string_free (&full_path);
266205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
266305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
266405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (result != DBUS_RESULT_SUCCESS)
266505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
266605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      const char *s;
266705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_string_get_const_data (&test_directory, &s);
266805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      _dbus_warn ("Could not get next file in %s: %s\n",
266905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                  s, dbus_result_to_string (result));
267005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      goto failed;
267105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
267205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
267305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = TRUE;
267405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
267505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington failed:
267605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
267705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (dir)
267805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    _dbus_directory_close (dir);
267905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_string_free (&test_directory);
268005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_string_free (&filename);
268105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
268205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  return retval;
268305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington}
268405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
268505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
26861b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson/**
26871b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @ingroup DBusMessageInternals
26881b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * Unit test for DBusMessage.
26891b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson *
26901b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson * @returns #TRUE on success.
26911b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson */
26921b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlssondbus_bool_t
269305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington_dbus_message_test (const char *test_data_dir)
26941b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson{
26951b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  DBusMessage *message;
26961b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  DBusMessageLoader *loader;
26971b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  int i;
26981b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  const char *data;
26991f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  dbus_int32_t our_int;
27001f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  char *our_str;
27011f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  double our_double;
270205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusString test_directory;
270305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  dbus_bool_t retval;
27041f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
27051f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  /* Test the vararg functions */
27061f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage");
270750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_message_set_client_serial (message, 1);
27081f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  dbus_message_append_fields (message,
27091f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson			      DBUS_TYPE_INT32, -0x12345678,
27101f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson			      DBUS_TYPE_STRING, "Test string",
27111f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson			      DBUS_TYPE_DOUBLE, 3.14159,
27121f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson			      0);
271350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_verbose_bytes_of_string (&message->header, 0,
271450c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                 _dbus_string_get_length (&message->header));
271550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_verbose_bytes_of_string (&message->body, 0,
271650c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                 _dbus_string_get_length (&message->body));
271750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
27181b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson  if (dbus_message_get_fields (message,
27191b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson			       DBUS_TYPE_INT32, &our_int,
27201b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson			       DBUS_TYPE_STRING, &our_str,
27211b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson			       DBUS_TYPE_DOUBLE, &our_double,
27221b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson			       0) != DBUS_RESULT_SUCCESS)
27231f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson    _dbus_assert_not_reached ("Could not get fields");
27241f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
27251f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  if (our_int != -0x12345678)
27261f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson    _dbus_assert_not_reached ("integers differ!");
27271f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
27281f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  if (our_double != 3.14159)
27291f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson    _dbus_assert_not_reached ("doubles differ!");
27301f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
27311f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson  if (strcmp (our_str, "Test string") != 0)
27321f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson    _dbus_assert_not_reached ("strings differ!");
273342788678e83ec1d82f048f86aff04017b58f072eAnders Carlsson
273442788678e83ec1d82f048f86aff04017b58f072eAnders Carlsson  dbus_free (our_str);
273542788678e83ec1d82f048f86aff04017b58f072eAnders Carlsson  dbus_message_unref (message);
27361f23ea99b37bfc8197f1c6a376f9afe08037f0f6Anders Carlsson
27371b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage");
273850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_message_set_client_serial (message, 1);
273950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_message_set_reply_serial (message, 0x12345678);
27404a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
27411b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  dbus_message_append_string (message, "Test string");
27421b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  dbus_message_append_int32 (message, -0x12345678);
27431b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  dbus_message_append_uint32 (message, 0xedd1e);
27441b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  dbus_message_append_double (message, 3.14159);
27451b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
27461b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  message_iter_test (message);
27471b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
27481b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  /* Message loader test */
27491b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  _dbus_message_lock (message);
27501b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  loader = _dbus_message_loader_new ();
27511b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
27521b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  /* Write the header data one byte at a time */
27531b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  _dbus_string_get_const_data (&message->header, &data);
27541b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  for (i = 0; i < _dbus_string_get_length (&message->header); i++)
27551b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    {
27561b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      DBusString *buffer;
27571b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
27581b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      _dbus_message_loader_get_buffer (loader, &buffer);
27591b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      _dbus_string_append_byte (buffer, data[i]);
27601b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      _dbus_message_loader_return_buffer (loader, buffer, 1);
27611b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    }
27621b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
27631b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  /* Write the body data one byte at a time */
27641b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  _dbus_string_get_const_data (&message->body, &data);
27651b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  for (i = 0; i < _dbus_string_get_length (&message->body); i++)
27661b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    {
27671b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      DBusString *buffer;
27681b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
27691b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      _dbus_message_loader_get_buffer (loader, &buffer);
27701b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      _dbus_string_append_byte (buffer, data[i]);
27711b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson      _dbus_message_loader_return_buffer (loader, buffer, 1);
27721b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    }
27731b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
27741b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  dbus_message_unref (message);
27751b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
27761b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  /* Now pop back the message */
27771b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (_dbus_message_loader_get_is_corrupted (loader))
27781b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("message loader corrupted");
27791b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
27801b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  message = _dbus_message_loader_pop_message (loader);
27811b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  if (!message)
27821b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson    _dbus_assert_not_reached ("received a NULL message");
27831b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
278450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (_dbus_message_get_reply_serial (message) != 0x12345678)
27854a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson    _dbus_assert_not_reached ("reply serial fields differ");
27864a85d321b4516c6a663e8bdd530ba59018c974dfAnders Carlsson
27871b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  message_iter_test (message);
27881b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
27891b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  dbus_message_unref (message);
27901b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson  _dbus_message_loader_unref (loader);
27911b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
279205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  /* Now load every message in test_data_dir if we have one */
279305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (test_data_dir == NULL)
279405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    return TRUE;
279505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
279605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = FALSE;
279705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
279805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_string_init_const (&test_directory, test_data_dir);
279905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
280005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!process_test_subdir (&test_directory, "valid-messages",
280105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                            MESSAGE_VALID))
280205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    goto failed;
280305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!process_test_subdir (&test_directory, "invalid-messages",
280405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                            MESSAGE_INVALID))
280505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    goto failed;
280605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
280705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  if (!process_test_subdir (&test_directory, "incomplete-messages",
280805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                            MESSAGE_INCOMPLETE))
280905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    goto failed;
281005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
281105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  retval = TRUE;
281205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
281305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington failed:
281405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
281505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_string_free (&test_directory);
281605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
281705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  return retval;
28181b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson}
28191b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson
28201b53cbcce333381754b0568b740ece550a8f6ac9Anders Carlsson#endif /* DBUS_BUILD_TESTS */
2821