Back to index

im-sdk  12.3.91
imbean.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2005 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 
00043 #include <stdio.h>
00044 #include <libxml/xmlmemory.h>
00045 #include <libxml/parser.h>
00046 #include <sys/stat.h>
00047 
00048 #include "imbean.h"
00049 
00050 #define ELEMENT_INITIAL_SIZE      6
00051 
00052 #define IBML_ERR_STR_DEFAULT                     "IBML Parser Error"
00053 #define IBML_ERR_STR_NO_MEMORY                   "IBML Error:  No Memory"
00054 #define IBML_ERR_STR_INVALID_ELEMENT_NAME        "IBML Error:  Invalid Element Name"
00055 #define IBML_ERR_STR_INVALID_ELEMENT_ATTRIBUTE   "IBML Error:  Invalid Element Property"
00056 #define IBML_ERR_STR_INVALID_ELEMENT_ITEM        "IBML Error:  Invalid Element Item"
00057 
00058 enum {
00059     IBML_ERR_OK = 0,
00060     IBML_ERR_NO_MEMORY,
00061     IBML_ERR_INVALID_ELEMENT_NAME,
00062     IBML_ERR_INVALID_ELEMENT_ATTRIBUTE,
00063     IBML_ERR_INVALID_ELEMENT_ITEM,
00064 };
00065 
00066 #define SafeFree(pointer)               if(pointer) free((char *)(pointer))
00067 
00068 static IbmlProperty *ibml_property_new()
00069 {
00070     IbmlProperty *ibml_property;
00071 
00072     ibml_property = (IbmlProperty *) malloc(sizeof(IbmlProperty));
00073     if (ibml_property == NULL)
00074        return NULL;
00075 
00076     ibml_property->name = NULL;
00077     ibml_property->type = NULL;
00078     ibml_property->value = NULL;
00079     ibml_property->options = NULL;
00080     ibml_property->scope = NULL;
00081 
00082     return ibml_property;
00083 }
00084 
00085 static int ibml_property_free(IbmlProperty * ibml_property)
00086 {
00087     if (ibml_property == NULL)
00088        return IBML_OK;
00089 
00090     SafeFree(ibml_property->name);
00091     SafeFree(ibml_property->type);
00092     SafeFree(ibml_property->value);
00093     SafeFree(ibml_property->options);
00094     SafeFree(ibml_property->scope);
00095 
00096     SafeFree(ibml_property);
00097 
00098     return IBML_OK;
00099 }
00100 
00101 static int ibml_property_print(IbmlProperty * ibml_property)
00102 {
00103     char *name;
00104     char *type;
00105     char *value;
00106     char *options;
00107     char *scope;
00108 
00109     if (ibml_property == NULL)
00110        return IBML_OK;
00111 
00112     name = ibml_property->name;
00113     type = ibml_property->type;
00114     value = ibml_property->value;
00115     options = ibml_property->options;
00116     scope = ibml_property->scope;
00117     if (name && value) {
00118        printf("    name: %s, value: %s,  ", name, value);
00119        if (type)
00120            printf("type: %s  ", type);
00121        if (options)
00122            printf("options: %s  ", options);
00123        if (scope)
00124            printf("scope: %s  ", scope);
00125        printf("\n");
00126     }
00127 
00128     return IBML_OK;
00129 }
00130 
00131 static IbmlElement *ibml_element_new()
00132 {
00133     IbmlElement *ibml_element;
00134 
00135     ibml_element = (IbmlElement *) malloc(sizeof(IbmlElement));
00136     if (ibml_element == NULL)
00137        return NULL;
00138 
00139     ibml_element->id = NULL;
00140     ibml_element->scope = NULL;
00141     ibml_element->class = NULL;
00142 
00143     ibml_element->num_properties = 0;
00144     ibml_element->properties = NULL;
00145 
00146     return ibml_element;
00147 }
00148 
00149 static int ibml_element_free(IbmlElement * ibml_element)
00150 {
00151     int i;
00152 
00153     if (ibml_element == NULL)
00154        return IBML_OK;
00155 
00156     SafeFree(ibml_element->id);
00157     SafeFree(ibml_element->scope);
00158     SafeFree(ibml_element->class);
00159 
00160     for (i = 0; i < ibml_element->num_properties; i++)
00161        ibml_property_free(ibml_element->properties[i]);
00162     SafeFree(ibml_element->properties);
00163 
00164     SafeFree(ibml_element);
00165 
00166     return IBML_OK;
00167 }
00168 
00169 static int ibml_element_print(IbmlElement * ibml_element)
00170 {
00171     int i;
00172     char *id;
00173 
00174     if (ibml_element == NULL)
00175        return IBML_OK;
00176 
00177     id = ibml_element->id;
00178     if (id && *id)
00179        printf("  id: %s\n", id);
00180 
00181     for (i = 0; i < ibml_element->num_properties; i++)
00182        ibml_property_print(ibml_element->properties[i]);
00183 
00184     return IBML_OK;
00185 }
00186 
00187 static int ibml_element_pushback_property(IbmlElement * ibml_element,
00188                                           IbmlProperty * ibml_property)
00189 {
00190     int i, num_properties;
00191 
00192     if (ibml_element == NULL || ibml_property == NULL)
00193         return IBML_ERROR;
00194 
00195     if (ibml_element->properties == NULL) {
00196         ibml_element->properties = (IbmlProperty **) calloc (ELEMENT_INITIAL_SIZE,
00197                                                              sizeof(IbmlProperty *));
00198         if (ibml_element->properties == NULL)
00199             return IBML_ERROR;
00200     }
00201 
00202     num_properties = ibml_element->num_properties;
00203     if ((num_properties + 1) % ELEMENT_INITIAL_SIZE == 0) {
00204         int num = num_properties + 1 + ELEMENT_INITIAL_SIZE;
00205 
00206         ibml_element->properties = (IbmlProperty **)realloc(ibml_element->properties,
00207                                                             num * sizeof(IbmlProperty *));
00208         if (ibml_element->properties == NULL)
00209             return IBML_ERROR;
00210 
00211         for (i = num_properties; i < num; i++)
00212             ibml_element->properties[i] = NULL;
00213     }
00214 
00215     ibml_element->properties[num_properties] = ibml_property;
00216     ibml_element->num_properties ++;
00217 
00218     return IBML_OK;
00219 }
00220 
00221 static IbmlCategory *ibml_category_new()
00222 {
00223     IbmlCategory *ibml_category;
00224 
00225     ibml_category = (IbmlCategory *) malloc(sizeof(IbmlCategory));
00226     if (ibml_category == NULL)
00227        return NULL;
00228 
00229     ibml_category->num_elements = 0;
00230     ibml_category->elements = NULL;
00231 
00232     return ibml_category;
00233 }
00234 
00235 static int ibml_category_free(IbmlCategory * ibml_category)
00236 {
00237     int i;
00238 
00239     if (ibml_category == NULL)
00240        return IBML_OK;
00241 
00242     for (i = 0; i < ibml_category->num_elements; i++)
00243        ibml_element_free(ibml_category->elements[i]);
00244     SafeFree(ibml_category->elements);
00245 
00246     SafeFree(ibml_category->scope);
00247     SafeFree(ibml_category);
00248 
00249     return IBML_OK;
00250 }
00251 
00252 static int ibml_category_print(IbmlCategory * ibml_category)
00253 {
00254     int i;
00255     char *scope;
00256 
00257     if (ibml_category == NULL)
00258        return IBML_OK;
00259 
00260     scope = ibml_category->scope;
00261     if (scope && *scope)
00262        printf("Category: %s\n", scope);
00263 
00264     for (i = 0; i < ibml_category->num_elements; i++)
00265        ibml_element_print(ibml_category->elements[i]);
00266 
00267     return IBML_OK;
00268 }
00269 
00270 static int ibml_category_pushback_element(IbmlCategory * ibml_category,
00271                                           IbmlElement * ibml_element)
00272 {
00273     int i, num_elements;
00274 
00275     if (ibml_category == NULL || ibml_element == NULL)
00276         return IBML_ERROR;
00277 
00278     if (ibml_category->elements == NULL) {
00279         ibml_category->elements = (IbmlElement **) calloc (ELEMENT_INITIAL_SIZE,
00280                                                            sizeof(IbmlElement *));
00281         if (ibml_category->elements == NULL)
00282             return IBML_ERROR;
00283     }
00284 
00285     num_elements = ibml_category->num_elements;
00286     if ((num_elements + 1) % ELEMENT_INITIAL_SIZE == 0) {
00287         int num = num_elements + 1 + ELEMENT_INITIAL_SIZE;
00288 
00289         ibml_category->elements = (IbmlElement **)realloc(ibml_category->elements,
00290                                                           num * sizeof(IbmlElement *));
00291         if (ibml_category->elements == NULL)
00292             return IBML_ERROR;
00293 
00294         for (i = num_elements; i < num; i++)
00295             ibml_category->elements[i] = NULL;
00296     }
00297 
00298     ibml_category->elements[num_elements] = ibml_element;
00299     ibml_category->num_elements ++;
00300 
00301     return IBML_OK;
00302 }
00303 
00304 IbmlData *ibml_data_new()
00305 {
00306     IbmlData *ibml_data;
00307 
00308     ibml_data = (IbmlData *) malloc(sizeof(IbmlData));
00309     if (ibml_data == NULL)
00310        return NULL;
00311 
00312     ibml_data->num_categories = 0;
00313     ibml_data->categories = NULL;
00314 
00315     return ibml_data;
00316 }
00317 
00318 int ibml_data_free(IbmlData * ibml_data)
00319 {
00320     int i;
00321 
00322     if (ibml_data == NULL)
00323        return IBML_OK;
00324 
00325     for (i = 0; i < ibml_data->num_categories; i++)
00326        ibml_category_free(ibml_data->categories[i]);
00327     SafeFree(ibml_data->categories);
00328 
00329     SafeFree(ibml_data);
00330 
00331     return IBML_OK;
00332 }
00333 
00334 int ibml_data_print(IbmlData * ibml_data)
00335 {
00336     int i;
00337 
00338     if (ibml_data == NULL)
00339        return IBML_OK;
00340 
00341     for (i = 0; i < ibml_data->num_categories; i++)
00342        ibml_category_print(ibml_data->categories[i]);
00343 
00344     return IBML_OK;
00345 }
00346 
00347 static int ibml_data_pushback_category(IbmlData * ibml_data,
00348                                        IbmlCategory * ibml_category)
00349 {
00350     int i, num_categories;
00351 
00352     if (ibml_data == NULL || ibml_category == NULL)
00353         return IBML_ERROR;
00354 
00355     if (ibml_data->categories == NULL) {
00356         ibml_data->categories = (IbmlCategory **) calloc (ELEMENT_INITIAL_SIZE,
00357                                                           sizeof(IbmlCategory *));
00358         if (ibml_data->categories == NULL)
00359             return IBML_ERROR;
00360     }
00361 
00362     num_categories = ibml_data->num_categories;
00363     if ((num_categories + 1) % ELEMENT_INITIAL_SIZE == 0) {
00364         int num = num_categories + 1 + ELEMENT_INITIAL_SIZE;
00365 
00366         ibml_data->categories = (IbmlCategory **)realloc(ibml_data->categories,
00367                                                          num * sizeof(IbmlCategory *));
00368         if (ibml_data->categories == NULL)
00369             return IBML_ERROR;
00370 
00371         for (i = num_categories; i < num; i++)
00372             ibml_data->categories[i] = NULL;
00373     }
00374 
00375     ibml_data->categories[num_categories] = ibml_category;
00376     ibml_data->num_categories ++;
00377 
00378     return IBML_OK;
00379 }
00380 
00381 static char *ibml_strdup(char *str)
00382 {
00383     char *ptr;
00384 
00385     ptr = (char *) calloc(strlen(str) + 1, 1);
00386     if (ptr != NULL)
00387        strcpy(ptr, str);
00388 
00389     return ptr;
00390 }
00391 
00392 static char *get_error_message(int error_no)
00393 {
00394     switch (error_no) {
00395     case IBML_ERR_NO_MEMORY:
00396        return IBML_ERR_STR_NO_MEMORY;
00397     case IBML_ERR_INVALID_ELEMENT_NAME:
00398        return IBML_ERR_STR_INVALID_ELEMENT_NAME;
00399     case IBML_ERR_INVALID_ELEMENT_ATTRIBUTE:
00400        return IBML_ERR_STR_INVALID_ELEMENT_ATTRIBUTE;
00401     case IBML_ERR_INVALID_ELEMENT_ITEM:
00402        return IBML_ERR_STR_INVALID_ELEMENT_ITEM;
00403     }
00404     return IBML_ERR_STR_DEFAULT;
00405 }
00406 
00407 int parseImbeanProperty(xmlDocPtr doc, xmlNodePtr cur,
00408                      IbmlElement * ibml_element)
00409 {
00410     xmlChar *property_name = NULL;
00411     xmlChar *property_value = NULL;
00412     xmlChar *property_scope = NULL;
00413     xmlChar *property_options = NULL;
00414     xmlChar *property_type = NULL;
00415 
00416     IbmlProperty *ibml_property;
00417 
00418     ibml_property = (IbmlProperty *) ibml_property_new();
00419     if (ibml_property == NULL) {
00420        return IBML_ERROR;
00421     }
00422 
00423     property_name = xmlGetProp(cur, IBML_ELEMENT_PROPERTY_NAME);
00424     if (property_name && *property_name)
00425        ibml_property->name = (char *) ibml_strdup(property_name);
00426     xmlFree(property_name);
00427 
00428     property_value = xmlGetProp(cur, IBML_ELEMENT_PROPERTY_VALUE);
00429     if (property_value && *property_value)
00430        ibml_property->value = (char *) ibml_strdup(property_value);
00431     xmlFree(property_value);
00432 
00433     property_options = xmlGetProp(cur, IBML_ELEMENT_PROPERTY_OPTIONS);
00434     if (property_options && *property_options)
00435        ibml_property->options = (char *) ibml_strdup(property_options);
00436     xmlFree(property_options);
00437 
00438     property_type = xmlGetProp(cur, IBML_ELEMENT_PROPERTY_TYPE);
00439     if (property_type && *property_type)
00440        ibml_property->type = (char *) ibml_strdup(property_type);
00441     xmlFree(property_type);
00442 
00443     property_scope = xmlGetProp(cur, IBML_ELEMENT_SCOPE);
00444     if (property_scope && *property_scope)
00445        ibml_property->scope = (char *) ibml_strdup(property_scope);
00446     xmlFree(property_scope);
00447 
00448     ibml_element_pushback_property(ibml_element, ibml_property);
00449 
00450     return IBML_OK;
00451 }
00452 
00453 int parseImbeanElement(xmlDocPtr doc, xmlNodePtr cur,
00454                      IbmlCategory * ibml_category)
00455 {
00456     xmlChar *id = NULL;
00457     xmlChar *scope = NULL;
00458 
00459     IbmlElement *ibml_element;
00460 
00461     ibml_element = ibml_element_new();
00462     if (ibml_element == NULL)
00463        return IBML_ERROR;
00464 
00465     id = xmlGetProp(cur, IBML_ELEMENT_IMBEAN_ID);
00466     if (id && *id)
00467        ibml_element->id = (char *) ibml_strdup(id);
00468     xmlFree(id);
00469 
00470     scope = xmlGetProp(cur, IBML_ELEMENT_SCOPE);
00471     if (scope && *scope)
00472        ibml_element->scope = (char *) ibml_strdup(scope);
00473     xmlFree(scope);
00474 
00475     cur = cur->xmlChildrenNode;
00476     while (cur != NULL) {
00477        if (!xmlStrcmp(cur->name, (const xmlChar *) IBML_ELEMENT_PROPERTY)) {
00478            parseImbeanProperty(doc, cur, ibml_element);
00479        }
00480        cur = cur->next;
00481     }
00482 
00483     ibml_category_pushback_element(ibml_category, ibml_element);
00484 
00485     return IBML_OK;
00486 }
00487 
00488 int parseImCategory(xmlDocPtr doc, xmlNodePtr cur, IbmlData * ibml_data)
00489 {
00490     xmlChar *scope;
00491     xmlChar *class;
00492 
00493     IbmlCategory *ibml_category;
00494 
00495     ibml_category = ibml_category_new();
00496     if (ibml_category == NULL)
00497        return IBML_ERROR;
00498 
00499     scope = xmlGetProp(cur, IBML_ELEMENT_SCOPE);
00500     if (scope && *scope)
00501        ibml_category->scope = (char *) ibml_strdup(scope);
00502     xmlFree(scope);
00503 
00504     cur = cur->xmlChildrenNode;
00505     while (cur != NULL) {
00506        if (!xmlStrcmp(cur->name, (const xmlChar *) IBML_ELEMENT_IMBEAN)) {
00507            parseImbeanElement(doc, cur, ibml_category);
00508        }
00509        cur = cur->next;
00510     }
00511 
00512     ibml_data_pushback_category(ibml_data, ibml_category);
00513 
00514     return IBML_OK;
00515 }
00516 
00517 IbmlData *imbean_config_new_from_memory(char *buffer, int size)
00518 {
00519     xmlDocPtr doc;
00520     xmlNodePtr cur;
00521 
00522     IbmlData *ibml_data;
00523 
00524     doc = xmlParseMemory(buffer, size);
00525     if (doc == NULL)
00526        return NULL;
00527 
00528     cur = xmlDocGetRootElement(doc);
00529     if (cur == NULL) {
00530        xmlFreeDoc(doc);
00531        return NULL;
00532     }
00533 
00534     if (xmlStrcmp(cur->name, (xmlChar *) IBML_ELEMENT_ROOT)) {
00535        fprintf(stderr, "wrong root, should be %s\n", IBML_ELEMENT_ROOT);
00536        xmlFreeDoc(doc);
00537        return NULL;
00538     }
00539 
00540     ibml_data = ibml_data_new();
00541     if (ibml_data == NULL) {
00542        xmlFreeDoc(doc);
00543        return NULL;
00544     }
00545 
00546     cur = cur->xmlChildrenNode;
00547     while (cur) {
00548        if (!xmlStrcmp(cur->name, (const xmlChar *) IBML_ELEMENT_CATAGORY)) {
00549            parseImCategory(doc, cur, ibml_data);
00550        }
00551        cur = cur->next;
00552     }
00553 
00554     xmlFreeDoc(doc);
00555     return ibml_data;
00556 }
00557 
00558 IbmlData *imbean_config_new_from_file(char *file_name)
00559 {
00560     IbmlData *ibml_data;
00561     FILE *fd;
00562 
00563     struct stat file_stat;
00564     int file_size;
00565     char *base;
00566 
00567     if (stat(file_name, &file_stat) == -1)
00568        return NULL;
00569 
00570     file_size = file_stat.st_size;
00571     if (file_size == 0)
00572        return NULL;
00573 
00574     if ((fd = fopen(file_name, "r")) == NULL)
00575        return NULL;
00576 
00577     base = (char *) calloc(file_size, sizeof(char));
00578     if (base == NULL) {
00579        fclose(fd);
00580        return NULL;
00581     }
00582 
00583     if (fread((char *) base, sizeof(char), file_size, fd) != file_size) {
00584        free((char *) base);
00585        fclose(fd);
00586        return NULL;
00587     }
00588 
00589     ibml_data = (IbmlData *) imbean_config_new_from_memory(base, file_size);
00590 
00591     free((char *) base);
00592     return ibml_data;
00593 }