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 }
WvBufBaseCommonImpl::get
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
WvDBusMsg::demarshal
static WvDBusMsg * demarshal(WvBuf &buf)
Demarshals a new WvDBusMsg from a buffer containing its binary DBus protocol representation.
Definition: wvdbusmarshal.cc:27
WvDBusMsg
Definition: wvdbusmsg.h:28
WvDBusMsg::marshal
void marshal(WvBuf &buf)
Locks this message, encodes it in DBus binary protocol format, and adds it to the given buffer.
Definition: wvdbusmarshal.cc:83
WvBufBase< unsigned char >
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers.
Definition: wvbuf.h:22
WvDBusMsg::WvDBusMsg
WvDBusMsg(WvStringParm busname, WvStringParm objectname, WvStringParm ifc, WvStringParm method)
Constructs a new WvDBus message.
Definition: wvdbusmsg.cc:323
WvDynBufBase< unsigned char >
WvBufBaseCommonImpl::used
size_t used() const
Returns the number of elements in the buffer currently available for reading.
Definition: wvbufbase.h:92
WvBufBaseCommonImpl::peek
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
WvDBusMsg::demarshal_bytes_needed
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...
Definition: wvdbusmarshal.cc:70