dbus-message.c revision 17fbe2b702cdc880abd6cbe117e620b6432f42e0
15a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington/* -*- mode: C; c-file-style: "gnu" -*- */
25a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington/* dbus-message.c  DBusMessage object
35a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
45a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * Copyright (C) 2002  Red Hat Inc.
55a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
65a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * Licensed under the Academic Free License version 1.2
75a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
85a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * This program is free software; you can redistribute it and/or modify
95a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * it under the terms of the GNU General Public License as published by
105a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * the Free Software Foundation; either version 2 of the License, or
115a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * (at your option) any later version.
125a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
135a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * This program is distributed in the hope that it will be useful,
145a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * but WITHOUT ANY WARRANTY; without even the implied warranty of
155a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
165a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * GNU General Public License for more details.
175a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
185a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * You should have received a copy of the GNU General Public License
195a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * along with this program; if not, write to the Free Software
205a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
215a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington *
225a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington */
235a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington
24041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-internals.h"
255a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington#include "dbus-message.h"
26041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-message-internal.h"
27041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-memory.h"
28041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-list.h"
29041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include <string.h>
305a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington
3193f222c1d8ed748994f74662671d003495b16d43Havoc Pennington/**
3255de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @defgroup DBusMessageInternals DBusMessage implementation details
3355de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @ingroup DBusInternals
3455de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @brief DBusMessage private implementation details.
3593f222c1d8ed748994f74662671d003495b16d43Havoc Pennington *
3655de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * The guts of DBusMessage and its methods.
3793f222c1d8ed748994f74662671d003495b16d43Havoc Pennington *
3893f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * @{
3993f222c1d8ed748994f74662671d003495b16d43Havoc Pennington */
4093f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
411428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
42271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington * The largest-length message we allow
43271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington *
44271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington * @todo match this up with whatever the protocol spec says.
45271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington */
46271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington#define _DBUS_MAX_MESSAGE_LENGTH (_DBUS_INT_MAX/16)
47271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
48271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington/**
49f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington * @brief Internals of DBusMessage
50f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington *
511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Object representing a message received from or to be sent to
5255de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * another application. This is an opaque object, all members
5355de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * are private.
541428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
555a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Penningtonstruct DBusMessage
565a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington{
571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int refcount; /**< Reference count */
58041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
59271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  DBusString header; /**< Header network data, stored
60271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                      * separately from body so we can
61271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                      * independently realloc it.
62271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                      */
63041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
64271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  DBusString body;   /**< Body network data. */
65041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
66041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
675a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington};
685a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington
69041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
70041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Gets the data to be sent over the network for this message.
71041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * The header and then the body should be written out.
72041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * This function is guaranteed to always return the same
73041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * data once a message is locked (with _dbus_message_lock()).
74041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
75041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param message the message.
76041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param header return location for message header data.
77041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param body return location for message body data.
78041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
79041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonvoid
80041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_get_network_data (DBusMessage          *message,
81271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                                const DBusString    **header,
82271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                                const DBusString    **body)
83041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
84041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_assert (message->locked);
85041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
86271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  *header = &message->header;
87271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  *body = &message->body;
88041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
89041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
90041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
91041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Locks a message. Allows checking that applications don't keep a
92041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * reference to a message in the outgoing queue and change it
93041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * underneath us. Messages are locked when they enter the outgoing
94041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * queue (dbus_connection_send_message()), and the library complains
95041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * if the message is modified while locked.
96041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
97041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param message the message to lock.
98041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
99041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonvoid
100041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_lock (DBusMessage *message)
101041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
102041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  message->locked = TRUE;
103041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
104041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
10555de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington/** @} */
10655de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington
10755de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington/**
10855de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @defgroup DBusMessage DBusMessage
10955de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @ingroup  DBus
110041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @brief Message to be sent or received over a DBusConnection.
11155de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington *
112041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * A DBusMessage is the most basic unit of communication over a
113041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * DBusConnection. A DBusConnection represents a stream of messages
114041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * received from a remote application, and a stream of messages
115041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * sent to a remote application.
11655de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington *
11755de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @{
11855de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington */
11955de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington
12055de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington/**
12155de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * @typedef DBusMessage
12255de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington *
12355de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * Opaque data type representing a message received from or to be
12455de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington * sent to another application.
12555de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington */
12655de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington
12793f222c1d8ed748994f74662671d003495b16d43Havoc Pennington/**
128041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Constructs a new message. Returns #NULL if memory
129041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * can't be allocated for the message.
130041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
13193f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * @return a new DBusMessage, free with dbus_message_unref()
13293f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * @see dbus_message_unref()
13393f222c1d8ed748994f74662671d003495b16d43Havoc Pennington */
1345a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc PenningtonDBusMessage*
1355a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Penningtondbus_message_new (void)
1365a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington{
137041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusMessage *message;
138041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
139041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  message = dbus_new0 (DBusMessage, 1);
140041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (message == NULL)
141041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    return NULL;
1425a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington
143041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  message->refcount = 1;
144041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
145271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  if (!_dbus_string_init (&message->header, _DBUS_MAX_MESSAGE_LENGTH))
146271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington    {
147271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      dbus_free (message);
148271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      return NULL;
149271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington    }
150271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
151271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  if (!_dbus_string_init (&message->body, _DBUS_MAX_MESSAGE_LENGTH))
152271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington    {
153271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      _dbus_string_free (&message->header);
154271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      dbus_free (message);
155271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      return NULL;
156271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington    }
157271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
158041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  /* We need to decide what a message contains. ;-) */
159271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  /* (not bothering to check failure of these appends) */
160271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  _dbus_string_append (&message->header, "H");
161271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  _dbus_string_append_byte (&message->header, '\0');
162271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  _dbus_string_append (&message->body, "Body");
163271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  _dbus_string_append_byte (&message->body, '\0');
164041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
165041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  return message;
1665a6adeee6e20252f8f2b01349b7e95ee6e99e4ffHavoc Pennington}
16793f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
16893f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
16993f222c1d8ed748994f74662671d003495b16d43Havoc Pennington/**
17093f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * Increments the reference count of a DBusMessage.
17193f222c1d8ed748994f74662671d003495b16d43Havoc Pennington *
1728164139fa6259257817898b3d389d96bd60f8c13Havoc Pennington * @param message The message
17393f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * @see dbus_message_unref
17493f222c1d8ed748994f74662671d003495b16d43Havoc Pennington */
17593f222c1d8ed748994f74662671d003495b16d43Havoc Penningtonvoid
17693f222c1d8ed748994f74662671d003495b16d43Havoc Penningtondbus_message_ref (DBusMessage *message)
17793f222c1d8ed748994f74662671d003495b16d43Havoc Pennington{
178041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  message->refcount += 1;
17993f222c1d8ed748994f74662671d003495b16d43Havoc Pennington}
18093f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
18193f222c1d8ed748994f74662671d003495b16d43Havoc Pennington/**
18293f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * Decrements the reference count of a DBusMessage.
18393f222c1d8ed748994f74662671d003495b16d43Havoc Pennington *
1848164139fa6259257817898b3d389d96bd60f8c13Havoc Pennington * @param message The message
18593f222c1d8ed748994f74662671d003495b16d43Havoc Pennington * @see dbus_message_ref
18693f222c1d8ed748994f74662671d003495b16d43Havoc Pennington */
18793f222c1d8ed748994f74662671d003495b16d43Havoc Penningtonvoid
18893f222c1d8ed748994f74662671d003495b16d43Havoc Penningtondbus_message_unref (DBusMessage *message)
18993f222c1d8ed748994f74662671d003495b16d43Havoc Pennington{
190041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_assert (message != NULL);
191041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_assert (message->refcount > 0);
192041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
193041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  message->refcount -= 1;
194041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (message->refcount == 0)
195041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
196271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      _dbus_string_free (&message->header);
197271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      _dbus_string_free (&message->body);
198041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
199041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      dbus_free (message);
200041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
201041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
202041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
20317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington/**
20417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * Gets the name of a message.
20517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * @param message the message
20617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * @returns the message name (should not be freed)
20717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington */
20817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Penningtonconst char*
20917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Penningtondbus_message_get_name (DBusMessage *message)
21017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington{
21117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  /* FIXME */
21217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
21317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  return NULL;
21417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington}
21517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
216041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/** @} */
217041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
218041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
219041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @addtogroup DBusMessageInternals
220041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
221041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @{
222041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
223041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
224041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @typedef DBusMessageLoader
225041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
226041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * The DBusMessageLoader object encapsulates the process of converting
227041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * a byte stream into a series of DBusMessage. It buffers the incoming
228041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * bytes as efficiently as possible, and generates a queue of
229041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * messages. DBusMessageLoader is typically used as part of a
230041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * DBusTransport implementation. The DBusTransport then hands off
231041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * the loaded messages to a DBusConnection, making the messages
232041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * visible to the application.
233041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
234041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
235041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
236041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
237041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Implementation details of DBusMessageLoader.
238041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * All members are private.
239041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
240041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonstruct DBusMessageLoader
241041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
242041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  int refcount;        /**< Reference count. */
243041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
244271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  DBusString data;     /**< Buffered data */
245271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
246041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusList *messages;  /**< Complete messages. */
247041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
248041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  unsigned int buffer_outstanding : 1; /**< Someone is using the buffer to read */
249041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington};
250041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
251041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
252041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * The initial buffer size of the message loader.
253041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
254041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @todo this should be based on min header size plus some average
255041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * body size, or something. Or rather, the min header size only, if we
256041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * want to try to read only the header, store that in a DBusMessage,
257041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * then read only the body and store that, etc., depends on
258041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * how we optimize _dbus_message_loader_get_buffer() and what
259041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * the exact message format is.
260041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
261041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#define INITIAL_LOADER_DATA_LEN 32
262041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
263041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
264041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Creates a new message loader. Returns #NULL if memory can't
265041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * be allocated.
266041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
267041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @returns new loader, or #NULL.
268041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
269041b0767b284034aee09e9a0de2a3844b8cc546aHavoc PenningtonDBusMessageLoader*
270041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_new (void)
271041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
272041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusMessageLoader *loader;
273041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
274041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  loader = dbus_new0 (DBusMessageLoader, 1);
275041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (loader == NULL)
276041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    return NULL;
277041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
278041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  loader->refcount = 1;
279271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
280271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  if (!_dbus_string_init (&loader->data, _DBUS_INT_MAX))
281271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington    {
282271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      dbus_free (loader);
283271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      return NULL;
284271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington    }
285271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
286271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  /* preallocate the buffer for speed, ignore failure */
287271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  (void) _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
288041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
289041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  return loader;
290041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
291041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
292041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
293041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Increments the reference count of the loader.
294041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
295041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param loader the loader.
296041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
297041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonvoid
298041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_ref (DBusMessageLoader *loader)
299041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
300041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  loader->refcount += 1;
301041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
302041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
303041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
304041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Decrements the reference count of the loader and finalizes the
305041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * loader when the count reaches zero.
306041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
307041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param loader the loader.
308041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
309041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonvoid
310041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_unref (DBusMessageLoader *loader)
311041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
312041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  loader->refcount -= 1;
313041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (loader->refcount == 0)
314041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
315041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_list_foreach (&loader->messages,
316041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                          (DBusForeachFunction) dbus_message_unref,
317041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                          NULL);
318041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_list_clear (&loader->messages);
319271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      _dbus_string_free (&loader->data);
320041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      dbus_free (loader);
321041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
322041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
323041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
324041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
325041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Gets the buffer to use for reading data from the network.  Network
326041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * data is read directly into an allocated buffer, which is then used
327041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * in the DBusMessage, to avoid as many extra memcpy's as possible.
328041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * The buffer must always be returned immediately using
329041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * _dbus_message_loader_return_buffer(), even if no bytes are
330041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * successfully read.
331041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
332041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @todo this function can be a lot more clever. For example
333041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * it can probably always return a buffer size to read exactly
334041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * the body of the next message, thus avoiding any memory wastage
335041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * or reallocs.
336041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
337041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param loader the message loader.
338271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington * @param buffer the buffer
339041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
340271fa7fc335f332bb2be3beeef735334546c4957Havoc Penningtonvoid
341041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_get_buffer (DBusMessageLoader  *loader,
342271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                                 DBusString        **buffer)
343041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
344041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_assert (!loader->buffer_outstanding);
345041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
346271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  *buffer = &loader->data;
347041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
348041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  loader->buffer_outstanding = TRUE;
349041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
350041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
351041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
352041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Returns a buffer obtained from _dbus_message_loader_get_buffer(),
353041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * indicating to the loader how many bytes of the buffer were filled
354041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * in. This function must always be called, even if no bytes were
355041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * successfully read.
356041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
357041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param loader the loader.
358041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param buffer the buffer.
359041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param bytes_read number of bytes that were read into the buffer.
360041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
361041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonvoid
362041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
363271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                                    DBusString         *buffer,
364041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                                    int                 bytes_read)
365041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
366041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_assert (loader->buffer_outstanding);
367271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  _dbus_assert (buffer == &loader->data);
36893f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
369041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  /* FIXME fake implementation just creates a message for every 7
370041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington   * bytes. The real implementation will pass ownership of
371271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington   * loader->data bytes to new messages, to avoid memcpy.  We can also
372041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington   * smart-realloc loader->data to shrink it if it's too big, though
373041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington   * _dbus_message_loader_get_buffer() could strategically arrange for
374041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington   * that to usually not happen.
375041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington   */
376041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
377041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  loader->buffer_outstanding = FALSE;
378041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
379271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington  while (_dbus_string_get_length (&loader->data) >= 7)
380041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
381041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      DBusMessage *message;
382041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
383041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      message = dbus_message_new ();
384041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      if (message == NULL)
385041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington        break; /* ugh, postpone this I guess. */
386041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
387041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_list_append (&loader->messages, message);
388041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
389271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington      _dbus_string_delete (&loader->data,
390271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington                           0, 7);
391271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
392041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_verbose ("Loaded message %p\n", message);
393041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
394041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
395041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
396041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
397041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Pops a loaded message (passing ownership of the message
398041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * to the caller). Returns #NULL if no messages have been
399041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * loaded.
400041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
401041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param loader the loader.
402041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @returns the next message, or #NULL if none.
403041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
404041b0767b284034aee09e9a0de2a3844b8cc546aHavoc PenningtonDBusMessage*
405041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_message_loader_pop_message (DBusMessageLoader *loader)
406041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
407041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  return _dbus_list_pop_first (&loader->messages);
40893f222c1d8ed748994f74662671d003495b16d43Havoc Pennington}
40993f222c1d8ed748994f74662671d003495b16d43Havoc Pennington
41093f222c1d8ed748994f74662671d003495b16d43Havoc Pennington/** @} */
411