00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "xml/IFile.h"
00010 #include "xml/XmlParser.h"
00011 #include "xml/Dom.h"
00012 #include "facilities/error.h"
00013 #include "dom/DOM_Document.hpp"
00014
00015
00016 #include <vector>
00017
00018
00019 extern "C" {
00020 FILE *popen(const char *command, const char *type);
00021 }
00022
00023
00024
00025 #include <stdio.h>
00026 #include <ctype.h>
00027 #include <string.h>
00028
00029
00030
00031
00032 namespace xml {
00033
00034 #define LEADING 1
00035 #define ALL 2
00036 #define TRAILING 4
00037
00038
00039
00040 void IFile::printOn (std::ostream& out) {
00041 for (iterator section_map=begin(); section_map!=end(); ++section_map) {
00042 IFile_Section& section = *(*section_map).second;
00043 out << "\n[" << (*section_map).first << "]\n";
00044
00045 for( IFile_Section::iterator item_map = section.begin();
00046 item_map != section.end(); ++item_map){
00047 IFile_Item& item = *(*item_map).second;
00048 out << (*item_map).first << " = " << (item.mystring()) << "\n";
00049 }
00050 }
00051 }
00052
00053 void IFile::print(){printOn(std::cout); std::cout.flush();}
00054
00055
00056 int IFile::stricmp (const char *str1, const char *str2)
00057 {
00058 while ( *str1 && *str2 && toupper(*str1)==toupper(*str2) )
00059 {
00060 str1++;
00061 str2++;
00062 }
00063
00064 return (toupper(*str1) - toupper(*str2));
00065 }
00066
00067
00068 void IFile::stripBlanks (char *str1, const char *str2, int flags)
00069 {
00070 if (flags & ALL)
00071 {
00072 while ( *str2 )
00073 {
00074 if (*str2==' ' || *str2=='\t')
00075 str2++;
00076 else
00077 *str1++ = *str2++;
00078 }
00079 *str1=0;
00080 }
00081 else
00082 {
00083 if (flags & LEADING)
00084 while ( *str2 && (*str2==' ' || *str2=='\t'))
00085 str2++;
00086
00087 strcpy (str1, str2);
00088
00089 if (flags & TRAILING)
00090 {
00091 str1 += strlen (str1);
00092
00093 do str1--; while (*str1==' ' || *str1=='\t');
00094 *++str1 = 0;
00095 }
00096 }
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 void IFile::extractEnvVar(std::string *fileStr) {
00125
00126
00127 int envStart = fileStr->find_first_of("$(");
00128 int envEnd = fileStr->find_first_of(")");
00129
00130
00131 int afterBracket = envStart + 2;
00132
00133 if(!((envStart==-1)||(envEnd==-1)))
00134 {
00135 std::string envVariable = fileStr->substr(afterBracket,(envEnd-afterBracket));
00136 const char * path = ::getenv(envVariable.c_str());
00137 if(path) {
00138 fileStr->replace(envStart,(envEnd+1), path);
00139 }
00140 }
00141 }
00142
00143
00144 IFile::~IFile ()
00145 {
00146 iterator it = begin();
00147 while (it != end())
00148 delete (*it++).second;
00149
00150 }
00151
00152 IFile_Section::~IFile_Section()
00153 {
00154 iterator it = begin();
00155 while (it != end())
00156 delete (*it++).second;
00157 }
00158
00159
00160
00161
00162 IFile::IFile (const DOM_Document& instrument)
00163 {
00164
00165 if (instrument == DOM_Document()) {
00166 FATAL_MACRO("Attempt to construct IFile from null DOM_Document");
00167 return;
00168 }
00169
00170 domToIni(instrument);
00171 }
00172
00173 IFile::IFile (const DOM_Element& instrument)
00174 {
00175
00176 if (instrument == DOM_Element()) {
00177 FATAL_MACRO("Attempt to construct IFile from null DOM_Element");
00178 return;
00179 }
00180
00181 domToIni(instrument);
00182 }
00183
00184
00185
00186 IFile::IFile (const char *filename)
00187 {
00188 XmlParser parser;
00189
00190 std::string filenameStr = filename;
00191 extractEnvVar(&filenameStr);
00192
00193
00194
00195 DOM_Document doc = parser.parse(filenameStr.c_str());
00196
00197
00198 if (doc == DOM_Document()) {
00199 FATAL_MACRO("Attempt to construct IFile from null DOM_Document");
00200 return;
00201 }
00202
00203
00204 domToIni(doc);
00205 }
00206
00207
00208 void IFile::domToIni(const DOM_Document& doc) {
00209 DOM_Element root = doc.getDocumentElement();
00210
00211
00212 domToIni(root);
00213 }
00214
00215 void IFile::domToIni(const DOM_Element& root) {
00216
00217
00218
00219 DOM_NodeList list = root.getElementsByTagName("section");
00220
00221 DOM_Element child;
00222 int nChild = list.getLength();
00223 int iChild;
00224
00225 for (iChild = 0; iChild < nChild; iChild++) {
00226 DOM_Node node = list.item(iChild);
00227
00228 if (node.getParentNode() == root) {
00229 child = DOM_Element(static_cast<DOM_Element &>(node));
00230 addSection(child);
00231 }
00232 }
00233 }
00234
00235
00236 void IFile::addSection(const DOM_Element& section) {
00237 if (!((section.getTagName()).equals("section"))) {
00238 FATAL_MACRO("Expecting tagName==section, found " <<
00239 Dom::transToChar(section.getTagName()) );
00240 }
00241
00242
00243
00244 char* sectName = Dom::transToChar((section.getAttribute("name")));
00245 IFile_Section* curSection = new IFile_Section(sectName);
00246 (*this)[curSection->title()]=curSection;
00247
00248 DOM_NodeList list = section.getChildNodes();
00249 DOM_Element child;
00250 int nChild = list.getLength();
00251 int iChild;
00252
00253 for (iChild = 0; iChild < nChild; iChild++) {
00254 DOM_Node node = list.item(iChild);
00255 if (node.getNodeType() == DOM_Node::ELEMENT_NODE) {
00256 child = DOM_Element(static_cast<DOM_Element &>(node));
00257
00258 if ((child.getTagName()).equals("section")) {
00259 addSection(child);
00260 }
00261 else if ((child.getTagName()).equals("item")) {
00262
00263 std::string itemName(Dom::transToChar(child.getAttribute("name")));
00264 std::string itemValue(Dom::transToChar(child.getAttribute("value")));
00265
00266
00267 IFile_Item* newItem =
00268 new IFile_Item(itemName, itemValue);
00269
00270 (*curSection)[newItem->title()]= newItem;
00271 }
00272 else {
00273 char *tag = Dom::transToChar(child.getTagName());
00274 FATAL_MACRO("unexpected tag in initialization:" << tag);
00275 }
00276 }
00277 }
00278
00279 }
00280
00281
00282 bool IFile::contains (const char *section, const char *item)
00283 {
00284 return (IFile::_getstring (section, item, 0) != 0);
00285 }
00286
00287
00288
00289 const char *IFile::_getstring(const char *sectionname, const char *itemname,
00290 int failFlag)
00291 {
00292 char hitem[1000], hsection[1000];
00293 IFile_Item *item = 0;
00294 IFile_Section *section =0;
00295
00296 stripBlanks (hitem, itemname, ALL);
00297 stripBlanks (hsection, sectionname, ALL);
00298
00299 const_iterator entry = find(std::string(hsection));
00300
00301 if (entry != end() ) {
00302 section = (*entry).second;
00303
00304 IFile_Section::const_iterator it = section->find(std::string(hitem));
00305 item = (it != section->end() ) ?item = (*it).second : 0;
00306
00307 }
00308
00309 if (item != 0) {
00310 #ifdef DEBUG
00311 INFO ("getstring: [" << hsection << "]" << hitem << ": ->" <<
00312 (item->string()) << "<-");
00313 #endif
00314 return item->mystring().c_str();
00315 }
00316 else if (failFlag)
00317 {
00318 if (section == 0)
00319 FATAL_MACRO ("cannot find section [" << sectionname << "]");
00320 else
00321 FATAL_MACRO ("cannot find item \"" << itemname << "\" in section [" <<
00322 sectionname << "]");
00323 return 0;
00324 }
00325
00326 else return 0;
00327 }
00328
00329
00330
00331 const char *IFile::getString (const char *section, const char *item)
00332 {
00333 return _getstring(section, item);
00334 }
00335
00336
00337
00338 void IFile::setString(const char *sectionname, const char *itemname,
00339 const char* newString)
00340 {
00341 char hitem[1000], hsection[1000];
00342 IFile_Item *item =0;
00343 IFile_Section *section=0;
00344
00345 stripBlanks (hitem, itemname, ALL);
00346 stripBlanks (hsection, sectionname, ALL);
00347
00348 iterator it = find(std::string(hsection));
00349
00350 if ( it != end() ) {
00351 section = (*it).second;
00352
00353 if (section->contains(hitem) )
00354 item = section->lookUp(hitem);
00355 }
00356
00357 if (item) item->mystring()=newString;
00358 }
00359
00360
00361 double IFile::getDouble (const char *section, const char *item)
00362 {
00363 double hf;
00364 std::string hilf (IFile::_getstring (section, item));
00365
00366 if (sscanf(hilf.c_str(), "%le", &hf) != 1)
00367 FATAL_MACRO ("[" << section << "]" << item << " = \'" << hilf <<
00368 "\' cannot be converted to double");
00369
00370 return hf;
00371 }
00372
00373
00374
00375 int IFile::getInt (const char *section, const char *item)
00376 {
00377 int hf;
00378 std::string hilf (IFile::_getstring (section, item));
00379
00380 if (sscanf(hilf.c_str(), "%d", &hf) != 1)
00381 FATAL_MACRO ("[" << section << "]" << item << " = \'" << hilf <<
00382 "\' cannot be converted to int");
00383
00384 return (hf);
00385 }
00386
00387
00388
00389 int IFile::getBool (const char *section, const char *item)
00390 {
00391 std::string hilf (IFile::_getstring (section, item));
00392
00393 if (hilf == "yes")
00394 return (1);
00395 else if (hilf == "true")
00396 return (1);
00397 else if (hilf == "1")
00398 return (1);
00399 else if (hilf == "no")
00400 return (0);
00401 else if (hilf == "false")
00402 return (0);
00403 else if (hilf == "0")
00404 return (0);
00405 else
00406 FATAL_MACRO ("[" << section << "]" << item << " = \'" << hilf <<
00407 "\' is not boolean");
00408 return (0);
00409 }
00410
00411
00412
00413 IFile::intVector IFile::getIntVector (const char *section, const char *item)
00414 {
00415 intVector iv;
00416 char buffer[1024];
00417
00418 strncpy(buffer, IFile::_getstring(section,item), sizeof(buffer) -1);
00419 if ( strlen(buffer) >= sizeof(buffer) ) {
00420 FATAL_MACRO("string returned from _getstring is too long");
00421 return iv;
00422 }
00423
00424 char *vString = strtok(buffer,"}");
00425 vString = strtok(buffer,"{");
00426
00427 char *test = strtok(vString,",");
00428 while (test != NULL) {
00429 iv.push_back(atoi(test));
00430 test = strtok((char*)NULL,",");
00431 }
00432 if (iv.size() <= 0) {
00433 std::string hilf (buffer);
00434 FATAL_MACRO ("[" << section << "]" << item << " = \'"
00435 << hilf << "\' is not an integer vector");
00436 }
00437 return (iv);
00438 }
00439
00440
00441 IFile::doubleVector IFile::getDoubleVector (const char *section,
00442 const char *item)
00443 {
00444 doubleVector dv;
00445 char buffer[1024];
00446
00447 strncpy(buffer, IFile::_getstring(section,item), sizeof(buffer) );
00448 if (strlen(buffer) >= sizeof(buffer) ) {
00449 FATAL_MACRO("string from _getstring() too long");
00450 return dv;
00451 }
00452 char *vString = strtok(buffer,"}");
00453 vString = strtok(buffer,"{");
00454
00455 char *test = strtok(vString,",");
00456 while (test != NULL) {
00457 dv.push_back(atof(test));
00458 test = strtok((char*)NULL,",");
00459 }
00460 if (dv.size() <= 0) {
00461 std::string hilf (buffer);
00462 FATAL_MACRO ("[" << section << "]" << item << " = \'"
00463 << hilf << "\' is not an double vector");
00464 }
00465 return (dv);
00466 }
00467
00468
00469
00470 int IFile::getInt (const char *section, const char *item, int defValue) {
00471 return ( contains(section, item) )? getInt( section, item ):defValue;
00472 }
00473
00474 int IFile::getBool (const char *section, const char *item, int defValue)
00475 {
00476 return ( contains(section, item) )? getBool( section, item ):defValue;
00477 }
00478
00479 double IFile::getDouble(const char *section, const char *item,
00480 double defValue) {
00481 return ( contains(section, item) )? getDouble( section, item ):defValue;
00482 }
00483
00484 const char *IFile::getString (const char *section, const char *item,
00485 const char *defValue) {
00486 return ( contains(section, item) )? getString( section, item ):defValue;
00487 }
00488
00489 IFile::intVector IFile::getIntVector (const char *section, const char *item,
00490 intVector defValues) {
00491 return (contains(section, item))? getIntVector(section, item)
00492 : defValues;
00493 }
00494
00495 IFile::doubleVector IFile::getDoubleVector (const char *section,
00496 const char *item,
00497 doubleVector defValues) {
00498 return (contains(section, item))? getDoubleVector(section, item):defValues;
00499 }
00500 }
00501