2005-01-23 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / dbus / dbus-message-factory.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-message-factory.c Generator of valid and invalid message data for test suite
3  *
4  * Copyright (C) 2005 Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  * 
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.
12  *
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.
17  * 
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
21  *
22  */
23 #include <config.h>
24
25 #ifdef DBUS_BUILD_TESTS
26 #include "dbus-message-factory.h"
27 #include "dbus-message-private.h"
28
29 typedef dbus_bool_t (* DBusInnerGeneratorFunc)   (int           sequence,
30                                                   DBusMessage **message_p);
31 typedef dbus_bool_t (* DBusMessageGeneratorFunc) (int           sequence,
32                                                   DBusString   *data,
33                                                   DBusValidity *expected_validity);
34
35 static void
36 set_reply_serial (DBusMessage *message)
37 {
38   if (message == NULL)
39     _dbus_assert_not_reached ("oom");
40   if (!dbus_message_set_reply_serial (message, 100))
41     _dbus_assert_not_reached ("oom");
42 }
43
44 static dbus_bool_t
45 generate_trivial_inner (int           sequence,
46                         DBusMessage **message_p)
47 {
48   DBusMessage *message;
49
50   switch (sequence)
51     {
52     case 0:
53       message = dbus_message_new_method_call ("org.freedesktop.TextEditor",
54                                               "/foo/bar",
55                                               "org.freedesktop.DocumentFactory",
56                                               "Create");
57       break;
58     case 1:
59       message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
60       set_reply_serial (message);
61       break;
62     case 2:
63       message = dbus_message_new_signal ("/foo/bar",
64                                          "org.freedesktop.DocumentFactory",
65                                          "Created");
66       break;
67     case 3:
68       message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
69
70       if (!dbus_message_set_error_name (message,
71                                         "org.freedesktop.TestErrorName"))
72         _dbus_assert_not_reached ("oom");
73       
74       {
75         DBusMessageIter iter;
76         const char *v_STRING = "This is an error";
77         
78         dbus_message_iter_init_append (message, &iter);
79         if (!dbus_message_iter_append_basic (&iter,
80                                              DBUS_TYPE_STRING,
81                                              &v_STRING))
82           _dbus_assert_not_reached ("oom");
83       }
84       
85       set_reply_serial (message);
86       break;
87     default:
88       return FALSE;
89     }
90   
91   if (message == NULL)
92     _dbus_assert_not_reached ("oom");
93
94   *message_p = message;
95   
96   return TRUE;
97 }
98
99 static dbus_bool_t
100 generate_outer (int                    sequence,
101                 DBusString            *data,
102                 DBusValidity          *expected_validity,
103                 DBusInnerGeneratorFunc func)
104 {
105   DBusMessage *message;
106
107   message = NULL;
108   if (!(*func)(sequence, &message))
109     return FALSE;
110
111   _dbus_assert (message != NULL);
112
113   _dbus_message_set_serial (message, 1);
114   _dbus_message_lock (message);
115   
116   *expected_validity = DBUS_VALID;
117
118   /* move for efficiency, since we'll nuke the message anyway */
119   if (!_dbus_string_move (&message->header.data, 0,
120                           data, 0))
121     _dbus_assert_not_reached ("oom");
122
123   if (!_dbus_string_copy (&message->body, 0,
124                           data, _dbus_string_get_length (data)))
125     _dbus_assert_not_reached ("oom");
126
127   dbus_message_unref (message);
128
129   return TRUE;
130 }
131
132 static dbus_bool_t
133 generate_trivial (int                    sequence,
134                   DBusString            *data,
135                   DBusValidity          *expected_validity)
136 {
137   return generate_outer (sequence, data, expected_validity,
138                          generate_trivial_inner);
139 }
140
141 static const DBusMessageGeneratorFunc generators[] = {
142   generate_trivial
143 };
144
145 void
146 _dbus_message_data_free (DBusMessageData *data)
147 {
148   _dbus_string_free (&data->data);
149 }
150
151 void
152 _dbus_message_data_iter_init (DBusMessageDataIter *iter)
153 {
154   iter->generator = 0;
155   iter->sequence = 0;
156 }
157
158 dbus_bool_t
159 _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter,
160                                       DBusMessageData     *data)
161 {
162   DBusMessageGeneratorFunc func;
163
164  restart:
165   if (iter->generator == _DBUS_N_ELEMENTS (generators))
166     return FALSE;
167   
168   func = generators[iter->generator];
169
170   if (!_dbus_string_init (&data->data))
171     _dbus_assert_not_reached ("oom");
172   
173   if ((*func)(iter->sequence, &data->data, &data->expected_validity))
174     iter->sequence += 1;
175   else
176     {
177       iter->generator += 1;
178       iter->sequence = 0;
179       _dbus_string_free (&data->data);
180       goto restart;
181     }
182   
183   return TRUE;
184 }
185
186 #endif /* DBUS_BUILD_TESTS */