/* * Copyright 2008-2011 Novell, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include void marshal (DBusMessage *msg, const char *type, void *ptr) { DBusMessageIter iter; dbus_message_iter_init_append (msg, &iter); dbind_any_marshal (&iter, &type, &ptr); } void demarshal (DBusMessage *msg, const char *type, void *ptr) { DBusMessageIter iter; if (!dbus_message_iter_init (msg, &iter)) { fprintf (stderr, "no data in msg\n"); g_assert_not_reached (); } else dbind_any_demarshal (&iter, &type, &ptr); } #if 0 dbus_bool_t dbus_message_marshal (DBusMessage *msg, char **marshalled_data_p, int *len_p); void dump_msg (DBusMessage *msg) { char *data = NULL; int len, i, j; dbus_message_marshal (msg, &data, &len); for (i = 0; i < (len+15)/16; i++) { fprintf (stderr, "%4.d | ", i * 16); for (j = 0; j < 16; j++) { unsigned char c = (i*16+j <= len) ? data[i*16+j] : 0; fprintf (stderr, "0x%.2x ", c); } fprintf (stderr, " | "); for (j = 0; j < 16; j++) { char c = (i*16+j <= len) ? data[i*16+j] : '\0'; fprintf (stderr, "%c", g_ascii_isprint (c) ? c : '.'); } } } #endif void test_simple () { dbus_int32_t v1, v2; DBusMessage *msg; msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL); v1 = 42; marshal (msg, "i", &v1); demarshal (msg, "i", &v2); g_assert (v2 == 42); g_assert (v1 == v2); dbind_any_free ("i", &v2); /* nop */ dbus_message_unref (msg); printf ("simple ok\n"); } void test_array () { GArray *a1, *a2; DBusMessage *msg; /* pod types */ a1 = g_array_new (FALSE, FALSE, sizeof (dbus_int32_t)); g_array_set_size (a1, 4); g_array_index (a1, dbus_int32_t, 0) = 42; g_array_index (a1, dbus_int32_t, 1) = 17; g_array_index (a1, dbus_int32_t, 2) = 26; g_array_index (a1, dbus_int32_t, 3) = 38; msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL); marshal (msg, "ai", &a1); demarshal (msg, "ai", &a2); g_assert (a2 != NULL); g_assert (a2->len == 4); g_assert (g_array_index (a2, dbus_int32_t, 0) == 42); g_assert (g_array_index (a2, dbus_int32_t, 1) == 17); g_assert (g_array_index (a2, dbus_int32_t, 2) == 26); g_assert (g_array_index (a2, dbus_int32_t, 3) == 38); g_array_free (a1, TRUE); dbind_any_free ("ai", &a2); dbus_message_unref (msg); printf ("array ok\n"); } /* this taught me that the struct type is a mis-nomer, it is generated by brackets */ void test_struct_native () { DBusMessage *msg; DBusMessageIter iter, arr, str; /* manually create ar(ss) */ msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL); dbus_message_iter_init_append (msg, &iter); dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(ss)", &arr); { char *foo; dbus_message_iter_open_container (&arr, DBUS_TYPE_STRUCT, NULL, &str); foo = "foo"; dbus_message_iter_append_basic (&str, DBUS_TYPE_STRING, &foo); foo = "baa"; dbus_message_iter_append_basic (&str, DBUS_TYPE_STRING, &foo); dbus_message_iter_close_container (&arr, &str); } dbus_message_iter_close_container (&iter, &arr); printf ("native struct marshalling ok\n"); dbus_message_unref (msg); } void test_struct_simple () { typedef struct { char *foo; char *baa; char *baz; } FooBaa; GArray *a1 = NULL, *a2 = NULL; DBusMessage *msg; a1 = g_array_new (FALSE, FALSE, sizeof (FooBaa)); g_array_set_size (a1, 2); g_array_index (a1, FooBaa, 0).foo = "foo"; g_array_index (a1, FooBaa, 0).baa = "baa"; g_array_index (a1, FooBaa, 0).baz = "baz"; g_array_index (a1, FooBaa, 1).foo = "Foo"; g_array_index (a1, FooBaa, 1).baa = "baA"; g_array_index (a1, FooBaa, 1).baz = "BaZ"; msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL); marshal (msg, "a(sss)", &a1); demarshal (msg, "a(sss)", &a2); g_assert (a2 != NULL); g_assert (a2 != a1); g_assert (a2->len == 2); g_assert (!strcmp (g_array_index (a2, FooBaa, 0).foo, "foo")); g_assert (!strcmp (g_array_index (a2, FooBaa, 0).baa, "baa")); g_assert (!strcmp (g_array_index (a2, FooBaa, 0).baz, "baz")); g_assert (!strcmp (g_array_index (a2, FooBaa, 1).foo, "Foo")); g_assert (!strcmp (g_array_index (a2, FooBaa, 1).baa, "baA")); g_assert (!strcmp (g_array_index (a2, FooBaa, 1).baz, "BaZ")); printf ("simple struct ok\n"); dbind_any_free ("a(sss)", &a2); dbus_message_unref (msg); } void test_struct_complex () { typedef struct { dbus_int32_t x, y; } Point; typedef struct { unsigned char pad1; double val; Point tl, br; char pad2; char *name; } Complex; #define TYPEOF_POINT \ DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ DBUS_TYPE_INT32_AS_STRING \ DBUS_TYPE_INT32_AS_STRING \ DBUS_STRUCT_END_CHAR_AS_STRING #define TYPEOF_COMPLEX \ DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ DBUS_TYPE_BYTE_AS_STRING \ DBUS_TYPE_DOUBLE_AS_STRING \ TYPEOF_POINT \ TYPEOF_POINT \ DBUS_TYPE_BYTE_AS_STRING \ DBUS_TYPE_STRING_AS_STRING \ DBUS_STRUCT_END_CHAR_AS_STRING DBusMessage *msg; Complex c1, c2; memset (&c1, 0, sizeof (c1)); memset (&c2, 0, sizeof (c2)); c1.pad1 = 2; c1.val = 0.1327569; c1.tl.x = 1; c1.tl.y = 17; c1.br.x = 2587; c1.br.y = -1; c1.pad2 = 1; c1.name = "stroustrup"; msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL); marshal (msg, TYPEOF_COMPLEX, &c1); demarshal (msg, TYPEOF_COMPLEX, &c2); g_assert (c2.pad1 == 2); g_assert (c2.val == c1.val); g_assert (c2.val != 0); g_assert (c2.tl.x == 1); g_assert (c2.tl.y == 17); g_assert (c2.br.x == 2587); g_assert (c2.br.y == -1); g_assert (c2.pad2 == 1); g_assert (!strcmp (c1.name, "stroustrup")); printf ("complex struct ok\n"); dbind_any_free (TYPEOF_COMPLEX, &c2); dbus_message_unref (msg); } void test_struct_with_array () { typedef struct { GArray *vals; unsigned char pad1; } ArrayStruct; #define TYPEOF_ARRAYSTRUCT \ DBUS_TYPE_ARRAY_AS_STRING \ DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ DBUS_TYPE_ARRAY_AS_STRING \ DBUS_TYPE_UINT32_AS_STRING \ DBUS_TYPE_BYTE_AS_STRING \ DBUS_STRUCT_END_CHAR_AS_STRING DBusMessage *msg; GArray *a1, *a2; ArrayStruct *p, *q; a1 = g_array_new (FALSE, FALSE, sizeof (ArrayStruct)); g_array_set_size (a1, 2); p = &g_array_index (a1, ArrayStruct, 0); p[0].vals = g_array_new (FALSE, FALSE, sizeof (dbus_uint32_t)); g_array_set_size (p[0].vals, 2); g_array_index (p[0].vals, dbus_uint32_t, 0) = 1; g_array_index (p[0].vals, dbus_uint32_t, 1) = 1000; p[0].pad1 = 2; p[1].vals = g_array_new (FALSE, FALSE, sizeof (dbus_uint32_t)); g_array_set_size (p[1].vals, 2); g_array_index (p[1].vals, dbus_uint32_t, 0) = 1000000; g_array_index (p[1].vals, dbus_uint32_t, 1) = 1000000000; p[1].pad1 = 8; msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL); marshal (msg, TYPEOF_ARRAYSTRUCT, &a1); demarshal (msg, TYPEOF_ARRAYSTRUCT, &a2); q = &g_array_index (a2, ArrayStruct, 0); g_assert (q[0].pad1 == 2); g_assert (g_array_index (q[1].vals, dbus_uint32_t, 1) == 1000000000); printf ("struct with array ok\n"); dbind_any_free (TYPEOF_ARRAYSTRUCT, &a2); dbus_message_unref (msg); g_array_free (p[0].vals, TRUE); g_array_free (p[1].vals, TRUE); } void test_twovals () { typedef struct { dbus_int32_t v1; dbus_int32_t v2; } TwoVal; #define TYPEOF_TWOVAL \ DBUS_TYPE_INT32_AS_STRING \ DBUS_TYPE_INT32_AS_STRING DBusMessage *msg; DBusMessageIter iter; TwoVal i, o; const char *type_twoval = TYPEOF_TWOVAL; const char *type; void *ptr; msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL); i.v1 = 42; i.v2 = 1764; dbus_message_iter_init_append (msg, &iter); type = type_twoval; ptr = &i; dbind_any_marshal (&iter, &type, &ptr); dbind_any_marshal (&iter, &type, &ptr); dbus_message_iter_init (msg, &iter); type = type_twoval; ptr = &o; dbind_any_demarshal (&iter, &type, &ptr); dbind_any_demarshal (&iter, &type, &ptr); g_assert (o.v1 == 42); g_assert (o.v2 == 1764); g_assert (i.v1 == o.v1); g_assert (i.v2 == o.v2); dbind_any_free ("ii", &o); /* nop */ dbus_message_unref (msg); printf ("two-val ok\n"); } void test_marshalling () { test_simple (); test_array (); test_struct_native (); test_struct_simple (); test_struct_complex (); test_struct_with_array (); test_twovals (); printf ("Marshalling ok\n"); } void test_helpers () { dbind_find_c_alignment ("(sss)"); dbind_find_c_alignment ("a(sss)"); dbind_find_c_alignment ("(s(s)yd(d)s)"); dbind_find_c_alignment ("a{ss}"); printf ("helpers passed\n"); } int main (int argc, char **argv) { DBusConnection *bus = dbus_bus_get (DBUS_BUS_SESSION, NULL); g_assert (bus != NULL); test_helpers (); test_marshalling (); return 0; }