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

xmlobjectfactory.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 <glib.h>
00023 #include <glib-object.h>
00024 #include <libxml/tree.h>
00025 #include <string.h>
00026 #include "xmlobjectfactory.h"
00027 #include "xml-common.h"
00028 #include "object.h"
00029 #include "debug.h"
00030 
00031 enum Type {
00032         T_ELEMENT,
00033         T_ATTRIBUTE,
00034         T_TYPE,
00035         T_COUNT
00036 };
00037 
00038 enum Element {
00039         E_OBJECT,
00040         E_PARAMETER,
00041         E_COUNT
00042 };
00043 
00044 enum Attributes {
00045         A_TYPE,
00046         A_NAME,
00047         A_COUNT
00048 };
00049 
00050 static const char * const element_names[E_COUNT] = {
00051         "object",
00052         "parameter"
00053 };
00054 
00055 static const char * const attribute_names[A_COUNT] = {
00056         "type",
00057         "name"
00058 };
00059 
00060 static const char * const * const names[T_COUNT] = {
00061         element_names,
00062         attribute_names,
00063         type_names
00064 };
00065 
00066 static const unsigned int counts[T_COUNT] = {
00067         E_COUNT,
00068         A_COUNT,
00069         Y_COUNT
00070 };
00071 
00072 static int get_id(enum Type type, const unsigned char * const name) {
00073         guint i = 0;
00074         ENTER_FUNC;
00075 
00076         if (name == NULL) {
00077                 LEAVE_FUNC;
00078                 return counts[type];
00079         }
00080 
00081         for (i = 0; i < counts[type]; i++) {
00082                 if (strcmp((gchar *)name, (gchar *)names[type][i]) == 0) {
00083                         break;
00084                 }
00085         }
00086 
00087         LEAVE_FUNC;
00088         return i;
00089 }
00090 
00091 static gchar *get_element_text(xmlNode *node) {
00092         ENTER_FUNC;
00093         for (; node; node = node->next) {
00094                 if (node->type == XML_TEXT_NODE) {
00095                         LEAVE_FUNC;
00096                         return (gchar *)node->content;
00097                 } else {
00098                         g_warning("Element should only have text children %d.", node->type);
00099                 }
00100         }
00101         LEAVE_FUNC;
00102         return NULL;
00103 }
00104 
00105 GParameter *elements_to_parameters(xmlNode *object_node, guint *n_params)
00106 {
00107         xmlNode *cur_node;
00108         GSList *properties = NULL;
00109         GParameter *param;
00110         guint i;
00111 
00112         for (cur_node = object_node->children; cur_node != NULL; cur_node = cur_node->next) {
00113                 if (cur_node->type == XML_ELEMENT_NODE) {
00114                         guint type_id;
00115                         xmlAttr *iter;
00116                         gchar *temp_type = NULL;
00117                         gchar *temp_name = NULL;
00118                         AlarmdObject *temp_object;
00119 
00120                         switch (get_id(T_ELEMENT, cur_node->name)) {
00121                         case E_PARAMETER:
00122                                 for (iter = cur_node->properties; iter != NULL; iter = iter->next) {
00123                                         switch (get_id(T_ATTRIBUTE, iter->name)) {
00124                                         case A_TYPE:
00125                                                 temp_type = get_element_text(iter->children);
00126                                                 break;
00127                                         case A_NAME:
00128                                                 temp_name = get_element_text(iter->children);
00129                                                 break;
00130                                         default:
00131                                                 g_warning("Invalid attribute.");
00132                                                 break;
00133                                         }
00134                                 }
00135                                 if (!temp_type || !temp_name) {
00136                                         temp_type = NULL;
00137                                         temp_name = NULL;
00138                                         break;
00139                                 }
00140                                 type_id = get_id(T_TYPE, temp_type);
00141                                 if (type_id == T_COUNT) {
00142                                         break;
00143                                 }
00144                                 param = g_new0(GParameter, 1);
00145                                 g_value_init(&param->value, type_gtypes[type_id]);
00146                                 param->name = temp_name;
00147                                 switch (type_id) {
00148                                 case Y_BOOLEAN:
00149                                         temp_name = get_element_text(cur_node->children);
00150                                         g_value_set_boolean(&param->value, atoi(temp_name));
00151                                         break;
00152                                 case Y_CHAR:
00153                                         g_value_set_char(&param->value, *get_element_text(cur_node->children));
00154                                         break;
00155                                 case Y_INT:
00156                                         temp_name = get_element_text(cur_node->children);
00157                                         g_value_set_int(&param->value, atoi(temp_name));
00158                                         break;
00159                                 case Y_INT64:
00160                                         temp_name = get_element_text(cur_node->children);
00161                                         g_value_set_int64(&param->value, atoll(temp_name));
00162                                         break;
00163                                 case Y_LONG:
00164                                         temp_name = get_element_text(cur_node->children);
00165                                         g_value_set_long(&param->value, atol(temp_name));
00166                                         break;
00167                                 case Y_OBJECT:
00168                                         temp_object = object_factory(cur_node->children);
00169                                         g_value_set_object(&param->value, temp_object);
00170                                         g_object_unref(temp_object);
00171                                         break;
00172                                 case Y_STRING:
00173                                         g_value_set_string(&param->value, get_element_text(cur_node->children));
00174                                         break;
00175                                 case Y_UCHAR:
00176                                         g_value_set_uchar(&param->value, (guchar)*get_element_text(cur_node->children));
00177                                         break;
00178                                 case Y_UINT:
00179                                         temp_name = get_element_text(cur_node->children);
00180                                         g_value_set_uint(&param->value, strtoul(temp_name, NULL, 10));
00181                                         break;
00182                                 case Y_UINT64:
00183                                         temp_name = get_element_text(cur_node->children);
00184                                         g_value_set_uint64(&param->value, strtoull(temp_name, NULL, 10));
00185                                         break;
00186                                 case Y_ULONG:
00187                                         temp_name = get_element_text(cur_node->children);
00188                                         g_value_set_ulong(&param->value, strtoul(temp_name, NULL, 10));
00189                                         break;
00190                                 }
00191                                 temp_name = NULL;
00192                                 temp_type = NULL;
00193                                 temp_object = NULL;
00194                                 properties = g_slist_append(properties, param);
00195                                 param = NULL;
00196                                 break;
00197                         case E_COUNT:
00198                         default:
00199                                 break;
00200                         }
00201                 }
00202         }
00203         *n_params = g_slist_length(properties);
00204         param = g_new0(GParameter, *n_params);
00205         for (i = 0; i < *n_params; i++) {
00206                 GParameter *temp = (GParameter *)properties->data;
00207                 param[i].name = temp->name;
00208                 g_value_init(&param[i].value, G_VALUE_TYPE(&temp->value));
00209                 g_value_copy(&temp->value, &param[i].value);
00210                 g_value_unset(&temp->value);
00211                 g_free(temp);
00212                 properties = g_slist_delete_link(properties, properties);
00213         }
00214 
00215         return param;
00216 }
00217 
00218 AlarmdObject *object_factory(xmlNode *object_node)
00219 {
00220         xmlAttr *iter = NULL;
00221         gchar *temp_type = NULL;
00222         GType object_type = 0;
00223         GParameter *param = NULL;
00224         AlarmdObject *temp_object = NULL;
00225         guint n_params;
00226 
00227         ENTER_FUNC;
00228 
00229         for (; object_node != NULL && object_node->type != XML_ELEMENT_NODE; object_node = object_node->next);
00230 
00231         if (object_node == NULL) {
00232                 DEBUG("No element node.");
00233                 LEAVE_FUNC;
00234                 return NULL;
00235         }
00236 
00237         if (get_id(T_ELEMENT, object_node->name) != E_OBJECT) {
00238                 DEBUG("Not object element.");
00239                 LEAVE_FUNC;
00240                 return NULL;
00241         }
00242 
00243         for (iter = object_node->properties; iter != NULL; iter = iter->next) {
00244                 switch (get_id(T_ATTRIBUTE, iter->name)) {
00245                 case A_TYPE:
00246                         temp_type = get_element_text(iter->children);
00247                         break;
00248                 default:
00249                         g_warning("Invalid attribute %s for %s", iter->name, object_node->name);
00250                         break;
00251                 }
00252         }
00253         if (temp_type == NULL) {
00254                 DEBUG("No type found.");
00255                 g_warning("No type found.");
00256                 LEAVE_FUNC;
00257                 return NULL;
00258         }
00259 
00260         object_type = g_type_from_name(temp_type);
00261 
00262         param = elements_to_parameters(object_node, &n_params);
00263 
00264         temp_object = g_object_newv(object_type, n_params, param);
00265 
00266         alarmd_gparameterv_free(param, n_params);
00267 
00268         LEAVE_FUNC;
00269         return temp_object;
00270 }

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