From f25559f534de1d81631b0c517b24a9b0e0818d21 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Wed, 25 Dec 2002 14:18:04 +0000 Subject: 2002-12-25 Anders Carlsson * dbus/Makefile.am: * dbus/dbus-marshal.c: (swap_bytes), (_dbus_marshal_double), (_dbus_marshal_int32), (_dbus_marshal_uint32), (_dbus_demarshal_double), (_dbus_demarshal_int32), (_dbus_demarshal_uint32), (_dbus_marshal_test): * dbus/dbus-marshal.h: * dbus/dbus-protocol.h: * dbus/dbus-test.c: (main): * dbus/dbus-test.h: Add un-optimized marshalling/demarshalling routines. --- dbus/Makefile.am | 2 + dbus/dbus-marshal.c | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++ dbus/dbus-marshal.h | 62 +++++++++++++++ dbus/dbus-protocol.h | 43 ++++++++++ dbus/dbus-test.c | 5 +- dbus/dbus-test.h | 2 +- 6 files changed, 328 insertions(+), 2 deletions(-) create mode 100644 dbus/dbus-marshal.c create mode 100644 dbus/dbus-marshal.h create mode 100644 dbus/dbus-protocol.h (limited to 'dbus') diff --git a/dbus/Makefile.am b/dbus/Makefile.am index 74b5dfbb..ba968ce4 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -53,6 +53,8 @@ libdbus_convenience_la_SOURCES= \ dbus-internals.h \ dbus-list.c \ dbus-list.h \ + dbus-marshal.c \ + dbus-marshal.h \ dbus-mempool.c \ dbus-mempool.h \ dbus-string.c \ diff --git a/dbus/dbus-marshal.c b/dbus/dbus-marshal.c new file mode 100644 index 00000000..0f9def5b --- /dev/null +++ b/dbus/dbus-marshal.c @@ -0,0 +1,216 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-marshal.c Marshalling routines + * + * Copyright (C) 2002 CodeFactory AB + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "dbus-marshal.h" +#include "dbus-internals.h" + + +/* This alignment thing is from ORBit2 */ +/* Align a value upward to a boundary, expressed as a number of bytes. + E.g. align to an 8-byte boundary with argument of 8. */ + +/* + * (this + boundary - 1) + * & + * ~(boundary - 1) + */ + +#define DBUS_ALIGN_VALUE(this, boundary) \ + (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) + +#define DBUS_ALIGN_ADDRESS(this, boundary) \ + ((void*)DBUS_ALIGN_VALUE(this, boundary)) + +/* from ORBit */ +static void +swap_bytes (unsigned char *data, + unsigned int len) +{ + unsigned char *p1 = data; + unsigned char *p2 = data + len - 1; + + while (p1 < p2) + { + unsigned char tmp = *p1; + *p1 = *p2; + *p2 = tmp; + + --p2; + ++p1; + } +} + +dbus_bool_t +_dbus_marshal_double (DBusString *str, + int byte_order, + double value) +{ + if (!_dbus_string_set_length (str, + DBUS_ALIGN_VALUE (_dbus_string_get_length (str), + sizeof (double)))) + return FALSE; + + if (byte_order != DBUS_COMPILER_BYTE_ORDER) + swap_bytes ((unsigned char *)&value, sizeof (double)); + + return _dbus_string_append_len (str, (const char *)&value, sizeof (double)); +} + +dbus_bool_t +_dbus_marshal_int32 (DBusString *str, + int byte_order, + dbus_int32_t value) +{ + if (!_dbus_string_set_length (str, + DBUS_ALIGN_VALUE (_dbus_string_get_length (str), + sizeof (dbus_int32_t)))) + return FALSE; + + if (byte_order != DBUS_COMPILER_BYTE_ORDER) + swap_bytes ((unsigned char *)&value, sizeof (dbus_int32_t)); + + return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_int32_t)); +} + +dbus_bool_t +_dbus_marshal_uint32 (DBusString *str, + int byte_order, + dbus_uint32_t value) +{ + if (!_dbus_string_set_length (str, + DBUS_ALIGN_VALUE (_dbus_string_get_length (str), + sizeof (dbus_uint32_t)))) + return FALSE; + + if (byte_order != DBUS_COMPILER_BYTE_ORDER) + swap_bytes ((unsigned char *)&value, sizeof (dbus_uint32_t)); + + return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_uint32_t)); +} + + + +double +_dbus_demarshal_double (DBusString *str, + int byte_order, + int start) +{ + double retval; + const char *buffer; + + _dbus_string_get_const_data_len (str, &buffer, start, sizeof (double)); + + retval = *(double *)buffer; + + if (byte_order != DBUS_COMPILER_BYTE_ORDER) + swap_bytes ((unsigned char *)&retval, sizeof (double)); + + return retval; +} + +dbus_int32_t +_dbus_demarshal_int32 (DBusString *str, + int byte_order, + int start) +{ + dbus_int32_t retval; + const char *buffer; + + _dbus_string_get_const_data_len (str, &buffer, start, sizeof (dbus_int32_t)); + + retval = *(dbus_int32_t *)buffer; + + if (byte_order != DBUS_COMPILER_BYTE_ORDER) + swap_bytes ((unsigned char *)&retval, sizeof (dbus_int32_t)); + + return retval; +} + +dbus_uint32_t +_dbus_demarshal_uint32 (DBusString *str, + int byte_order, + int start) +{ + dbus_uint32_t retval; + const char *buffer; + + _dbus_string_get_const_data_len (str, &buffer, start, sizeof (dbus_uint32_t)); + + retval = *(dbus_uint32_t *)buffer; + + if (byte_order != DBUS_COMPILER_BYTE_ORDER) + swap_bytes ((unsigned char *)&retval, sizeof (dbus_uint32_t)); + + return retval; +} + +/** @} */ + +#ifdef DBUS_BUILD_TESTS +#include "dbus-test.h" +#include + +dbus_bool_t +_dbus_marshal_test (void) +{ + DBusString str; + int pos = 0; + + if (!_dbus_string_init (&str, _DBUS_INT_MAX)) + _dbus_assert_not_reached ("failed to init string"); + + + /* Marshal doubles */ + if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14)) + _dbus_assert_not_reached ("could not marshal double value"); + _dbus_assert (_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos) == 3.14); + pos += 8; + + if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14)) + _dbus_assert_not_reached ("could not marshal double value"); + _dbus_assert (_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos) == 3.14); + pos += 8; + + /* Marshal signed integers */ + if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678)) + _dbus_assert_not_reached ("could not marshal signed integer value"); + _dbus_assert (_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos) == -12345678); + pos += 4; + + if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678)) + _dbus_assert_not_reached ("could not marshal signed integer value"); + _dbus_assert (_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos) == -12345678); + pos += 4; + + /* Marshal unsigned integers */ + if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678)) + _dbus_assert_not_reached ("could not marshal signed integer value"); + _dbus_assert (_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos) == 0x12345678); + pos += 4; + + _dbus_string_free (&str); + + return TRUE; +} + +#endif /* DBUS_BUILD_TESTS */ diff --git a/dbus/dbus-marshal.h b/dbus/dbus-marshal.h new file mode 100644 index 00000000..00a5f502 --- /dev/null +++ b/dbus/dbus-marshal.h @@ -0,0 +1,62 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-marshal.h Marshalling routines + * + * Copyright (C) 2002 CodeFactory AB + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef DBUS_MARSHAL_H +#define DBUS_MARSHAL_H + +#include +#include +#include + +#ifdef WORDS_BIGENDIAN +#define DBUS_COMPILER_BYTE_ORDER DBUS_LITTLE_ENDIAN +#else +#define DBUS_COMPILER_BYTE_ORDER DBUS_BIG_ENDIAN +#endif + +dbus_bool_t _dbus_marshal_double (DBusString *str, + int byte_order, + double value); +dbus_bool_t _dbus_marshal_int32 (DBusString *str, + int byte_order, + dbus_int32_t value); +dbus_bool_t _dbus_marshal_uint32 (DBusString *str, + int byte_order, + dbus_uint32_t value); + +double _dbus_demarshal_double (DBusString *str, + int byte_order, + int start); +dbus_int32_t _dbus_demarshal_int32 (DBusString *str, + int byte_order, + int start); +dbus_uint32_t _dbus_demarshal_uint32 (DBusString *str, + int byte_order, + int start); + + + + + + +#endif /* DBUS_PROTOCOL_H */ diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h new file mode 100644 index 00000000..0e009241 --- /dev/null +++ b/dbus/dbus-protocol.h @@ -0,0 +1,43 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-protocol.h D-Bus protocol constants + * + * Copyright (C) 2002 CodeFactory AB + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef DBUS_PROTOCOL_H +#define DBUS_PROTOCOL_H + +/* Don't include anything in here from anywhere else. It's + * intended for use by any random library. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Message byte order */ +#define DBUS_LITTLE_ENDIAN ('l') /* LSB first */ +#define DBUS_BIG_ENDIAN ('B') /* MSB first */ + +#ifdef __cplusplus +} +#endif + +#endif /* DBUS_PROTOCOL_H */ diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c index df840a7c..d09c5486 100644 --- a/dbus/dbus-test.c +++ b/dbus/dbus-test.c @@ -37,7 +37,10 @@ int main (int argc, char **argv) { - + printf ("%s: running marshalling tests\n", argv[0]); + if (!_dbus_marshal_test ()) + die ("marshalling"); + printf ("%s: running memory pool tests\n", argv[0]); if (!_dbus_mem_pool_test ()) die ("memory pools"); diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h index 80e0204c..e2624ede 100644 --- a/dbus/dbus-test.h +++ b/dbus/dbus-test.h @@ -28,8 +28,8 @@ dbus_bool_t _dbus_hash_test (void); dbus_bool_t _dbus_list_test (void); +dbus_bool_t _dbus_marshal_test (void); dbus_bool_t _dbus_mem_pool_test (void); dbus_bool_t _dbus_string_test (void); - #endif /* DBUS_TEST_H */ -- cgit