00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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(¶m->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(¶m->value, atoi(temp_name));
00151 break;
00152 case Y_CHAR:
00153 g_value_set_char(¶m->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(¶m->value, atoi(temp_name));
00158 break;
00159 case Y_INT64:
00160 temp_name = get_element_text(cur_node->children);
00161 g_value_set_int64(¶m->value, atoll(temp_name));
00162 break;
00163 case Y_LONG:
00164 temp_name = get_element_text(cur_node->children);
00165 g_value_set_long(¶m->value, atol(temp_name));
00166 break;
00167 case Y_OBJECT:
00168 temp_object = object_factory(cur_node->children);
00169 g_value_set_object(¶m->value, temp_object);
00170 g_object_unref(temp_object);
00171 break;
00172 case Y_STRING:
00173 g_value_set_string(¶m->value, get_element_text(cur_node->children));
00174 break;
00175 case Y_UCHAR:
00176 g_value_set_uchar(¶m->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(¶m->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(¶m->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(¶m->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(¶m[i].value, G_VALUE_TYPE(&temp->value));
00209 g_value_copy(&temp->value, ¶m[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 }