WvStreams
|
00001 /* -*- Mode: C++ -*- 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 2004-2006 Net Integration Technologies, Inc. 00004 * 00005 * Ugly routines that call directly into DBus internals for marshalling and 00006 * demarshalling DBusMessage objects into data buffers. 00007 * 00008 * We separate this into a separate file mostly so we don't mix DBus 00009 * internal header files with other WvStreams header files. 00010 */ 00011 #include <inttypes.h> 00012 #define DBUS_COMPILATION 00013 //#undef PACKAGE_BUGREPORT 00014 //#undef PACKAGE_NAME 00015 //#undef PACKAGE_STRING 00016 //#undef PACKAGE_TARNAME 00017 //#undef PACKAGE_VERSION 00018 #undef interface 00019 #include <dbus/dbus.h> 00020 #include <dbus-upstream/dbus/dbus-marshal-header.h> 00021 #include <dbus-upstream/dbus/dbus-internals.h> 00022 #include <dbus-upstream/dbus/dbus-string.h> 00023 #include <dbus-upstream/dbus/dbus-message-private.h> 00024 00025 int wvdbus_marshal(DBusMessage *msg, char **cbuf, size_t *len) 00026 { 00027 static uint32_t global_serial = 1000; 00028 DBusString tmp; 00029 00030 if (!_dbus_string_init (&tmp)) 00031 return 0; 00032 00033 if (!dbus_message_get_serial(msg)) 00034 _dbus_message_set_serial(msg, ++global_serial); 00035 00036 _dbus_message_lock(msg); 00037 _dbus_string_copy(&msg->header.data, 0, &tmp, 0); 00038 *len = _dbus_string_get_length(&tmp); 00039 _dbus_string_copy(&msg->body, 0, &tmp, *len); 00040 *len = _dbus_string_get_length(&tmp); 00041 00042 _dbus_string_steal_data(&tmp, cbuf); 00043 _dbus_string_free(&tmp); 00044 return 1; 00045 } 00046 00047 00048 size_t wvdbus_message_length(const void *buf, size_t len) 00049 { 00050 if (!buf || len < DBUS_MINIMUM_HEADER_SIZE) 00051 return DBUS_MINIMUM_HEADER_SIZE; 00052 00053 // doesn't copy - no need to free 00054 DBusString buftmp; 00055 _dbus_string_init_const_len(&buftmp, (const char *)buf, len); 00056 00057 int byte_order, fields_array_len, header_len, body_len; 00058 DBusValidity validity = DBUS_VALID; 00059 int have_message 00060 = _dbus_header_have_message_untrusted(DBUS_MAXIMUM_MESSAGE_LENGTH, 00061 &validity, &byte_order, 00062 &fields_array_len, 00063 &header_len, 00064 &body_len, 00065 &buftmp, 0, 00066 len); 00067 if (have_message || validity == DBUS_VALID) 00068 return header_len + body_len; 00069 else 00070 return 0; // broken! 00071 } 00072 00073 00074 DBusMessage *wvdbus_demarshal(const void *buf, size_t len, size_t *used) 00075 { 00076 DBusMessageLoader *loader; 00077 DBusString *lbuf; 00078 DBusMessage *msg; 00079 00080 if (!buf) 00081 { 00082 *used = 0; 00083 return NULL; 00084 } 00085 00086 size_t real_len = wvdbus_message_length(buf, len); 00087 if (real_len == 0) // invalid message data 00088 { 00089 *used = len; // clear invalid crap - the best we can do 00090 return NULL; 00091 } 00092 else if (real_len > len) // not enough data 00093 { 00094 *used = 0; 00095 return NULL; 00096 } 00097 00098 loader = _dbus_message_loader_new(); 00099 if (!loader) 00100 return NULL; 00101 00102 _dbus_message_loader_get_buffer(loader, &lbuf); 00103 _dbus_string_append_len(lbuf, (const char *)buf, real_len); 00104 _dbus_message_loader_return_buffer(loader, lbuf, real_len); 00105 00106 if (!_dbus_message_loader_queue_messages(loader)) 00107 goto fail; 00108 00109 if (_dbus_message_loader_get_is_corrupted(loader)) 00110 goto fail; 00111 00112 msg = _dbus_message_loader_pop_message(loader); 00113 if (!msg) 00114 goto fail; 00115 00116 _dbus_message_loader_unref(loader); 00117 *used = real_len; 00118 return msg; 00119 00120 fail: 00121 _dbus_message_loader_unref(loader); 00122 *used = real_len ? real_len : len; 00123 return NULL; 00124 }