2003-09-15 Havoc Pennington <hp@pobox.com>
[platform/upstream/dbus.git] / glib / dbus-gidl.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-gidl.c data structure describing an interface, to be generated from IDL
3  *             or something
4  *
5  * Copyright (C) 2003  Red Hat, Inc.
6  *
7  * Licensed under the Academic Free License version 1.2
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24
25 #include "dbus-gidl.h"
26
27 #ifndef DOXYGEN_SHOULD_SKIP_THIS
28
29 struct BaseInfo
30 {
31   unsigned int refcount : 28;
32   unsigned int type     : 4;
33   char *name;
34 };
35
36 struct NodeInfo
37 {
38   BaseInfo base;
39   GSList *interfaces;
40   GSList *nodes;
41 };
42
43 struct InterfaceInfo
44 {
45   BaseInfo base;
46   /* Since we have BaseInfo now these could be one list */
47   GSList *methods;
48   GSList *signals;
49 };
50
51 struct MethodInfo
52 {
53   BaseInfo base;
54   GSList *args;
55 };
56
57 struct SignalInfo
58 {
59   BaseInfo base;
60   GSList *args;
61 };
62
63 struct ArgInfo
64 {
65   BaseInfo base;
66   int type;
67   ArgDirection direction;
68 };
69
70 void
71 base_info_ref (BaseInfo *info)
72 {
73   g_return_if_fail (info != NULL);
74   g_return_if_fail (info->refcount > 0);
75   
76   info->refcount += 1;
77 }
78
79 static void
80 base_info_free (void *ptr)
81 {
82   BaseInfo *info;
83
84   info = ptr;
85   
86   g_free (info->name);
87   g_free (info);
88 }
89
90 void
91 base_info_unref (BaseInfo *info)
92 {
93   g_return_if_fail (info != NULL);
94   g_return_if_fail (info->refcount > 0);
95   
96   /* This is sort of bizarre, BaseInfo was tacked on later */
97
98   switch (info->type)
99     {
100     case INFO_TYPE_NODE:
101       node_info_unref ((NodeInfo*) info);
102       break;
103     case INFO_TYPE_INTERFACE:
104       interface_info_unref ((InterfaceInfo*) info);
105       break;
106     case INFO_TYPE_SIGNAL:
107       signal_info_unref ((SignalInfo*) info);
108       break;
109     case INFO_TYPE_METHOD:
110       method_info_unref ((MethodInfo*) info);
111       break;
112     case INFO_TYPE_ARG:
113       arg_info_unref ((ArgInfo*) info);
114       break;
115     }
116 }
117
118 InfoType
119 base_info_get_type (BaseInfo      *info)
120 {
121   return info->type;
122 }
123
124 const char*
125 base_info_get_name (BaseInfo *info)
126 {
127   return info->name;
128 }
129
130 void
131 base_info_set_name (BaseInfo      *info,
132                     const char    *name)
133 {
134   char *old;
135
136   old = info->name;
137   info->name = g_strdup (name);
138   g_free (old);
139 }
140
141 GType
142 base_info_get_gtype (void)
143 {
144   static GType our_type = 0;
145   
146   if (our_type == 0)
147     our_type = g_boxed_type_register_static ("BaseInfo",
148                                              (GBoxedCopyFunc) base_info_ref,
149                                              (GBoxedFreeFunc) base_info_unref);
150
151   return our_type;
152 }
153
154 static void
155 free_interface_list (GSList **interfaces_p)
156 {
157   GSList *tmp;
158   tmp = *interfaces_p;
159   while (tmp != NULL)
160     {
161       interface_info_unref (tmp->data);
162       tmp = tmp->next;
163     }
164   g_slist_free (*interfaces_p);
165   *interfaces_p = NULL;
166 }
167
168 static void
169 free_node_list (GSList **nodes_p)
170 {
171   GSList *tmp;
172   tmp = *nodes_p;
173   while (tmp != NULL)
174     {
175       node_info_unref (tmp->data);
176       tmp = tmp->next;
177     }
178   g_slist_free (*nodes_p);
179   *nodes_p = NULL;
180 }
181
182 static void
183 free_method_list (GSList **methods_p)
184 {
185   GSList *tmp;
186   tmp = *methods_p;
187   while (tmp != NULL)
188     {
189       method_info_unref (tmp->data);
190       tmp = tmp->next;
191     }
192   g_slist_free (*methods_p);
193   *methods_p = NULL;
194 }
195
196 static void
197 free_signal_list (GSList **signals_p)
198 {
199   GSList *tmp;
200   tmp = *signals_p;
201   while (tmp != NULL)
202     {
203       signal_info_unref (tmp->data);
204       tmp = tmp->next;
205     }
206   g_slist_free (*signals_p);
207   *signals_p = NULL;
208 }
209
210 NodeInfo*
211 node_info_new (const char *name)
212 {
213   NodeInfo *info;
214
215   /* name can be NULL */
216   
217   info = g_new0 (NodeInfo, 1);
218   info->base.refcount = 1;
219   info->base.name = g_strdup (name);
220   info->base.type = INFO_TYPE_NODE;
221   
222   return info;
223 }
224
225 void
226 node_info_ref (NodeInfo *info)
227 {
228   info->base.refcount += 1;
229 }
230
231 void
232 node_info_unref (NodeInfo *info)
233 {
234   info->base.refcount -= 1;
235   if (info->base.refcount == 0)
236     {
237       free_interface_list (&info->interfaces);
238       free_node_list (&info->nodes);
239       base_info_free (info);
240     }
241 }
242
243 const char*
244 node_info_get_name (NodeInfo *info)
245 {
246   return info->base.name;
247 }
248
249 GSList*
250 node_info_get_interfaces (NodeInfo *info)
251 {
252   return info->interfaces;
253 }
254
255 void
256 node_info_add_interface (NodeInfo *info,
257                          InterfaceInfo    *interface)
258 {
259   interface_info_ref (interface);
260   info->interfaces = g_slist_append (info->interfaces, interface);
261 }
262
263 GSList*
264 node_info_get_nodes (NodeInfo *info)
265 {
266   return info->nodes;
267 }
268
269 void
270 node_info_add_node (NodeInfo *info,
271                     NodeInfo *node)
272 {
273   node_info_ref (node);
274   info->nodes = g_slist_append (info->nodes, node);
275 }
276
277 InterfaceInfo*
278 interface_info_new (const char *name)
279 {
280   InterfaceInfo *info;
281
282   info = g_new0 (InterfaceInfo, 1);
283   info->base.refcount = 1;
284   info->base.name = g_strdup (name);
285   info->base.type = INFO_TYPE_INTERFACE;
286   
287   return info;
288 }
289
290 void
291 interface_info_ref (InterfaceInfo *info)
292 {
293   info->base.refcount += 1;
294 }
295
296 void
297 interface_info_unref (InterfaceInfo *info)
298 {
299   info->base.refcount -= 1;
300   if (info->base.refcount == 0)
301     {
302       free_method_list (&info->methods);
303       free_signal_list (&info->signals);
304       base_info_free (info);
305     }
306 }
307
308 const char*
309 interface_info_get_name (InterfaceInfo *info)
310 {
311   return info->base.name;
312 }
313
314 GSList*
315 interface_info_get_methods (InterfaceInfo *info)
316 {
317   return info->methods;
318 }
319
320 GSList*
321 interface_info_get_signals (InterfaceInfo *info)
322 {
323   return info->signals;
324 }
325
326 void
327 interface_info_add_method (InterfaceInfo *info,
328                            MethodInfo    *method)
329 {
330   method_info_ref (method);
331   info->methods = g_slist_append (info->methods, method);
332 }
333
334 void
335 interface_info_add_signal (InterfaceInfo *info,
336                            SignalInfo    *signal)
337 {
338   signal_info_ref (signal);
339   info->signals = g_slist_append (info->signals, signal);
340 }
341
342 static void
343 free_arg_list (GSList **args_p)
344 {
345   GSList *tmp;
346   tmp = *args_p;
347   while (tmp != NULL)
348     {
349       arg_info_unref (tmp->data);
350       tmp = tmp->next;
351     }
352   g_slist_free (*args_p);
353   *args_p = NULL;
354 }
355
356 MethodInfo*
357 method_info_new (const char *name)
358 {
359   MethodInfo *info;
360
361   info = g_new0 (MethodInfo, 1);
362   info->base.refcount = 1;
363   info->base.name = g_strdup (name);
364   info->base.type = INFO_TYPE_METHOD;
365   
366   return info;
367 }
368
369 void
370 method_info_ref (MethodInfo *info)
371 {
372   info->base.refcount += 1;
373 }
374
375 void
376 method_info_unref (MethodInfo *info)
377 {
378   info->base.refcount -= 1;
379   if (info->base.refcount == 0)
380     {
381       free_arg_list (&info->args);
382       base_info_free (info);
383     }
384 }
385
386 const char*
387 method_info_get_name (MethodInfo *info)
388 {
389   return info->base.name;
390 }
391
392 GSList*
393 method_info_get_args (MethodInfo *info)
394 {
395   return info->args;
396 }
397
398 void
399 method_info_add_arg (MethodInfo    *info,
400                      ArgInfo       *arg)
401 {
402   arg_info_ref (arg);
403   info->args = g_slist_append (info->args, arg);
404 }
405
406 SignalInfo*
407 signal_info_new (const char *name)
408 {
409   SignalInfo *info;
410
411   info = g_new0 (SignalInfo, 1);
412   info->base.refcount = 1;
413   info->base.name = g_strdup (name);
414   info->base.type = INFO_TYPE_SIGNAL;
415   
416   return info;
417 }
418
419 void
420 signal_info_ref (SignalInfo *info)
421 {
422   info->base.refcount += 1;
423 }
424
425 void
426 signal_info_unref (SignalInfo *info)
427 {
428   info->base.refcount -= 1;
429   if (info->base.refcount == 0)
430     {
431       free_arg_list (&info->args);
432       base_info_free (info);
433     }
434 }
435
436 const char*
437 signal_info_get_name (SignalInfo *info)
438 {
439   return info->base.name;
440 }
441
442 GSList*
443 signal_info_get_args (SignalInfo *info)
444 {
445   return info->args;
446 }
447
448 void
449 signal_info_add_arg (SignalInfo    *info,
450                      ArgInfo       *arg)
451 {
452   arg_info_ref (arg);
453   info->args = g_slist_append (info->args, arg);
454 }
455
456 ArgInfo*
457 arg_info_new (const char  *name,
458               ArgDirection direction,
459               int          type)
460 {
461   ArgInfo *info;
462
463   info = g_new0 (ArgInfo, 1);
464   info->base.refcount = 1;
465   info->base.type = INFO_TYPE_ARG;
466   
467   /* name can be NULL */
468   info->base.name = g_strdup (name);
469   info->direction = direction;
470   info->type = type;
471
472   return info;
473 }
474
475 void
476 arg_info_ref (ArgInfo *info)
477 {
478   info->base.refcount += 1;
479 }
480
481 void
482 arg_info_unref (ArgInfo *info)
483 {
484   info->base.refcount -= 1;
485   if (info->base.refcount == 0)
486     {
487       base_info_free (info);
488     }
489 }
490 const char*
491 arg_info_get_name (ArgInfo *info)
492 {
493   return info->base.name;
494 }
495
496 int
497 arg_info_get_type (ArgInfo *info)
498 {
499   return info->type;
500 }
501
502 ArgDirection
503 arg_info_get_direction (ArgInfo *info)
504 {
505   return info->direction;
506 }
507
508 #ifdef DBUS_BUILD_TESTS
509
510 /**
511  * @ingroup DBusGIDL
512  * Unit test for GLib IDL internals
513  * @returns #TRUE on success.
514  */
515 dbus_bool_t
516 _dbus_gidl_test (void)
517 {
518
519   return TRUE;
520 }
521
522 #endif /* DBUS_BUILD_TESTS */
523
524 #endif /* DOXYGEN_SHOULD_SKIP_THIS */