00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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 GHashTable *annotations;
00047
00048 GSList *methods;
00049 GSList *signals;
00050 GSList *properties;
00051 };
00052
00053 struct MethodInfo
00054 {
00055 BaseInfo base;
00056 GHashTable *annotations;
00057 GSList *args;
00058 };
00059
00060 struct SignalInfo
00061 {
00062 BaseInfo base;
00063 GSList *args;
00064 };
00065
00066 struct PropertyInfo
00067 {
00068 BaseInfo base;
00069 char *type;
00070 PropertyAccessFlags access;
00071 };
00072
00073 struct ArgInfo
00074 {
00075 BaseInfo base;
00076 char *type;
00077 ArgDirection direction;
00078 GHashTable *annotations;
00079 };
00080
00081 static void
00082 get_hash_key (gpointer key, gpointer value, gpointer data)
00083 {
00084 GSList **list = data;
00085 *list = g_slist_prepend (*list, key);
00086 }
00087
00088 static GSList *
00089 get_hash_keys (GHashTable *table)
00090 {
00091 GSList *ret = NULL;
00092
00093 g_hash_table_foreach (table, get_hash_key, &ret);
00094
00095 return ret;
00096 }
00097
00098 BaseInfo *
00099 base_info_ref (BaseInfo *info)
00100 {
00101 g_return_val_if_fail (info != NULL, NULL);
00102 g_return_val_if_fail (info->refcount > 0, NULL);
00103
00104 info->refcount += 1;
00105
00106 return info;
00107 }
00108
00109 static void
00110 base_info_free (void *ptr)
00111 {
00112 BaseInfo *info;
00113
00114 info = ptr;
00115
00116 g_free (info->name);
00117 g_free (info);
00118 }
00119
00120 void
00121 base_info_unref (BaseInfo *info)
00122 {
00123 g_return_if_fail (info != NULL);
00124 g_return_if_fail (info->refcount > 0);
00125
00126
00127
00128 switch (info->type)
00129 {
00130 case INFO_TYPE_NODE:
00131 node_info_unref ((NodeInfo*) info);
00132 break;
00133 case INFO_TYPE_INTERFACE:
00134 interface_info_unref ((InterfaceInfo*) info);
00135 break;
00136 case INFO_TYPE_SIGNAL:
00137 signal_info_unref ((SignalInfo*) info);
00138 break;
00139 case INFO_TYPE_METHOD:
00140 method_info_unref ((MethodInfo*) info);
00141 break;
00142 case INFO_TYPE_PROPERTY:
00143 property_info_unref ((PropertyInfo*) info);
00144 break;
00145 case INFO_TYPE_ARG:
00146 arg_info_unref ((ArgInfo*) info);
00147 break;
00148 }
00149 }
00150
00151 InfoType
00152 base_info_get_type (BaseInfo *info)
00153 {
00154 return info->type;
00155 }
00156
00157 const char*
00158 base_info_get_name (BaseInfo *info)
00159 {
00160 return info->name;
00161 }
00162
00163 void
00164 base_info_set_name (BaseInfo *info,
00165 const char *name)
00166 {
00167 char *old;
00168
00169 old = info->name;
00170 info->name = g_strdup (name);
00171 g_free (old);
00172 }
00173
00174 GType
00175 base_info_get_gtype (void)
00176 {
00177 static GType our_type = 0;
00178
00179 if (our_type == 0)
00180 our_type = g_boxed_type_register_static ("BaseInfo",
00181 (GBoxedCopyFunc) base_info_ref,
00182 (GBoxedFreeFunc) base_info_unref);
00183
00184 return our_type;
00185 }
00186
00187 static void
00188 free_interface_list (GSList **interfaces_p)
00189 {
00190 GSList *tmp;
00191 tmp = *interfaces_p;
00192 while (tmp != NULL)
00193 {
00194 interface_info_unref (tmp->data);
00195 tmp = tmp->next;
00196 }
00197 g_slist_free (*interfaces_p);
00198 *interfaces_p = NULL;
00199 }
00200
00201 static void
00202 free_node_list (GSList **nodes_p)
00203 {
00204 GSList *tmp;
00205 tmp = *nodes_p;
00206 while (tmp != NULL)
00207 {
00208 node_info_unref (tmp->data);
00209 tmp = tmp->next;
00210 }
00211 g_slist_free (*nodes_p);
00212 *nodes_p = NULL;
00213 }
00214
00215 static void
00216 free_method_list (GSList **methods_p)
00217 {
00218 GSList *tmp;
00219 tmp = *methods_p;
00220 while (tmp != NULL)
00221 {
00222 method_info_unref (tmp->data);
00223 tmp = tmp->next;
00224 }
00225 g_slist_free (*methods_p);
00226 *methods_p = NULL;
00227 }
00228
00229 static void
00230 free_signal_list (GSList **signals_p)
00231 {
00232 GSList *tmp;
00233 tmp = *signals_p;
00234 while (tmp != NULL)
00235 {
00236 signal_info_unref (tmp->data);
00237 tmp = tmp->next;
00238 }
00239 g_slist_free (*signals_p);
00240 *signals_p = NULL;
00241 }
00242
00243 static void
00244 free_property_list (GSList **props_p)
00245 {
00246 GSList *tmp;
00247 tmp = *props_p;
00248 while (tmp != NULL)
00249 {
00250 property_info_unref (tmp->data);
00251 tmp = tmp->next;
00252 }
00253 g_slist_free (*props_p);
00254 *props_p = NULL;
00255 }
00256
00257 NodeInfo*
00258 node_info_new (const char *name)
00259 {
00260 NodeInfo *info;
00261
00262
00263
00264 info = g_new0 (NodeInfo, 1);
00265 info->base.refcount = 1;
00266 info->base.name = g_strdup (name);
00267 info->base.type = INFO_TYPE_NODE;
00268
00269 return info;
00270 }
00271
00272 NodeInfo *
00273 node_info_ref (NodeInfo *info)
00274 {
00275 info->base.refcount += 1;
00276
00277 return info;
00278 }
00279
00280 void
00281 node_info_unref (NodeInfo *info)
00282 {
00283 info->base.refcount -= 1;
00284 if (info->base.refcount == 0)
00285 {
00286 free_interface_list (&info->interfaces);
00287 free_node_list (&info->nodes);
00288 base_info_free (info);
00289 }
00290 }
00291
00292 const char*
00293 node_info_get_name (NodeInfo *info)
00294 {
00295 return info->base.name;
00296 }
00297
00298 GSList*
00299 node_info_get_interfaces (NodeInfo *info)
00300 {
00301 return info->interfaces;
00302 }
00303
00304 void
00305 node_info_add_interface (NodeInfo *info,
00306 InterfaceInfo *interface)
00307 {
00308 interface_info_ref (interface);
00309 info->interfaces = g_slist_append (info->interfaces, interface);
00310 }
00311
00312 GSList*
00313 node_info_get_nodes (NodeInfo *info)
00314 {
00315 return info->nodes;
00316 }
00317
00318 void
00319 node_info_add_node (NodeInfo *info,
00320 NodeInfo *node)
00321 {
00322 node_info_ref (node);
00323 info->nodes = g_slist_append (info->nodes, node);
00324 }
00325
00326 void
00327 node_info_replace_node (NodeInfo *info,
00328 NodeInfo *old_child,
00329 NodeInfo *new_child)
00330 {
00331 GSList *link;
00332
00333 node_info_ref (new_child);
00334 link = g_slist_find (info->nodes, old_child);
00335 g_assert (link != NULL);
00336 node_info_unref (old_child);
00337 link->data = new_child;
00338 }
00339
00340 InterfaceInfo*
00341 interface_info_new (const char *name)
00342 {
00343 InterfaceInfo *info;
00344
00345 info = g_new0 (InterfaceInfo, 1);
00346 info->base.refcount = 1;
00347 info->base.name = g_strdup (name);
00348 info->base.type = INFO_TYPE_INTERFACE;
00349 info->annotations = g_hash_table_new_full (g_str_hash, g_str_equal,
00350 (GDestroyNotify) g_free,
00351 (GDestroyNotify) g_free);
00352
00353 return info;
00354 }
00355
00356 InterfaceInfo *
00357 interface_info_ref (InterfaceInfo *info)
00358 {
00359 info->base.refcount += 1;
00360
00361 return info;
00362 }
00363
00364 void
00365 interface_info_unref (InterfaceInfo *info)
00366 {
00367 info->base.refcount -= 1;
00368 if (info->base.refcount == 0)
00369 {
00370 g_hash_table_destroy (info->annotations);
00371 free_method_list (&info->methods);
00372 free_signal_list (&info->signals);
00373 free_property_list (&info->properties);
00374 base_info_free (info);
00375 }
00376 }
00377
00378 const char*
00379 interface_info_get_name (InterfaceInfo *info)
00380 {
00381 return info->base.name;
00382 }
00383
00384 GSList *
00385 interface_info_get_annotations (InterfaceInfo *info)
00386 {
00387 return get_hash_keys (info->annotations);
00388 }
00389
00390 const char*
00391 interface_info_get_annotation (InterfaceInfo *info,
00392 const char *name)
00393 {
00394 return g_hash_table_lookup (info->annotations, name);
00395 }
00396
00397 GSList*
00398 interface_info_get_methods (InterfaceInfo *info)
00399 {
00400 return info->methods;
00401 }
00402
00403 GSList*
00404 interface_info_get_signals (InterfaceInfo *info)
00405 {
00406 return info->signals;
00407 }
00408
00409 GSList*
00410 interface_info_get_properties (InterfaceInfo *info)
00411 {
00412 return info->properties;
00413 }
00414
00415 void
00416 interface_info_add_annotation (InterfaceInfo *info,
00417 const char *name,
00418 const char *value)
00419 {
00420 g_hash_table_insert (info->annotations,
00421 g_strdup (name),
00422 g_strdup (value));
00423 }
00424
00425 void
00426 interface_info_add_method (InterfaceInfo *info,
00427 MethodInfo *method)
00428 {
00429 method_info_ref (method);
00430 info->methods = g_slist_append (info->methods, method);
00431 }
00432
00433 void
00434 interface_info_add_signal (InterfaceInfo *info,
00435 SignalInfo *signal)
00436 {
00437 signal_info_ref (signal);
00438 info->signals = g_slist_append (info->signals, signal);
00439 }
00440
00441 void
00442 interface_info_add_property (InterfaceInfo *info,
00443 PropertyInfo *property)
00444 {
00445 property_info_ref (property);
00446 info->properties = g_slist_append (info->properties, property);
00447 }
00448
00449 static void
00450 free_arg_list (GSList **args_p)
00451 {
00452 GSList *tmp;
00453 tmp = *args_p;
00454 while (tmp != NULL)
00455 {
00456 ArgInfo *ai = tmp->data;
00457 g_assert (ai->base.type == INFO_TYPE_ARG);
00458 arg_info_unref (tmp->data);
00459 tmp = tmp->next;
00460 }
00461 g_slist_free (*args_p);
00462 *args_p = NULL;
00463 }
00464
00465 MethodInfo*
00466 method_info_new (const char *name)
00467 {
00468 MethodInfo *info;
00469
00470 info = g_new0 (MethodInfo, 1);
00471 info->base.refcount = 1;
00472 info->base.name = g_strdup (name);
00473 info->base.type = INFO_TYPE_METHOD;
00474 info->annotations = g_hash_table_new_full (g_str_hash, g_str_equal,
00475 (GDestroyNotify) g_free,
00476 (GDestroyNotify) g_free);
00477
00478 return info;
00479 }
00480
00481 MethodInfo *
00482 method_info_ref (MethodInfo *info)
00483 {
00484 info->base.refcount += 1;
00485
00486 return info;
00487 }
00488
00489 void
00490 method_info_unref (MethodInfo *info)
00491 {
00492 info->base.refcount -= 1;
00493 if (info->base.refcount == 0)
00494 {
00495 g_hash_table_destroy (info->annotations);
00496 free_arg_list (&info->args);
00497 base_info_free (info);
00498 }
00499 }
00500
00501 const char*
00502 method_info_get_name (MethodInfo *info)
00503 {
00504 return info->base.name;
00505 }
00506
00507 GSList *
00508 method_info_get_annotations (MethodInfo *info)
00509 {
00510 return get_hash_keys (info->annotations);
00511 }
00512
00513 const char*
00514 method_info_get_annotation (MethodInfo *info,
00515 const char *name)
00516 {
00517 return g_hash_table_lookup (info->annotations, name);
00518 }
00519
00520 GSList*
00521 method_info_get_args (MethodInfo *info)
00522 {
00523 return info->args;
00524 }
00525
00526 int
00527 method_info_get_n_args (MethodInfo *info)
00528 {
00529 return g_slist_length (info->args);
00530 }
00531
00532 static int
00533 args_sort_by_direction (const void *a,
00534 const void *b)
00535 {
00536 const ArgInfo *arg_a = a;
00537 const ArgInfo *arg_b = b;
00538
00539 if (arg_a->direction == arg_b->direction)
00540 return 0;
00541 else if (arg_a->direction == ARG_IN)
00542 return -1;
00543 else
00544 return 1;
00545 }
00546
00547 void
00548 method_info_add_annotation (MethodInfo *info,
00549 const char *name,
00550 const char *value)
00551 {
00552 g_hash_table_insert (info->annotations,
00553 g_strdup (name),
00554 g_strdup (value));
00555 }
00556
00557 void
00558 method_info_add_arg (MethodInfo *info,
00559 ArgInfo *arg)
00560 {
00561 arg_info_ref (arg);
00562 info->args = g_slist_append (info->args, arg);
00563
00564
00565
00566
00567
00568 info->args = g_slist_sort (info->args, args_sort_by_direction);
00569 }
00570
00571 SignalInfo*
00572 signal_info_new (const char *name)
00573 {
00574 SignalInfo *info;
00575
00576 info = g_new0 (SignalInfo, 1);
00577 info->base.refcount = 1;
00578 info->base.name = g_strdup (name);
00579 info->base.type = INFO_TYPE_SIGNAL;
00580
00581 return info;
00582 }
00583
00584 SignalInfo *
00585 signal_info_ref (SignalInfo *info)
00586 {
00587 info->base.refcount += 1;
00588
00589 return info;
00590 }
00591
00592 void
00593 signal_info_unref (SignalInfo *info)
00594 {
00595 info->base.refcount -= 1;
00596 if (info->base.refcount == 0)
00597 {
00598 free_arg_list (&info->args);
00599 base_info_free (info);
00600 }
00601 }
00602
00603 const char*
00604 signal_info_get_name (SignalInfo *info)
00605 {
00606 return info->base.name;
00607 }
00608
00609 GSList*
00610 signal_info_get_args (SignalInfo *info)
00611 {
00612 return info->args;
00613 }
00614
00615 int
00616 signal_info_get_n_args (SignalInfo *info)
00617 {
00618 return g_slist_length (info->args);
00619 }
00620
00621 void
00622 signal_info_add_arg (SignalInfo *info,
00623 ArgInfo *arg)
00624 {
00625 g_assert (arg->direction == ARG_OUT);
00626
00627 arg_info_ref (arg);
00628 info->args = g_slist_append (info->args, arg);
00629
00630
00631 }
00632
00633 PropertyInfo*
00634 property_info_new (const char *name,
00635 const char *type,
00636 PropertyAccessFlags access)
00637 {
00638 PropertyInfo *info;
00639
00640 info = g_new0 (PropertyInfo, 1);
00641 info->base.refcount = 1;
00642 info->base.name = g_strdup (name);
00643 info->base.type = INFO_TYPE_PROPERTY;
00644
00645 info->type = g_strdup (type);
00646 info->access = access;
00647
00648 return info;
00649 }
00650
00651 PropertyInfo*
00652 property_info_ref (PropertyInfo *info)
00653 {
00654 info->base.refcount += 1;
00655
00656 return info;
00657 }
00658
00659 void
00660 property_info_unref (PropertyInfo *info)
00661 {
00662 info->base.refcount -= 1;
00663 if (info->base.refcount == 0)
00664 {
00665 g_free (info->type);
00666 base_info_free (info);
00667 }
00668 }
00669
00670 const char*
00671 property_info_get_name (PropertyInfo *info)
00672 {
00673 return info->base.name;
00674 }
00675
00676 const char *
00677 property_info_get_type (PropertyInfo *info)
00678 {
00679 return info->type;
00680 }
00681
00682 PropertyAccessFlags
00683 property_info_get_access (PropertyInfo *info)
00684 {
00685 return info->access;
00686 }
00687
00688 ArgInfo*
00689 arg_info_new (const char *name,
00690 ArgDirection direction,
00691 const char *type)
00692 {
00693 ArgInfo *info;
00694
00695 info = g_new0 (ArgInfo, 1);
00696 info->base.refcount = 1;
00697 info->base.type = INFO_TYPE_ARG;
00698
00699
00700 info->base.name = g_strdup (name);
00701 info->direction = direction;
00702 info->type = g_strdup (type);
00703 info->annotations = g_hash_table_new_full (g_str_hash, g_str_equal,
00704 (GDestroyNotify) g_free,
00705 (GDestroyNotify) g_free);
00706
00707 return info;
00708 }
00709
00710 ArgInfo *
00711 arg_info_ref (ArgInfo *info)
00712 {
00713 info->base.refcount += 1;
00714
00715 return info;
00716 }
00717
00718 void
00719 arg_info_unref (ArgInfo *info)
00720 {
00721 info->base.refcount -= 1;
00722 if (info->base.refcount == 0)
00723 {
00724 g_hash_table_destroy (info->annotations);
00725 g_free (info->type);
00726 base_info_free (info);
00727 }
00728 }
00729
00730 const char*
00731 arg_info_get_name (ArgInfo *info)
00732 {
00733 return info->base.name;
00734 }
00735
00736 const char *
00737 arg_info_get_type (ArgInfo *info)
00738 {
00739 return info->type;
00740 }
00741
00742 ArgDirection
00743 arg_info_get_direction (ArgInfo *info)
00744 {
00745 return info->direction;
00746 }
00747
00748 GSList*
00749 arg_info_get_annotations (ArgInfo *info)
00750 {
00751 return get_hash_keys (info->annotations);
00752 }
00753
00754 const char*
00755 arg_info_get_annotation (ArgInfo *info,
00756 const char *annotation)
00757 {
00758 return g_hash_table_lookup (info->annotations, annotation);
00759 }
00760
00761 void
00762 arg_info_add_annotation (ArgInfo *info,
00763 const char *name,
00764 const char *value)
00765 {
00766 g_hash_table_insert (info->annotations,
00767 g_strdup (name),
00768 g_strdup (value));
00769 }
00770
00771
00772 #ifdef DBUS_BUILD_TESTS
00773
00779 gboolean
00780 _dbus_gidl_test (void)
00781 {
00782
00783 return TRUE;
00784 }
00785
00786 #endif
00787
00788 #endif