WvStreams
wvdbusmarshal.cc
1 /* -*- Mode: C++ -*-
2  * Worldvisions Weaver Software:
3  * Copyright (C) 2004-2006 Net Integration Technologies, Inc.
4  *
5  * Wrapper code for marshalling/demarshalling WvDBusMsg objects. This is
6  * in a separate file from WvDBusMsg in case you want to use a WvDBusMsg
7  * but not our special/gross marshalling code from wvdbusmarshal_c.c.
8  *
9  */
10 #include "wvdbusmsg.h"
11 #undef interface // windows
12 #include <dbus/dbus.h>
13 
14 
15 static int wvdbus_message_length(const char *buf, size_t len)
16 {
17  int msglen = dbus_message_demarshal_bytes_needed(buf, len);
18  if (msglen > 0)
19  return msglen;
20  else if (msglen == 0)
21  return DBUS_MINIMUM_HEADER_SIZE;
22 
23  return 0;
24 }
25 
26 
28 {
29  // to make sure bytes are aligned (as required by d-bus), copy them into a
30  // new buffer (not very efficient, but what can you do without reworking
31  // our buffer implementation)
32  WvDynBuf alignedbuf;
33  size_t buflen = buf.used();
34  alignedbuf.put(buf.peek(0, buflen), buflen);
35 
36  // first get size of message to demarshal. if too little or bad length,
37  // return NULL (possibly after consuming the bad data)
38  size_t messagelen = wvdbus_message_length((const char *)
39  alignedbuf.peek(0, buflen),
40  buflen);
41  if (messagelen == 0) // invalid message data
42  {
43  buf.get(buflen); // clear invalid crap - the best we can do
44  return NULL;
45  }
46  else if (messagelen > buflen) // not enough data
47  return NULL;
48 
49  // Assuming that worked and we can demarshal a message, try to do so
50  DBusError error;
51  dbus_error_init(&error);
52  DBusMessage *_msg = dbus_message_demarshal((const char *)
53  alignedbuf.peek(0, buflen),
54  messagelen, &error);
55  if (dbus_error_is_set(&error))
56  dbus_error_free (&error);
57  buf.get(messagelen);
58 
59  if (_msg)
60  {
61  WvDBusMsg *msg = new WvDBusMsg(_msg);
62  dbus_message_unref(_msg);
63  return msg;
64  }
65  else
66  return NULL;
67 }
68 
69 
71 {
72  // to make sure bytes are aligned (as required by d-bus), copy them into a
73  // new buffer (not very efficient, but what can you do without reworking
74  // our buffer implementation)
75  WvDynBuf alignedbuf;
76  size_t used = buf.used();
77  alignedbuf.put(buf.peek(0, used), used);
78 
79  return wvdbus_message_length((const char *)alignedbuf.peek(0, used), used);
80 }
81 
82 
84 {
85  DBusMessage *msg = *this;
86 
87  static uint32_t global_serial = 1000;
88  if (!dbus_message_get_serial(msg))
89  {
90  dbus_message_set_serial(msg, ++global_serial);
91  }
92 
93  dbus_message_lock (msg);
94  char *cbuf;
95  int len;
96  dbus_message_marshal(msg, &cbuf, &len);
97  buf.put(cbuf, len);
98  free(cbuf);
99 }
static size_t demarshal_bytes_needed(WvBuf &buf)
Given a buffer containing what might be the header of a DBus message, checks how many bytes need to b...
void marshal(WvBuf &buf)
Locks this message, encodes it in DBus binary protocol format, and adds it to the given buffer...
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers...
Definition: wvbuf.h:22
size_t used() const
Returns the number of elements in the buffer currently available for reading.
Definition: wvbufbase.h:92
const T * peek(int offset, size_t count)
Returns a const pointer into the buffer at the specified offset to the specified number of elements w...
Definition: wvbufbase.h:225
static WvDBusMsg * demarshal(WvBuf &buf)
Demarshals a new WvDBusMsg from a buffer containing its binary DBus protocol representation.
WvDBusMsg(WvStringParm busname, WvStringParm objectname, WvStringParm ifc, WvStringParm method)
Constructs a new WvDBus message.
Definition: wvdbusmsg.cc:323
const T * get(size_t count)
Reads exactly the specified number of elements and returns a pointer to a storage location owned by t...
Definition: wvbufbase.h:114