1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal.c Marshalling routines
4 * Copyright (C) 2002 CodeFactory AB
6 * Licensed under the Academic Free License version 1.2
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "dbus-marshal.h"
25 #include "dbus-internals.h"
29 /* This alignment thing is from ORBit2 */
30 /* Align a value upward to a boundary, expressed as a number of bytes.
31 E.g. align to an 8-byte boundary with argument of 8. */
34 * (this + boundary - 1)
39 #define DBUS_ALIGN_VALUE(this, boundary) \
40 (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
42 #define DBUS_ALIGN_ADDRESS(this, boundary) \
43 ((void*)DBUS_ALIGN_VALUE(this, boundary))
47 swap_bytes (unsigned char *data,
50 unsigned char *p1 = data;
51 unsigned char *p2 = data + len - 1;
55 unsigned char tmp = *p1;
65 _dbus_marshal_double (DBusString *str,
69 if (!_dbus_string_set_length (str,
70 DBUS_ALIGN_VALUE (_dbus_string_get_length (str),
74 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
75 swap_bytes ((unsigned char *)&value, sizeof (double));
77 return _dbus_string_append_len (str, (const char *)&value, sizeof (double));
81 _dbus_marshal_int32 (DBusString *str,
85 if (!_dbus_string_set_length (str,
86 DBUS_ALIGN_VALUE (_dbus_string_get_length (str),
87 sizeof (dbus_int32_t))))
90 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
91 swap_bytes ((unsigned char *)&value, sizeof (dbus_int32_t));
93 return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_int32_t));
97 _dbus_marshal_uint32 (DBusString *str,
101 if (!_dbus_string_set_length (str,
102 DBUS_ALIGN_VALUE (_dbus_string_get_length (str),
103 sizeof (dbus_uint32_t))))
106 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
107 swap_bytes ((unsigned char *)&value, sizeof (dbus_uint32_t));
109 return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_uint32_t));
113 _dbus_marshal_string (DBusString *str,
119 if (!_dbus_string_set_length (str,
120 DBUS_ALIGN_VALUE (_dbus_string_get_length (str),
121 sizeof (dbus_uint32_t))))
124 len = strlen (value);
126 if (!_dbus_string_lengthen (str, len + 1))
129 if (!_dbus_marshal_uint32 (str, byte_order, len))
132 return _dbus_string_append_len (str, value, len + 1);
137 _dbus_demarshal_double (DBusString *str,
145 _dbus_string_get_const_data_len (str, &buffer, pos, sizeof (double));
147 retval = *(double *)buffer;
149 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
150 swap_bytes ((unsigned char *)&retval, sizeof (double));
153 *new_pos = pos + sizeof (double);
159 _dbus_demarshal_int32 (DBusString *str,
167 _dbus_string_get_const_data_len (str, &buffer, pos, sizeof (dbus_int32_t));
169 retval = *(dbus_int32_t *)buffer;
171 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
172 swap_bytes ((unsigned char *)&retval, sizeof (dbus_int32_t));
175 *new_pos = pos + sizeof (dbus_int32_t);
181 _dbus_demarshal_uint32 (DBusString *str,
186 dbus_uint32_t retval;
189 _dbus_string_get_const_data_len (str, &buffer, pos, sizeof (dbus_uint32_t));
191 retval = *(dbus_uint32_t *)buffer;
193 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
194 swap_bytes ((unsigned char *)&retval, sizeof (dbus_uint32_t));
197 *new_pos = pos + sizeof (dbus_uint32_t);
203 _dbus_demarshal_string (DBusString *str,
212 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
214 retval = dbus_malloc (len + 1);
219 _dbus_string_get_const_data_len (str, &data, pos, len + 1);
224 memcpy (retval, data, len + 1);
227 *new_pos = pos + len + 1;
234 #ifdef DBUS_BUILD_TESTS
235 #include "dbus-test.h"
239 _dbus_marshal_test (void)
244 if (!_dbus_string_init (&str, _DBUS_INT_MAX))
245 _dbus_assert_not_reached ("failed to init string");
248 /* Marshal doubles */
249 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
250 _dbus_assert_not_reached ("could not marshal double value");
251 _dbus_assert (_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14);
254 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
255 _dbus_assert_not_reached ("could not marshal double value");
256 _dbus_assert (_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14);
258 /* Marshal signed integers */
259 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
260 _dbus_assert_not_reached ("could not marshal signed integer value");
261 _dbus_assert (_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678);
263 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
264 _dbus_assert_not_reached ("could not marshal signed integer value");
265 _dbus_assert (_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678);
267 /* Marshal unsigned integers */
268 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
269 _dbus_assert_not_reached ("could not marshal signed integer value");
270 _dbus_assert (_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678);
272 _dbus_string_free (&str);
274 /* FIXME. Add string marshal tests */
279 #endif /* DBUS_BUILD_TESTS */