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