Main Page | Data Structures | File List | Data Fields | Globals

object.c

Go to the documentation of this file.
00001 /**
00002  * This file is part of alarmd
00003  *
00004  * Contact Person: David Weinehall <david.weinehall@nokia.com>
00005  *
00006  * Copyright (C) 2006 Nokia Corporation
00007  * alarmd and libalarm are free software; you can redistribute them
00008  * and/or modify them under the terms of the GNU Lesser General Public
00009  * License version 2.1 as published by the Free Software Foundation.
00010  *
00011  * alarmd and libalarm are distributed in the hope that they will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this software; if not, write to the Free
00018  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00019  * 02110-1301 USA
00020  */
00021 
00022 #include <stdarg.h>
00023 #include "object.h"
00024 #include "xml-common.h"
00025 #include "debug.h"
00026 
00027 static void alarmd_object_class_init(AlarmdObjectClass *klass);
00028 static GParameter *_alarmd_object_real_get_properties(AlarmdObject *object, guint *n_objects);
00029 static void _alarmd_object_real_changed(AlarmdObject *object);
00030 static xmlNode *_alarmd_object_real_to_xml(AlarmdObject *object);
00031 static void _alarmd_object_real_to_dbus(AlarmdObject *object, DBusMessageIter *iter);
00032 static GSList *_alarmd_object_real_get_saved_properties(void);
00033 static void _alarmd_object_real_time_changed(AlarmdObject *object);
00034 
00035 struct signal_closure {
00036         AlarmdObject *object;
00037         guint signal;
00038         va_list var_args;
00039 };
00040 
00041 enum signals {
00042         SIGNAL_CHANGED,
00043         SIGNAL_TIME_CHANGED,
00044         SIGNAL_COUNT
00045 };
00046 
00047 static guint object_signals[SIGNAL_COUNT];
00048 
00049 GType alarmd_object_get_type(void)
00050 {
00051         static GType object_type = 0;
00052 
00053         if (!object_type)
00054         {
00055                 static const GTypeInfo object_info =
00056                 {
00057                         sizeof (AlarmdObjectClass),
00058                         NULL,
00059                         NULL,
00060                         (GClassInitFunc) alarmd_object_class_init,
00061                         NULL,
00062                         NULL,
00063                         sizeof (AlarmdObject),
00064                         0,
00065                         NULL,
00066                         NULL
00067                 };
00068 
00069                 object_type = g_type_register_static(G_TYPE_OBJECT,
00070                                 "AlarmdObject",
00071                                 &object_info, 0);
00072         }
00073 
00074         return object_type;
00075 }
00076 
00077 GParameter *alarmd_object_get_properties(AlarmdObject *object, guint *n_objects)
00078 {
00079         GParameter *params = NULL;
00080         GParamSpec *spec = NULL;
00081         guint i;
00082         guint count;
00083         GSList *list;
00084         ENTER_FUNC;
00085 
00086         list = alarmd_object_get_saved_properties(object);
00087         count = g_slist_length(list);
00088         params = g_new0(GParameter, count);
00089 
00090         for (i = 0; i < count; i++) {
00091                 const gchar *name = (const gchar *)list->data;
00092                 params[i].name = name;
00093                 spec = g_object_class_find_property(G_OBJECT_GET_CLASS(object), name);
00094                 if (g_type_is_a(spec->value_type, G_TYPE_OBJECT)) {
00095                         g_value_init(&params[i].value, G_TYPE_OBJECT);
00096                 } else {
00097                         g_value_init(&params[i].value, spec->value_type);
00098                 }
00099                 g_object_get_property(G_OBJECT(object), name, &params[i].value);
00100                 list = g_slist_delete_link(list, list);
00101         }
00102 
00103         *n_objects = count;
00104         LEAVE_FUNC;
00105         return params;
00106 }
00107 
00108 GSList *alarmd_object_get_saved_properties(AlarmdObject *object)
00109 {
00110         GSList *retval = NULL;
00111         ENTER_FUNC;
00112         retval = ALARMD_OBJECT_GET_CLASS(object)->get_saved_properties();
00113         LEAVE_FUNC;
00114         return retval;
00115 }
00116 
00117 void alarmd_gparameterv_free(GParameter *paramv, guint n_objects)
00118 {
00119         ENTER_FUNC;
00120         guint i;
00121         if (n_objects == 0 || paramv == NULL) {
00122                 LEAVE_FUNC;
00123                 return;
00124         }
00125 
00126         for (i = 0; i < n_objects; i++) {
00127                 g_value_unset(&paramv[i].value);
00128         }
00129 
00130         g_free(paramv);
00131         LEAVE_FUNC;
00132 }
00133 
00134 xmlNode *alarmd_object_to_xml(AlarmdObject *object)
00135 {
00136         xmlNode *retval;
00137         ENTER_FUNC;
00138         retval = ALARMD_OBJECT_GET_CLASS(object)->to_xml(object);
00139         LEAVE_FUNC;
00140         return retval;
00141 }
00142 
00143 void alarmd_object_changed(AlarmdObject *object)
00144 {
00145         ENTER_FUNC;
00146         g_signal_emit(object, object_signals[SIGNAL_CHANGED], 0);
00147         LEAVE_FUNC;
00148 }
00149 
00150 void alarmd_object_to_dbus(AlarmdObject *object, DBusMessageIter *iter)
00151 {
00152         ENTER_FUNC;
00153         ALARMD_OBJECT_GET_CLASS(object)->to_dbus(object, iter);
00154         LEAVE_FUNC;
00155 }
00156 
00157 void alarmd_object_time_changed(AlarmdObject *queue)
00158 {
00159         ENTER_FUNC;
00160         g_signal_emit(ALARMD_OBJECT(queue), object_signals[SIGNAL_TIME_CHANGED], 0);
00161         LEAVE_FUNC;
00162 }
00163 
00164 static void alarmd_object_class_init(AlarmdObjectClass *klass)
00165 {
00166         ENTER_FUNC;
00167         klass->changed = _alarmd_object_real_changed;
00168         klass->get_properties = _alarmd_object_real_get_properties;
00169         klass->get_saved_properties = _alarmd_object_real_get_saved_properties;
00170         klass->to_xml = _alarmd_object_real_to_xml;
00171         klass->to_dbus = _alarmd_object_real_to_dbus;
00172         klass->time_changed = _alarmd_object_real_time_changed;
00173 
00174         object_signals[SIGNAL_CHANGED] = g_signal_new("changed",
00175                         G_TYPE_FROM_CLASS(klass),
00176                         G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
00177                         G_STRUCT_OFFSET(AlarmdObjectClass, changed),
00178                         NULL, NULL,
00179                         g_cclosure_marshal_VOID__VOID,
00180                         G_TYPE_NONE, 0);
00181         object_signals[SIGNAL_TIME_CHANGED] = g_signal_new("time_changed",
00182                         G_TYPE_FROM_CLASS(klass),
00183                         G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
00184                         G_STRUCT_OFFSET(AlarmdObjectClass, time_changed),
00185                         NULL, NULL,
00186                         g_cclosure_marshal_VOID__VOID,
00187                         G_TYPE_NONE, 0);
00188         LEAVE_FUNC;
00189 }
00190 
00191 static GParameter *_alarmd_object_real_get_properties(AlarmdObject *object, guint *n_objects)
00192 {
00193         ENTER_FUNC;
00194         (void)object;
00195 
00196         *n_objects = 0;
00197         
00198         LEAVE_FUNC;
00199         return NULL;
00200 }
00201 
00202 static void _alarmd_object_real_to_dbus(AlarmdObject *object, DBusMessageIter *iter)
00203 {
00204         GParameter *properties = NULL;
00205         guint n_props = 0;
00206         guint i;
00207         gchar *temp = NULL;
00208         ENTER_FUNC;
00209 
00210         temp = g_strdup_printf("/%s", G_OBJECT_TYPE_NAME(object));
00211         dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &temp);
00212         g_free(temp);
00213         properties = alarmd_object_get_properties(object, &n_props);
00214         dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &n_props);
00215         for (i = 0; i < n_props; i++) {
00216                 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &properties[i].name);
00217                 switch (G_VALUE_TYPE(&properties[i].value)) {
00218                 case G_TYPE_CHAR:
00219                         {
00220                                 gchar value = g_value_get_char(&properties[i].value);
00221                                 dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &value);
00222                                 break;
00223                         }
00224                 case G_TYPE_BOOLEAN:
00225                         {
00226                                 dbus_bool_t value = g_value_get_boolean(&properties[i].value);
00227                                 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
00228                                 break;
00229                         }
00230                 case G_TYPE_LONG:
00231                         {
00232                                 dbus_int32_t value = g_value_get_long(&properties[i].value);
00233                                 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &value);
00234                                 break;
00235                         }
00236                 case G_TYPE_INT:
00237                         {
00238                                 dbus_int32_t value = g_value_get_int(&properties[i].value);
00239                                 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &value);
00240                                 break;
00241                         }
00242                 case G_TYPE_UINT:
00243                         {
00244                                 dbus_uint32_t value = g_value_get_uint(&properties[i].value);
00245                                 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &value);
00246                                 break;
00247                         }
00248 #ifdef DBUS_HAVE_INT64
00249                 case G_TYPE_INT64:
00250                         {
00251                                 dbus_uint64_t value = g_value_get_int64(&properties[i].value);
00252                                 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT64, &value);
00253                                 break;
00254                         }
00255                 case G_TYPE_UINT64:
00256                         {
00257                                 dbus_uint64_t value = g_value_get_uint64(&properties[i].value);
00258                                 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &value);
00259                                 break;
00260                         }
00261 #endif
00262                 case G_TYPE_DOUBLE:
00263                         {
00264                                 double value = g_value_get_double(&properties[i].value);
00265                                 dbus_message_iter_append_basic(iter, DBUS_TYPE_DOUBLE, &value);
00266                                 break;
00267                         }
00268                 case G_TYPE_STRING:
00269                         {
00270                                 const gchar *value = g_value_get_string(&properties[i].value);
00271                                 if (value == NULL) {
00272                                         value = "";
00273                                 }
00274                                 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &value);
00275                                 break;
00276                         }
00277                 case G_TYPE_OBJECT:
00278                         {
00279                                 GObject *value = g_value_get_object(&properties[i].value);
00280                                 alarmd_object_to_dbus(ALARMD_OBJECT(value), iter);
00281                                 break;
00282                         }
00283                 default:
00284                         {
00285                                 dbus_int32_t value = -1;
00286                                 DEBUG("Unsupported type for %s", properties[i].name);
00287                                 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &value);
00288                                 break;
00289                         }
00290                 }
00291         }
00292 
00293         alarmd_gparameterv_free(properties, n_props);
00294 
00295         LEAVE_FUNC;
00296 }
00297 
00298 static xmlNode *_alarmd_object_real_to_xml(AlarmdObject *object)
00299 {
00300         xmlNode *node;
00301         guint n_properties = 0;
00302         guint i;
00303         GParameter *properties = NULL;
00304 
00305         ENTER_FUNC;
00306         node = xmlNewNode(NULL, "object");
00307         xmlNewProp(node, "type", g_type_name(G_OBJECT_TYPE(object)));
00308 
00309         properties = alarmd_object_get_properties(object, &n_properties);
00310         for (i = 0; i < n_properties; i++) {
00311                 gchar *temp = NULL;
00312                 xmlNode *children = NULL;
00313                 xmlNode *added_node = NULL;
00314                 guint j;
00315 
00316                 switch (G_VALUE_TYPE(&properties[i].value)) {
00317                 case G_TYPE_BOOLEAN:
00318                         temp = g_strdup_printf("%d", g_value_get_boolean(&properties[i].value));
00319                         break;
00320                 case G_TYPE_CHAR:
00321                         temp = g_strdup_printf("%c", g_value_get_char(&properties[i].value));
00322                         break;
00323                 case G_TYPE_DOUBLE:
00324                         temp = g_strdup_printf("%f", g_value_get_double(&properties[i].value));
00325                         break;
00326                 case G_TYPE_FLOAT:
00327                         temp = g_strdup_printf("%f", g_value_get_float(&properties[i].value));
00328                         break;
00329                 case G_TYPE_INT:
00330                         temp = g_strdup_printf("%d", g_value_get_int(&properties[i].value));
00331                         break;
00332                 case G_TYPE_INT64:
00333                         temp = g_strdup_printf("%lld", g_value_get_int64(&properties[i].value));
00334                         break;
00335                 case G_TYPE_LONG:
00336                         temp = g_strdup_printf("%ld", g_value_get_long(&properties[i].value));
00337                         break;
00338                 case G_TYPE_OBJECT:
00339                         temp = NULL;
00340                         if (g_value_get_object(&properties[i].value)) {
00341                                 children = alarmd_object_to_xml(ALARMD_OBJECT(g_value_get_object(&properties[i].value)));
00342                         }
00343                         break;
00344                 case G_TYPE_STRING:
00345                         temp = g_strdup(g_value_get_string(&properties[i].value));
00346                         break;
00347                 case G_TYPE_UCHAR:
00348                         temp = g_strdup_printf("%c", g_value_get_uchar(&properties[i].value));
00349                         break;
00350                 case G_TYPE_UINT:
00351                         temp = g_strdup_printf("%u", g_value_get_uint(&properties[i].value));
00352                         break;
00353                 case G_TYPE_UINT64:
00354                         temp = g_strdup_printf("%llu", g_value_get_uint64(&properties[i].value));
00355                         break;
00356                 case G_TYPE_ULONG:
00357                         temp = g_strdup_printf("%lu", g_value_get_long(&properties[i].value));
00358                         break;
00359                 default:
00360                         temp = NULL;
00361                         g_warning("Unsupported type: %s", g_type_name(G_VALUE_TYPE(&properties[i].value)));
00362                         break;
00363                 }
00364                 added_node = xmlNewChild(node, NULL, "parameter", temp);
00365                 if (temp) {
00366                         g_free(temp);
00367                         temp = NULL;
00368                 }
00369                 if (children) {
00370                         xmlAddChild(added_node, children);
00371                 }
00372                 for (j = 0; j < Y_COUNT; j++) {
00373                         if (G_VALUE_TYPE(&properties[i].value) == type_gtypes[j])
00374                                 break;
00375                 }
00376                 xmlNewProp(added_node, "name", properties[i].name);
00377                 xmlNewProp(added_node, "type", type_names[j]);
00378         }
00379 
00380         alarmd_gparameterv_free(properties, n_properties);
00381 
00382         LEAVE_FUNC;
00383         return node;
00384 }
00385 
00386 static void _alarmd_object_real_changed(AlarmdObject *object)
00387 {
00388         ENTER_FUNC;
00389         (void)object;
00390         LEAVE_FUNC;
00391 }
00392 
00393 static GSList *_alarmd_object_real_get_saved_properties(void)
00394 {
00395         ENTER_FUNC;
00396         LEAVE_FUNC;
00397         return NULL;
00398 }
00399 
00400 static void _alarmd_object_real_time_changed(AlarmdObject *object)
00401 {
00402         ENTER_FUNC;
00403         (void)object;
00404         LEAVE_FUNC;
00405 }

Generated on Thu Dec 21 18:23:30 2006 for Alarmd by  doxygen 1.4.2