Main Page   Modules   Data Structures   File List   Data Fields   Related Pages  

dbus-gidl.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* dbus-gidl.c data structure describing an interface, to be generated from IDL
00003  *             or something
00004  *
00005  * Copyright (C) 2003  Red Hat, Inc.
00006  *
00007  * Licensed under the Academic Free License version 2.0
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  */
00024 
00025 #include "dbus-gidl.h"
00026 
00027 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00028 
00029 struct BaseInfo
00030 {
00031   unsigned int refcount : 28;
00032   unsigned int type     : 4;
00033   char *name;
00034 };
00035 
00036 struct NodeInfo
00037 {
00038   BaseInfo base;
00039   GSList *interfaces;
00040   GSList *nodes;
00041 };
00042 
00043 struct InterfaceInfo
00044 {
00045   BaseInfo base;
00046   /* Since we have BaseInfo now these could be one list */
00047   GSList *methods;
00048   GSList *signals;
00049 };
00050 
00051 struct MethodInfo
00052 {
00053   BaseInfo base;
00054   GSList *args;
00055 };
00056 
00057 struct SignalInfo
00058 {
00059   BaseInfo base;
00060   GSList *args;
00061 };
00062 
00063 struct ArgInfo
00064 {
00065   BaseInfo base;
00066   int type;
00067   ArgDirection direction;
00068 };
00069 
00070 BaseInfo *
00071 base_info_ref (BaseInfo *info)
00072 {
00073   g_return_val_if_fail (info != NULL, NULL);
00074   g_return_val_if_fail (info->refcount > 0, NULL);
00075   
00076   info->refcount += 1;
00077 
00078   return info;
00079 }
00080 
00081 static void
00082 base_info_free (void *ptr)
00083 {
00084   BaseInfo *info;
00085 
00086   info = ptr;
00087   
00088   g_free (info->name);
00089   g_free (info);
00090 }
00091 
00092 void
00093 base_info_unref (BaseInfo *info)
00094 {
00095   g_return_if_fail (info != NULL);
00096   g_return_if_fail (info->refcount > 0);
00097   
00098   /* This is sort of bizarre, BaseInfo was tacked on later */
00099 
00100   switch (info->type)
00101     {
00102     case INFO_TYPE_NODE:
00103       node_info_unref ((NodeInfo*) info);
00104       break;
00105     case INFO_TYPE_INTERFACE:
00106       interface_info_unref ((InterfaceInfo*) info);
00107       break;
00108     case INFO_TYPE_SIGNAL:
00109       signal_info_unref ((SignalInfo*) info);
00110       break;
00111     case INFO_TYPE_METHOD:
00112       method_info_unref ((MethodInfo*) info);
00113       break;
00114     case INFO_TYPE_ARG:
00115       arg_info_unref ((ArgInfo*) info);
00116       break;
00117     }
00118 }
00119 
00120 InfoType
00121 base_info_get_type (BaseInfo      *info)
00122 {
00123   return info->type;
00124 }
00125 
00126 const char*
00127 base_info_get_name (BaseInfo *info)
00128 {
00129   return info->name;
00130 }
00131 
00132 void
00133 base_info_set_name (BaseInfo      *info,
00134                     const char    *name)
00135 {
00136   char *old;
00137 
00138   old = info->name;
00139   info->name = g_strdup (name);
00140   g_free (old);
00141 }
00142 
00143 GType
00144 base_info_get_gtype (void)
00145 {
00146   static GType our_type = 0;
00147   
00148   if (our_type == 0)
00149     our_type = g_boxed_type_register_static ("BaseInfo",
00150                                              (GBoxedCopyFunc) base_info_ref,
00151                                              (GBoxedFreeFunc) base_info_unref);
00152 
00153   return our_type;
00154 }
00155 
00156 static void
00157 free_interface_list (GSList **interfaces_p)
00158 {
00159   GSList *tmp;
00160   tmp = *interfaces_p;
00161   while (tmp != NULL)
00162     {
00163       interface_info_unref (tmp->data);
00164       tmp = tmp->next;
00165     }
00166   g_slist_free (*interfaces_p);
00167   *interfaces_p = NULL;
00168 }
00169 
00170 static void
00171 free_node_list (GSList **nodes_p)
00172 {
00173   GSList *tmp;
00174   tmp = *nodes_p;
00175   while (tmp != NULL)
00176     {
00177       node_info_unref (tmp->data);
00178       tmp = tmp->next;
00179     }
00180   g_slist_free (*nodes_p);
00181   *nodes_p = NULL;
00182 }
00183 
00184 static void
00185 free_method_list (GSList **methods_p)
00186 {
00187   GSList *tmp;
00188   tmp = *methods_p;
00189   while (tmp != NULL)
00190     {
00191       method_info_unref (tmp->data);
00192       tmp = tmp->next;
00193     }
00194   g_slist_free (*methods_p);
00195   *methods_p = NULL;
00196 }
00197 
00198 static void
00199 free_signal_list (GSList **signals_p)
00200 {
00201   GSList *tmp;
00202   tmp = *signals_p;
00203   while (tmp != NULL)
00204     {
00205       signal_info_unref (tmp->data);
00206       tmp = tmp->next;
00207     }
00208   g_slist_free (*signals_p);
00209   *signals_p = NULL;
00210 }
00211 
00212 NodeInfo*
00213 node_info_new (const char *name)
00214 {
00215   NodeInfo *info;
00216 
00217   /* name can be NULL */
00218   
00219   info = g_new0 (NodeInfo, 1);
00220   info->base.refcount = 1;
00221   info->base.name = g_strdup (name);
00222   info->base.type = INFO_TYPE_NODE;
00223   
00224   return info;
00225 }
00226 
00227 NodeInfo *
00228 node_info_ref (NodeInfo *info)
00229 {
00230   info->base.refcount += 1;
00231 
00232   return info;
00233 }
00234 
00235 void
00236 node_info_unref (NodeInfo *info)
00237 {
00238   info->base.refcount -= 1;
00239   if (info->base.refcount == 0)
00240     {
00241       free_interface_list (&info->interfaces);
00242       free_node_list (&info->nodes);
00243       base_info_free (info);
00244     }
00245 }
00246 
00247 const char*
00248 node_info_get_name (NodeInfo *info)
00249 {
00250   return info->base.name;
00251 }
00252 
00253 GSList*
00254 node_info_get_interfaces (NodeInfo *info)
00255 {
00256   return info->interfaces;
00257 }
00258 
00259 void
00260 node_info_add_interface (NodeInfo *info,
00261                          InterfaceInfo    *interface)
00262 {
00263   interface_info_ref (interface);
00264   info->interfaces = g_slist_append (info->interfaces, interface);
00265 }
00266 
00267 GSList*
00268 node_info_get_nodes (NodeInfo *info)
00269 {
00270   return info->nodes;
00271 }
00272 
00273 void
00274 node_info_add_node (NodeInfo *info,
00275                     NodeInfo *node)
00276 {
00277   node_info_ref (node);
00278   info->nodes = g_slist_append (info->nodes, node);
00279 }
00280 
00281 InterfaceInfo*
00282 interface_info_new (const char *name)
00283 {
00284   InterfaceInfo *info;
00285 
00286   info = g_new0 (InterfaceInfo, 1);
00287   info->base.refcount = 1;
00288   info->base.name = g_strdup (name);
00289   info->base.type = INFO_TYPE_INTERFACE;
00290   
00291   return info;
00292 }
00293 
00294 InterfaceInfo *
00295 interface_info_ref (InterfaceInfo *info)
00296 {
00297   info->base.refcount += 1;
00298 
00299   return info;
00300 }
00301 
00302 void
00303 interface_info_unref (InterfaceInfo *info)
00304 {
00305   info->base.refcount -= 1;
00306   if (info->base.refcount == 0)
00307     {
00308       free_method_list (&info->methods);
00309       free_signal_list (&info->signals);
00310       base_info_free (info);
00311     }
00312 }
00313 
00314 const char*
00315 interface_info_get_name (InterfaceInfo *info)
00316 {
00317   return info->base.name;
00318 }
00319 
00320 GSList*
00321 interface_info_get_methods (InterfaceInfo *info)
00322 {
00323   return info->methods;
00324 }
00325 
00326 GSList*
00327 interface_info_get_signals (InterfaceInfo *info)
00328 {
00329   return info->signals;
00330 }
00331 
00332 void
00333 interface_info_add_method (InterfaceInfo *info,
00334                            MethodInfo    *method)
00335 {
00336   method_info_ref (method);
00337   info->methods = g_slist_append (info->methods, method);
00338 }
00339 
00340 void
00341 interface_info_add_signal (InterfaceInfo *info,
00342                            SignalInfo    *signal)
00343 {
00344   signal_info_ref (signal);
00345   info->signals = g_slist_append (info->signals, signal);
00346 }
00347 
00348 static void
00349 free_arg_list (GSList **args_p)
00350 {
00351   GSList *tmp;
00352   tmp = *args_p;
00353   while (tmp != NULL)
00354     {
00355       arg_info_unref (tmp->data);
00356       tmp = tmp->next;
00357     }
00358   g_slist_free (*args_p);
00359   *args_p = NULL;
00360 }
00361 
00362 MethodInfo*
00363 method_info_new (const char *name)
00364 {
00365   MethodInfo *info;
00366 
00367   info = g_new0 (MethodInfo, 1);
00368   info->base.refcount = 1;
00369   info->base.name = g_strdup (name);
00370   info->base.type = INFO_TYPE_METHOD;
00371   
00372   return info;
00373 }
00374 
00375 MethodInfo *
00376 method_info_ref (MethodInfo *info)
00377 {
00378   info->base.refcount += 1;
00379 
00380   return info;
00381 }
00382 
00383 void
00384 method_info_unref (MethodInfo *info)
00385 {
00386   info->base.refcount -= 1;
00387   if (info->base.refcount == 0)
00388     {
00389       free_arg_list (&info->args);
00390       base_info_free (info);
00391     }
00392 }
00393 
00394 const char*
00395 method_info_get_name (MethodInfo *info)
00396 {
00397   return info->base.name;
00398 }
00399 
00400 GSList*
00401 method_info_get_args (MethodInfo *info)
00402 {
00403   return info->args;
00404 }
00405 
00406 static int
00407 args_sort_by_direction (const void *a,
00408                         const void *b)
00409 {
00410   const ArgInfo *arg_a = a;
00411   const ArgInfo *arg_b = b;
00412 
00413   if (arg_a->direction == arg_b->direction)
00414     return 0;
00415   else if (arg_a->direction == ARG_IN)
00416     return -1; /* in is less than out */
00417   else
00418     return 1;
00419 }                  
00420 
00421 void
00422 method_info_add_arg (MethodInfo    *info,
00423                      ArgInfo       *arg)
00424 {
00425   arg_info_ref (arg);
00426   info->args = g_slist_append (info->args, arg);
00427 
00428   /* Keep "in" args sorted before "out" and otherwise maintain
00429    * stable order (g_slist_sort is stable, at least in sufficiently
00430    * new glib)
00431    */
00432   info->args = g_slist_sort (info->args, args_sort_by_direction);
00433 }
00434 
00435 SignalInfo*
00436 signal_info_new (const char *name)
00437 {
00438   SignalInfo *info;
00439 
00440   info = g_new0 (SignalInfo, 1);
00441   info->base.refcount = 1;
00442   info->base.name = g_strdup (name);
00443   info->base.type = INFO_TYPE_SIGNAL;
00444   
00445   return info;
00446 }
00447 
00448 SignalInfo *
00449 signal_info_ref (SignalInfo *info)
00450 {
00451   info->base.refcount += 1;
00452 
00453   return info;
00454 }
00455 
00456 void
00457 signal_info_unref (SignalInfo *info)
00458 {
00459   info->base.refcount -= 1;
00460   if (info->base.refcount == 0)
00461     {
00462       free_arg_list (&info->args);
00463       base_info_free (info);
00464     }
00465 }
00466 
00467 const char*
00468 signal_info_get_name (SignalInfo *info)
00469 {
00470   return info->base.name;
00471 }
00472 
00473 GSList*
00474 signal_info_get_args (SignalInfo *info)
00475 {
00476   return info->args;
00477 }
00478 
00479 void
00480 signal_info_add_arg (SignalInfo    *info,
00481                      ArgInfo       *arg)
00482 {
00483   g_assert (arg->direction == ARG_OUT);
00484   
00485   arg_info_ref (arg);
00486   info->args = g_slist_append (info->args, arg);
00487 
00488   /* signal args don't need sorting since only "out" is allowed */
00489 }
00490 
00491 ArgInfo*
00492 arg_info_new (const char  *name,
00493               ArgDirection direction,
00494               int          type)
00495 {
00496   ArgInfo *info;
00497 
00498   info = g_new0 (ArgInfo, 1);
00499   info->base.refcount = 1;
00500   info->base.type = INFO_TYPE_ARG;
00501   
00502   /* name can be NULL */
00503   info->base.name = g_strdup (name);
00504   info->direction = direction;
00505   info->type = type;
00506 
00507   return info;
00508 }
00509 
00510 ArgInfo *
00511 arg_info_ref (ArgInfo *info)
00512 {
00513   info->base.refcount += 1;
00514 
00515   return info;
00516 }
00517 
00518 void
00519 arg_info_unref (ArgInfo *info)
00520 {
00521   info->base.refcount -= 1;
00522   if (info->base.refcount == 0)
00523     {
00524       base_info_free (info);
00525     }
00526 }
00527 const char*
00528 arg_info_get_name (ArgInfo *info)
00529 {
00530   return info->base.name;
00531 }
00532 
00533 int
00534 arg_info_get_type (ArgInfo *info)
00535 {
00536   return info->type;
00537 }
00538 
00539 ArgDirection
00540 arg_info_get_direction (ArgInfo *info)
00541 {
00542   return info->direction;
00543 }
00544 
00545 #ifdef DBUS_BUILD_TESTS
00546 
00552 dbus_bool_t
00553 _dbus_gidl_test (void)
00554 {
00555 
00556   return TRUE;
00557 }
00558 
00559 #endif /* DBUS_BUILD_TESTS */
00560 
00561 #endif /* DOXYGEN_SHOULD_SKIP_THIS */

Generated on Wed Jun 9 05:01:25 2004 for D-BUS by doxygen1.2.15