core/load_xml_handle.cpp

00001 /* gld_load.h
00002  * 
00003  * Authors:
00004  *  Matthew Hauer <matthew.hauer@pnl.gov>, 6 Nov 07 -
00005  *
00006  * Versions:
00007  *  1.0 - MH - initial version
00008  *
00009  * Credits:
00010  *  adapted from SAX2Print.h
00011  *
00012  *  @file load_xml_handle.cpp
00013  *  @addtogroup load XML file loader
00014  *  @ingroup core
00015  *
00016  */
00017 
00018 #include <xercesc/util/XMLUniDefs.hpp>
00019 #include <xercesc/sax2/Attributes.hpp>
00020 #include "load_xml_handle.h"
00021 
00022 #define _CRT_SECURE_NO_DEPRECATE 1
00023 
00024 gld_loadHndl::gld_loadHndl() : fFormatter("LATIN1", 0, this, XMLFormatter::NoEscapes, (const XMLFormatter::UnRepFlags) 0),
00025         fExpandNS ( false ){
00026     depth = 0;
00027     first = last = -1;
00028     stack_state = EMPTY;
00029 
00030     load_state = false;
00031     module_name[0] = 0;
00032     obj = NULL;
00033     stack_ptr = NULL;
00034     object_count = 0;
00035     class_count = 0;
00036 }
00037 
00038 gld_loadHndl::gld_loadHndl(const char* const encodingName, const XMLFormatter::UnRepFlags unRepFlags, const bool expandNamespaces)
00039     :   fFormatter(encodingName, 0, this, XMLFormatter::NoEscapes, unRepFlags),
00040         fExpandNS ( expandNamespaces ){
00041     depth = 0;
00042     first = last = -1;
00043     obj = NULL;
00044     stack_state = EMPTY;
00045 
00046     load_state = false;
00047     module_name[0] = 0;
00048     stack_ptr = NULL;
00049     object_count = 0;
00050     class_count = 0;
00051 }
00052 
00053 gld_loadHndl::~gld_loadHndl(){
00054     ;
00055 }
00056 
00057 void gld_loadHndl::setDocumentLocator(const Locator *const loc){
00058     this->locator = loc;
00059 }
00060 
00061 void gld_loadHndl::writeChars(const XMLByte* const toWrite){
00062     ;
00063 }
00064 
00065 void gld_loadHndl::writeChars(const XMLByte* const toWrite, const unsigned int count, XMLFormatter* const formatter){
00066     //printf("%s", (char *)toWrite);
00067 }
00068 
00069 void gld_loadHndl::error(const SAXParseException& e){
00070     output_error("XML_Load: %ls(%i:char %i)\n Message: %ls", (char *)e.getSystemId(), e.getLineNumber(), e.getColumnNumber(), (char *)e.getMessage());
00071     load_state = false;
00072 }
00073 
00074 void gld_loadHndl::fatalError(const SAXParseException& e){
00075     output_error("XML_Load: %ls(%i:char %i)\n Message: %ls", (char *)e.getSystemId(), e.getLineNumber(), e.getColumnNumber(), (char *)e.getMessage());
00076     load_state = false;
00077 }
00078 
00079 void gld_loadHndl::warning(const SAXParseException& e){
00080     output_warning("XML_Load: %ls(%i:char %i)\n Message: %ls", (char *)e.getSystemId(), e.getLineNumber(), e.getColumnNumber(), (char *)e.getMessage());
00081     //load_state = false;
00082 }
00083 
00084 
00085 void gld_loadHndl::notationDecl(const  XMLCh* const name, const XMLCh* const publicId, const XMLCh* const systemId){
00086     ;
00087 }
00088 
00091 void gld_loadHndl::parse_property(char *buffer){
00092     ;
00093 }
00094 
00095 char *gld_loadHndl::read_module_prop(char *buffer, size_t len){
00096     //printf("read_module_prop (%s)\n", buffer);
00097     if(strcmp(propname, "major") == 0){
00098         char temp[8];
00099         int major_in = atoi(buffer);
00100         int major = 0;
00101         module_getvar(this->module, "major", temp, 8);
00102         major = atoi(temp);
00103         if(major == 0)                  //  don't care if major = 0
00104             return NULL;
00105         if(major == major_in){          //  current version, continue
00106             return NULL;
00107         } else if(major > major_in){    //  old version
00108             output_warning("The input file was built using an older major version of the module.");
00109             return NULL;
00110         } else if(major < major_in){    //  newer version
00111             output_warning("The file was built using a newer major version of the module loading it!");
00112             return NULL;
00113         }
00114     } else if(strcmp(propname, "minor") == 0){
00115         char temp[8];
00116         int minor_in = atoi(buffer);
00117         int minor = 0;
00118         int major = 0;
00119         module_getvar(this->module, "major", temp, 8);
00120         major = atoi(temp);
00121         module_getvar(this->module, "minor", temp, 8);
00122         minor = atoi(temp);
00123         if(major == 0)  //  don't care if major = 0
00124             return NULL;
00125         if(minor == minor_in){          //  current version, continue
00126             return NULL;
00127         } else if(minor > minor_in){    //  old version
00128             output_warning("XML::read_module_prop(): The input file was built using an older minor version of the module.");
00129         } else if(minor < minor_in){    //  new version
00130             output_warning("XML::read_module_prop(): The file was built using a newer minor version of the module loading it!");
00131         }
00132     }
00133     return NULL;
00134 }
00135 
00136 char *gld_loadHndl::read_global_prop(char *buffer, size_t len){
00137     return 0;
00138 }
00139 
00140 char *gld_loadHndl::read_clock_prop(char* buffer, size_t len){
00141     TIMESTAMP tsval = 0;
00142     if(strcmp(propname, "tick") == 0){
00143         ;
00144     } else if(strcmp(propname, "timezone") == 0){
00145         if (timestamp_set_tz(buffer)==NULL){
00146             sprintf(errmsg, "timezone %s is not defined", timezone);
00147             return errmsg;
00148         }
00149     } else if(strcmp(propname, "timestamp") == 0){
00150         if(time_value_datetime(buffer, &tsval)){
00151             global_clock = tsval;
00152         } else {
00153             sprintf(errmsg, "timestamp \"%s\" could not be resolved", buffer);
00154             return errmsg;
00155         }
00156     } else {
00157         sprintf(errmsg, "Unrecognized keyword in start_element_clock(%s)", buffer);
00158         return errmsg;
00159     }
00160     return NULL;
00161 }
00162 
00163 char *gld_loadHndl::read_object_prop(char *buffer, size_t len){
00164     //wchar_t wbuff[1024];
00165     //char tbuff[1024];
00166     char *rand_ptr = NULL;
00167     char *rand_mode_ptr = NULL;
00168     char *unit_ptr = NULL;
00169     double realval = 0.0;
00170     UNIT *unit=NULL;
00171     SAXParseException *e = NULL;
00172     void *addr = object_get_addr(obj, propname); /* get the & to set later */
00173     if(this->obj == NULL){
00174         sprintf(errmsg, "Null object pointer in read_object_prop(%s)", buffer);
00175         return errmsg;  //  no object
00176     }
00177     if(this->prop == NULL){
00178         if (strcmp(propname, "parent")==0){
00179             if (strcmp(propname, "root")==0){
00180                 obj->parent = NULL;
00181             } else {
00182                 add_unresolved(obj,(OBJECT **)&obj->parent,oclass,buffer,42,UR_RANKS); 
00183             }
00184         } else if (strcmp(propname, "rank")==0){
00185             obj->rank = atoi(buffer);
00186         } else if (strcmp(propname, "clock")==0){
00187             obj->clock = atoi64(buffer);
00188         } else if (strcmp(propname, "latitude")==0){
00189             obj->latitude = load_latitude(buffer);
00190         } else if (strcmp(propname, "longitude")==0){
00191             obj->longitude = load_longitude(buffer);
00192         } else if (strcmp(propname, "in")==0){
00193             obj->in_svc = convert_to_timestamp(buffer);
00194         } else if (strcmp(propname, "out")==0){
00195             obj->out_svc = convert_to_timestamp(buffer);
00196         } else {
00197             sprintf(errmsg, "Null property pointer in read_object_prop(%s)", buffer);
00198             return errmsg;
00199         }
00200         return NULL;
00201     }
00202     //  determine property type
00203     switch(prop->ptype){
00204         case PT_double:
00205             //  scan for "random"
00206             if(strncmp("random.", buffer, 7) == 0){
00207                 char temp[256];
00208                 char *modep = NULL;
00209                 double first = 0.0, second = 0.0;
00210                 RANDOMTYPE rt;
00211                 strncpy(temp, buffer, 256);
00212                 modep = strtok(temp+7, "(");
00213                 if(modep == NULL){
00214                     //output_error("XML_Load: misformed random() value");
00215                     load_state = false;
00216                     sprintf(errmsg, "Misformed random() value in read_object_prop(%s)", buffer);
00217                     return errmsg;
00218                 }
00219                 rt = random_type(modep);
00220                 if(rt == 0){
00221                     //output_message("XML_Load: '%s' ~ %s is not a valid random distribution", buffer, modep);
00222                     load_state = false;
00223                     sprintf(errmsg, "Invalid random distribution in read_object_prop(%s)", buffer);
00224                     return errmsg;
00225                 } else {
00226                     first = atof(strtok(NULL, ","));
00227                     second = atof(strtok(NULL, ")"));
00228                     realval = random_value(rt, first, second);
00229                 }
00230                 if(strlen(strchr(buffer, ')')+1) > 0){ /* look for units */
00231                     unit = unit_find(strchr(buffer, ')') + 2);
00232                     if (unit!=NULL && prop->unit!=NULL && unit_convert_ex(unit,prop->unit,&realval)==0){
00233                         sprintf(errmsg, "Cannot convert units from %s to %s in read_object_prop(%s)", unit->name,prop->unit->name, buffer);
00234                         load_state = false;
00235                         return errmsg;
00236                     }
00237                 }
00238             } else {
00239                 unit_ptr = NULL;
00240                 realval = strtod(buffer, &unit_ptr);
00241                 if(unit_ptr != NULL){
00242                     while(*unit_ptr == ' ') ++unit_ptr;
00243                     unit = unit_find(unit_ptr);
00244                     if(strlen(unit_ptr) > 0){
00245                         if (unit!=NULL && prop->unit!=NULL && unit_convert_ex(unit,prop->unit,&realval)==0){
00246                             sprintf(errmsg, "Cannot convert units from %s to %s in read_object_prop(%s)", unit->name,prop->unit->name, buffer);
00247                             load_state = false;
00248                             return errmsg;
00249                         }
00250                     }
00251                 }
00252             }
00253             /* if((unit_ptr != NULL) && (*unit_ptr != '\0')){;} */
00254             if(object_set_double_by_name(obj, propname, realval) == 0){
00255                 sprintf(errmsg, "Could not set \"%s\" to %f in read_object_prop(%s)", propname, realval, buffer);
00256                 load_state = false;
00257                 return errmsg;
00258             } else {
00259                 return NULL; /* success */
00260             }
00261             break;
00262         case PT_object:
00263             if(add_unresolved(obj,(OBJECT **)addr,oclass,buffer,42,UR_NONE) == NULL){
00264                 sprintf(errmsg, "Failure with add_unresolved() in read_object_prop(%s)", buffer);
00265                 return errmsg;
00266             }
00267             break;
00268         default:
00269             if(prop->ptype < _PT_LAST){ //  set value by name
00270                 if (object_set_value_by_name(obj, propname, buffer)==0) {
00271                     //output_error("XML_Load: property %s of %s:%s could not be set to '%s'", propname, obj->oclass->name, obj->id, buffer);
00272                     sprintf("Property %s of %s:%s could not be set to \"%s\" in read_object_prop(%s)", propname, obj->oclass->name, obj->id, buffer);
00273                     load_state = false;
00274                     return errmsg;
00275                 } else {
00276                     ;
00277                 }
00278             } else {
00279                 sprintf(errmsg, "Invalid property id = %i in read_object_prop(%s)", prop->ptype, buffer);
00280                 return errmsg;
00281             }
00282     }
00283     return 0;
00284 }
00285 
00288 void gld_loadHndl::characters(const XMLCh* const chars, const unsigned int length){
00289     char buffer[1024];
00290     char tbuff[1024];
00291     wchar_t wbuff[1024];
00292     SAXParseException *e = NULL;
00293     char *unit_ptr = NULL;
00294     unsigned int i = 0;
00295     size_t len = 0;
00296     char *retval = NULL;    //  negative logic
00297     switch(stack_state){
00298         case MODULE_PROP:
00299         case GLOBAL_PROP:
00300         case OBJECT_PROP:
00301         case CLOCK_PROP:
00302             //  get prop
00303             if((len = wcslen((const wchar_t *)chars)) < 1){
00304                 sprintf(tbuff, "Unable to get length of characters in characters()");
00305                 mbstowcs(wbuff, tbuff, 1024);
00306                 e = new SAXParseException((const XMLCh *)wbuff, *(this->locator));
00307                 error(*e);
00308                 delete e;
00309                 return;
00310             }
00311             if(len != wcstombs(buffer, (const wchar_t *)chars, 1024)){
00312                 sprintf(tbuff, "Unable to convert wcs to char in characters()");
00313                 mbstowcs(wbuff, tbuff, 1024);
00314                 e = new SAXParseException((const XMLCh *)wbuff, *(this->locator));
00315                 error(*e);
00316                 delete e;
00317                 return;
00318             }
00319             break;
00320         default:
00321             return; //  ignore whatever characters we read, we don't use them here.
00322     }
00323     switch(stack_state){
00324         case MODULE_PROP:
00325             retval = this->read_module_prop(buffer, len);
00326             break;
00327         case GLOBAL_PROP:
00328             retval = this->read_global_prop(buffer, len);
00329             break;
00330         case OBJECT_PROP:
00331             retval = this->read_object_prop(buffer, len);
00332             //  get prop
00333             break;
00334         case CLOCK_PROP:
00335             retval = this->read_clock_prop(buffer, len);
00336     }
00337     if(retval != NULL){
00338         stack_state = EMPTY;    //  stop processing
00339         output_error("Error reading the XML file");
00340         mbstowcs(wbuff, errmsg, 1024);
00341         e = new SAXParseException((const XMLCh *)wbuff, *(this->locator));
00342         error(*e);
00343         delete e;
00344         load_state = 0;
00345     }
00346 
00347 }
00348 
00351 void gld_loadHndl::endDocument(){
00352     OBJECT *tempobj = object_get_first();
00353 
00354     /* resolve_list(); */
00355     if(load_resolve_all() == FAILED){
00356         output_error("XML_Load: unable to resolve object linkings!");
00357         load_state = false;
00358     }
00359     /* "establish ranks" */
00360 
00361     for (; obj!=NULL; obj=obj->next)
00362         object_set_parent(obj,obj->parent);
00363     output_verbose("XML_Load: %d object%s loaded.", object_get_count(), object_get_count() > 0 ? "s" : "");
00364     if(object_count > 0)
00365         if(object_get_count() != this->object_count)
00366             output_warning("XML_Load: we expected %i objects instead!", this->object_count);
00367     output_verbose("XML_Load: %d class%s loaded.", class_get_count(), class_get_count() > 0 ? "es" : "");
00368     if(class_count > 0)
00369         if(class_get_count() != this->class_count)
00370             output_warning("XML_Load: we expected %i classes instead!", this->class_count);
00371 }
00372 
00373 char *gld_loadHndl::end_element_empty(char *buffer, size_t len){    //  why are we here?
00374     return NULL;
00375 }
00376 
00377 char *gld_loadHndl::end_element_load(char *buffer, size_t len){
00378     if(strcmp("load", buffer) == 0)
00379         stack_state = EMPTY;
00380     return NULL;
00381 }
00382 
00383 char *gld_loadHndl::end_element_module(char *buffer, size_t len){
00384     if(strcmp("module", buffer) == 0)
00385         stack_state = LOAD;
00386     return NULL;
00387 }
00388 
00389 char *gld_loadHndl::end_element_module_prop(char *buffer, size_t len){
00390     if(strcmp(propname, buffer) == 0){
00391         memset(propname, 0, len);
00392         stack_state = MODULE_STATE;
00393     }
00394     return NULL;
00395 }
00396 
00397 char *gld_loadHndl::end_element_object(char *buffer, size_t len){
00398     if(strcmp("object", buffer) == 0)
00399         stack_state = MODULE_STATE;
00400     return NULL;
00401 }
00402 
00403 char *gld_loadHndl::end_element_object_prop(char *buffer, size_t len){
00404     if(strcmp(propname, buffer) == 0){
00405         memset(propname, 0, len);
00406         stack_state = OBJECT_STATE;
00407     }
00408     return NULL;
00409 }
00410 
00411 char *gld_loadHndl::end_element_global(char *buffer, size_t len){
00412     if(strcmp("global", buffer) == 0)
00413         stack_state = LOAD;
00414     return NULL;
00415 }
00416 
00417 char *gld_loadHndl::end_element_global_prop(char *buffer, size_t len){
00418     if(strcmp(propname, buffer) == 0){
00419         memset(propname, 0, len);
00420         stack_state = GLOBAL_STATE;
00421     }
00422     return NULL;
00423 }
00424 
00425 char *gld_loadHndl::end_element_clock_prop(char *buffer, size_t len){
00426     if(strcmp(propname, buffer) == 0){
00427         memset(propname, 0, len);
00428         stack_state = CLOCK_STATE;
00429     }
00430     return NULL;
00431 }
00432 
00433 char *gld_loadHndl::end_element_clock(char *buffer, size_t len){
00434     if(strcmp("clock", buffer) == 0)
00435         stack_state = LOAD;
00436     return NULL;
00437 }
00438 
00441 void gld_loadHndl::endElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname){
00442     char buffer[128];
00443     int i = 0;
00444     size_t len = 0;
00445     gldStack *temp_stack = NULL;
00446     char *retval = NULL;    // negative logic
00447     
00448     --depth;
00449 
00450     len = wcslen((const wchar_t *)qname);
00451     wcstombs(buffer, (const wchar_t *)qname, 128);
00452     
00453     switch(stack_state){
00454         case EMPTY:
00455             retval = end_element_empty(buffer, len);
00456             break;
00457         case LOAD:
00458             retval = end_element_load(buffer, len);
00459             break;
00460         case MODULE_STATE:
00461             retval = end_element_module(buffer, len);
00462             break;
00463         case MODULE_PROP:
00464             retval = end_element_module_prop(buffer, len);
00465             break;
00466         case OBJECT_STATE:
00467             retval = end_element_object(buffer, len);
00468             break;
00469         case OBJECT_PROP:
00470             retval = end_element_object_prop(buffer, len);
00471             break;
00472         case GLOBAL_STATE:
00473             retval = end_element_global(buffer, len);
00474             break;
00475         case GLOBAL_PROP:
00476             retval = end_element_global_prop(buffer, len);
00477             break;
00478         case CLOCK_STATE:
00479             retval = end_element_clock(buffer, len);
00480             break;
00481         case CLOCK_PROP:
00482             retval = end_element_clock_prop(buffer, len);
00483             break;
00484     }
00485 }
00486 
00487 
00488 void gld_loadHndl::ignorableWhitespace(const XMLCh* const chars, const unsigned int length){
00489     output_verbose("XML_Load: ignored: %i spaces.", length);
00490 }
00491 
00492 
00493 void gld_loadHndl::processingInstruction(const  XMLCh* const target, const XMLCh* const data){
00494     /* put GLD macros in here? -mh */
00495     return;
00496 }
00497 
00500 void gld_loadHndl::startDocument(){
00501     depth = 0;
00502     module_name[0] = 0;
00503     load_state = true;
00504 }
00505 
00506 char *gld_loadHndl::start_element_empty(char *buffer, size_t len, const Attributes& attributes){
00507     if(strcmp(buffer, "load") == 0){
00508         stack_state = LOAD;
00509     } // cut some slack, don't break here.
00510     return NULL;
00511 }
00512 
00513 char *gld_loadHndl::start_element_load(char *buffer, size_t len, const Attributes& attributes){
00514     static wchar_t wcs_type[5], wcs_minor[6], wcs_major[6];
00515     static size_t wcs_type_len = mbstowcs(wcs_type, "type", 5);
00516     static size_t wcs_major_len = mbstowcs(wcs_major, "major", 6);
00517     static size_t wcs_minor_len = mbstowcs(wcs_minor, "minor", 6);
00518     XMLCh *_major = NULL, *_minor = NULL;
00519     long int major = 0, minor = 0;
00520     if(strcmp(buffer, "global") == 0){
00521         stack_state = GLOBAL_STATE;
00522     } else if(strcmp(buffer, "module") == 0){   //  LOAD THE MODULE
00523         wcstombs(module_name, (const wchar_t *)attributes.getValue((const XMLCh *)wcs_type), 1024);
00524         _major = (XMLCh *)attributes.getValue((const XMLCh *)wcs_major);
00525         _minor = (XMLCh *)attributes.getValue((const XMLCh *)wcs_minor);
00526         if(_major != NULL)
00527             major = wcstol((const wchar_t *)_major, NULL, 10);
00528         if(_minor != NULL)
00529             minor = wcstol((const wchar_t *)_minor, NULL, 10);
00530         
00531         if((module = module_load(module_name, 0, NULL)) == NULL){
00532             sprintf(errmsg, "Unable to load module \"%s\" in start_element_load()", module_name);
00533             return errmsg;
00534         } else {
00535             strcpy(module_name, buffer);
00536             stack_state = MODULE_STATE;
00537             if(major != 0){
00538                 char temp[8];
00539                 module_getvar(this->module, "major", temp, 8);
00540                 int major_in = atoi(temp);
00541                 module_getvar(this->module, "minor", temp, 8);
00542                 int minor_in = atoi(temp);
00543                 if(major < major_in){
00544                     output_warning("XML::read_module_prop(): The input file was built using an older major version of the module.");
00545                     return NULL; /* avoid minor var complaints */
00546                 }
00547                 if(minor == minor_in){          //  current version, continue
00548                     return NULL;
00549                 } else if(minor > minor_in){    //  old version
00550                     output_warning("XML::read_module_prop(): The input file was built using an older minor version of the module.");
00551                 } else if(minor < minor_in){    //  new version
00552                     output_warning("XML::read_module_prop(): The file was built using a newer minor version of the module loading it!");
00553                 }
00554             }
00555         }
00556     } else if(strcmp(buffer, "clock") == 0){
00557         stack_state = CLOCK_STATE;
00558     } else {
00559         sprintf(errmsg, "Unrecognized keyword in start_element_load(%s)", buffer);
00560         return errmsg;
00561     }
00562     return NULL;
00563 }
00564 
00565 char *gld_loadHndl::start_element_module_build_object(const Attributes &attributes){
00566     static wchar_t str_id[3],
00567             str_name[5],
00568             str_type[5];
00569     static size_t str_id_len = mbstowcs(str_id, "id", 3),
00570             str_name_len = mbstowcs(str_name, "name", 5),
00571             str_type_len = mbstowcs(str_type, "type", 5);
00572     char object_type[64],
00573         object_id[64],
00574         object_name[64];
00575     char *temp = NULL;
00576     char *retval = NULL;
00577     int first = -1,
00578         last = -1;
00579     if(attributes.getIndex((const XMLCh *) str_type) < 0){
00580         sprintf(errmsg, "object tag without a type in start_element_module_build_object()");
00581         return errmsg;
00582     } else {
00583         wcstombs(object_type, (const wchar_t *)attributes.getValue((const XMLCh *) str_type), 64);
00584         oclass = class_get_class_from_classname_in_module(object_type, module);
00585         if(oclass == NULL){
00586             sprintf(errmsg, "Class \"%s\" for module \"%s\"is not recognized in start_element_module_build_object()", object_type, module->name);
00587             return errmsg;
00588         } else {
00589             ; /* recognized class type */
00590         }
00591     }
00592     if(attributes.getIndex((const XMLCh *) str_id) < 0){
00593         /* anonymous objects are legit - mh */
00594         last = first = -1;
00595     } else {
00596         wcstombs(object_id, (wchar_t *)attributes.getValue((const XMLCh *) str_id), 64);
00597         temp = strchr(object_id, '.');
00598         if(temp == NULL){ /* no "..", just a number*/
00599             first = strtol(object_id, NULL, 10);
00600             if(first < 0){
00601                 sprintf(errmsg, "Invalid object id of %i in start_element_module_build_object()", first);
00602                 return errmsg;
00603             } else {
00604                 last = first;
00605             }
00606         } else {
00607             if(temp[0] == temp[1]){
00608                 if(temp == object_id){ /* "..x", count */
00609                     last = strtol(object_id+2, NULL, 10);
00610                     if(last < 1){
00611                         sprintf(errmsg, "Invalid object id of %i in start_element_module_build_object()", first);
00612                         return errmsg;
00613                     } else {
00614                         first = -1;
00615                     }
00616                 } else { /* "x..y", range */
00617                     *temp = 0;
00618                     first = strtol(object_id, NULL, 10);
00619                     last = strtol(temp+2, NULL, 10);
00620                     *temp = '.';
00621                     if(first < 0){
00622                         output_error("XML_Load: first ID < 0 !");
00623                         sprintf(errmsg, "Invalid object id of %i in start_element_module_build_object()", first);
00624                         return errmsg;
00625                     }
00626                     if(last < 1){
00627                         output_error("XML_Load: last ID < 1 !");
00628                         sprintf(errmsg, "Invalid object id of %i in start_element_module_build_object()", first);
00629                         return errmsg;
00630                     }
00631                     if(first >= last){
00632                         output_error("XML_Load: first id >= last id!");
00633                         sprintf(errmsg, "Invalid object id of %i in start_element_module_build_object()", first);
00634                         return errmsg;
00635                     }
00636                 }
00637             } else {
00638                 sprintf(errmsg, "Invalid ID format in start_element_module_build_object()");
00639                 return errmsg;
00640             }
00641         }
00642     }
00643     if((retval = build_object_vect(first, last)) != 0){ /* unable to call constructors */
00644         sprintf(errmsg, "Unable to create objects in start_element_module_build_object()");
00645         return errmsg;
00646     } else {
00647         ;
00648     }
00649     if(attributes.getIndex((const XMLCh *) str_name) < 0){
00650         strcpy(object_name, "(none)");
00651     } else {
00652         wcstombs(object_name, (wchar_t *)attributes.getValue((const XMLCh *) str_name), 64);
00653         object_set_name(obj, object_name);
00654     }
00655     //printf("object: type = %s, id = %s, name = %s\n", object_type, object_id, object_name);
00656     stack_state = OBJECT_STATE;
00657     return NULL;
00658 }
00659 
00660 char *gld_loadHndl::start_element_module(char *buffer, size_t len, const Attributes& attributes){
00661     //  check generic props
00662     if(0 == strcmp(buffer, "object")){
00663         strcpy(propname, "object");
00664         return start_element_module_build_object(attributes);
00665     }/* else if(0 == strcmp(buffer, "major")){
00666         strcpy(propname, "major");
00667         stack_state = MODULE_PROP;
00668     } else if(0 == strcmp(buffer, "minor")){
00669         strcpy(propname, "minor");
00670         stack_state = MODULE_PROP;
00671     } */else if(NULL != module_getvar_addr(this->module, buffer)){  //  check specific props
00672         strcpy(propname, buffer);
00673         stack_state = MODULE_PROP;
00674     } else {
00675         sprintf(errmsg, "Unrecognized keyword in start_element_module(%s)", buffer);
00676         return errmsg;
00677     }
00678     return NULL;
00679 }
00680 
00681 char *gld_loadHndl::start_element_module_prop(char *buffer, size_t len, const Attributes& attributes){
00682     if(module_getvar(this->module, buffer, NULL, -1)){
00683         strcpy(propname, buffer);
00684         stack_state = MODULE_PROP;
00685     }
00686     return NULL;
00687 }
00688 
00689 char *gld_loadHndl::start_element_object(char *buffer, size_t len, const Attributes& attributes){
00690     //  check generic props
00691     if(0 == strcmp(buffer, "parent")){
00692         strcpy(propname, "parent");
00693         stack_state = OBJECT_PROP;
00694     } else if(0 == strcmp(buffer, "root")){
00695         strcpy(propname, "root");
00696         stack_state = OBJECT_PROP;
00697     } else if(0 == strcmp(buffer, "rank")){
00698         strcpy(propname, "rank");
00699         stack_state = OBJECT_PROP;
00700     } else if(0 == strcmp(buffer, "clock")){
00701         strcpy(propname, "clock");
00702         stack_state = OBJECT_PROP;
00703     } else if(0 == strcmp(buffer, "latitude")){
00704         strcpy(propname, "latitude");
00705         stack_state = OBJECT_PROP;
00706     } else if(0 == strcmp(buffer, "longitude")){
00707         strcpy(propname, "longitude");
00708         stack_state = OBJECT_PROP;
00709     } else if(0 == strcmp(buffer, "in")){
00710         strcpy(propname, "in");
00711         stack_state = OBJECT_PROP;
00712     } else if(0 == strcmp(buffer, "out")){
00713         strcpy(propname, "out");
00714         stack_state = OBJECT_PROP;
00715     } else if(0 == strcmp(buffer, "library")){
00716         strcpy(propname, "library");    //  uhm?  an object library?
00717         stack_state = OBJECT_PROP;
00718     }   //  check specific props
00719     else if((prop = class_find_property(oclass, buffer)) != NULL){
00720         strcpy(propname, buffer);
00721         stack_state = OBJECT_PROP;
00722     } else {
00723         sprintf(errmsg, "Unrecognized property in start_element_object(%s)", buffer);
00724         return errmsg;
00725     }
00726     prop = class_find_property(obj->oclass, buffer);    //  prop = NULL is valid for hardcoded properties. -MH
00727     return NULL;
00728 }
00729 
00730 char *gld_loadHndl::start_element_object_prop(char *buffer, size_t len, const Attributes& attributes){
00731     //  we shouldn't be here.
00732     return NULL;
00733 }
00734 
00735 char *gld_loadHndl::start_element_global(char *buffer, size_t len, const Attributes& attributes){
00736     //  check generic props
00737     if(0 == strcmp(buffer, "version_major")){
00738         strcpy(propname, "version_major");
00739         stack_state = GLOBAL_PROP;
00740     } else if(0 == strcmp(buffer, "version_minor")){
00741         strcpy(propname, "version_minor");
00742         stack_state = GLOBAL_PROP;
00743     } else if(0 == strcmp(buffer, "savefilename")){
00744         strcpy(propname, "savefilename");
00745         stack_state = GLOBAL_PROP;
00746     } else if(0 == strcmp(buffer, "class_count")){
00747         strcpy(propname, "class_count");
00748         stack_state = GLOBAL_PROP;
00749     } else if(0 == strcmp(buffer, "object_count")){
00750         strcpy(propname, "object_count");
00751         stack_state = GLOBAL_PROP;
00752     } else if(0 == strcmp(buffer, "property")){ //  check specific props
00753         strcpy(propname, "property");
00754         stack_state = GLOBAL_PROP;
00755     }
00756     //  anything else, we don't care about.
00757     return NULL;
00758 }
00759 
00760 char *gld_loadHndl::start_element_global_prop(char *buffer, size_t len, const Attributes& attributes){
00761     //  we may not supposed to be here?
00762     return NULL;
00763 }
00764 
00765 char *gld_loadHndl::start_element_clock(char *buffer, size_t len, const Attributes& attributes){
00766     if(strcmp(buffer, "tick") == 0){
00767         stack_state = CLOCK_PROP;
00768         strcpy(propname, "tick");
00769     } else if(strcmp(buffer, "timezone") == 0){
00770         stack_state = CLOCK_PROP;
00771         strcpy(propname, "timezone");
00772     } else if(strcmp(buffer, "timestamp") == 0){
00773         stack_state = CLOCK_PROP;
00774         strcpy(propname, "timestamp");
00775     } else {    //  bad keyword
00776         sprintf(errmsg, "Unrecognized keyword in start_element_clock(%s)", buffer);
00777         return errmsg;
00778     }
00779     return NULL;
00780 }
00781 
00782 char *gld_loadHndl::start_element_clock_prop(char *buffer, size_t len, const Attributes& attributes){
00783     return NULL;
00784 }
00785 
00786 #define ADD_KEYWORD(A)  stack_ptr = new gldStack(); \
00787                         strcpy(stack_ptr->object_type, "module"); \
00788                         strcpy(stack_ptr->keyword, (A)); \
00789 
00790 void gld_loadHndl::startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname,
00791                                 const Attributes& attributes){
00792     char buffer[128];
00793     char *temp = NULL;
00794     unsigned int i = 0;
00795     size_t len = 0;
00796     char *retval = 0;   //  negative logic
00797     gldStack *currStack = NULL;
00798     wchar_t str_id[3],  /* = "id", */
00799             str_name[5],/* = "name", */
00800             str_type[5];/* = "type"; */
00801 
00802     mbstowcs(str_id, "id", 3);
00803     mbstowcs(str_name, "name", 5);
00804     mbstowcs(str_type, "type", 5);
00805 
00806     if((len = wcslen((const wchar_t *)qname)) < 1){
00807         output_error("startElement: Unable to parse element tag length!");
00808         load_state = 0;
00809         return;
00810     }
00811     if(wcstombs(buffer, (const wchar_t *)qname, 128) < 1){
00812         output_error("startElement: Unable to convert element tag name from wchar to char!");
00813         load_state = 0;
00814         return;
00815     }
00816     switch(this->stack_state){
00817         case EMPTY:
00818             retval = start_element_empty(buffer, len, attributes);
00819             break;
00820         case LOAD:
00821             retval = start_element_load(buffer, len, attributes);
00822             break;
00823         case MODULE_STATE:
00824             retval = start_element_module(buffer, len, attributes);
00825             break;
00826         case MODULE_PROP:
00827             retval = start_element_module_prop(buffer, len, attributes);
00828             break;
00829         case OBJECT_STATE:
00830             retval = start_element_object(buffer, len, attributes);
00831             break;
00832         case OBJECT_PROP:
00833             retval = start_element_object_prop(buffer, len, attributes);
00834             break;
00835         case GLOBAL_STATE:
00836             retval = start_element_global(buffer, len, attributes);
00837             break;
00838         case GLOBAL_PROP:
00839             retval = start_element_global_prop(buffer, len, attributes);
00840             break;
00841         case CLOCK_STATE:
00842             retval = start_element_clock(buffer, len, attributes);
00843             break;
00844         case CLOCK_PROP:
00845             retval = start_element_clock_prop(buffer, len, attributes);
00846             break;
00847     }
00848     if(retval != NULL){
00849         char tbuff[256];
00850         wchar_t wbuff[256];
00851         SAXParseException *e = NULL;
00852         sprintf(tbuff, "Error in start_element with tag \"%s\": %s", buffer, retval);
00853         mbstowcs(wbuff, tbuff, 1024);
00854         e = new SAXParseException((const XMLCh *)wbuff, *(this->locator));
00855         error(*e);
00856         delete e;
00857     }
00858 }
00859 
00860 #undef ADD_KEYWORD
00861 
00867 char *gld_loadHndl::build_object_vect(int start, int end){
00868     int count = 0, i = 0;
00869     obj_vect.clear();
00870     if(start == end){
00871         if((*oclass->create)(&obj, NULL) == 0){
00872             //output_error("XML_Load: Unable to create a lone object with ID = %i.", start);
00873             sprintf(errmsg, "Unable to create a lone object with ID = %i in build_object_vect(%i, %i)", start, start, end);
00874             load_state = false;
00875             return errmsg;
00876         }
00877         if(start != -1){
00878             if(load_set_index(obj, (OBJECTNUM)end) == 0){
00879                 sprintf(errmsg, "Unable to index an item in build_object_vect(%i, %i)", start, end);
00880                 load_state = false;
00881                 return errmsg;
00882             } else {
00883                 ; /* success*/
00884             }
00885         }
00886         /* successfully created object */
00887         return NULL;
00888     }
00889     if(start == -1){ /* create unindexed objects */
00890         count = end;
00891     } else {
00892         if(last > first){
00893             count = last - first + 1;
00894         } else {
00895             sprintf(errmsg, "last < first, aborting build_object_vect(%i, %i)", start, end);
00896             load_state = false;
00897             return errmsg;
00898         }
00899     }
00900     obj_vect.reserve(count);
00901     for(i = (start == -1) ? 0 : start; i <= last; ++i){ /* "if start == -1, use 0, else use start" */
00902         if((*oclass->create)((obj_vect[i]), NULL) != 0){
00903             if(start != -1){
00904                 if(load_set_index(obj_vect[i], (OBJECTNUM)i) == 0){
00905                     sprintf(errmsg, "Unable to index a batch item in build_object_vect(%i, %i)", start, end);
00906                     load_state = false;
00907                     // cleanup all items?
00908                     return errmsg;
00909                 } 
00910             }
00911         } else { /* failed */
00912             sprintf(errmsg, "Unable to create an object in build_object_vect(%i, %i)", start, end);
00913             load_state = false;
00914             /* cleanup existing objects, if any */
00915             return errmsg;
00916         }
00917     }
00918     return NULL; /* positive logic */
00919 }
00920 
00921 #undef _CRT_SECURE_NO_DEPRECATE
00922 
00923 /* EOF */

GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy