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