00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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(¶ms[i].value, G_TYPE_OBJECT);
00096 } else {
00097 g_value_init(¶ms[i].value, spec->value_type);
00098 }
00099 g_object_get_property(G_OBJECT(object), name, ¶ms[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(¶mv[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 }