CGEM BOSS 6.6.5.g
BESIII Offline Software System
Loading...
Searching...
No Matches
IFile.cxx
Go to the documentation of this file.
1// $Header: /bes/bes/BossCvs/Calibration/xmlBase/src/IFile.cxx,v 1.1.1.1 2005/10/17 06:10:27 maqm Exp $
2
3
4#include "xmlBase/IFile.h"
5#include "xmlBase/XmlParser.h"
6#include "xmlBase/Dom.h"
7#include "facilities/Util.h" // for expandEnvVar
8#include <xercesc/dom/DOMDocument.hpp>
9
10#include <sstream>
11#include <vector>
12#include <cstdio>
13#include <string>
14#include <cctype>
15
16#define FATAL_MACRO(output) std::cerr << output;throw(IFileException(output))
17
18// globals
19
20namespace xmlBase {
21
22XERCES_CPP_NAMESPACE_USE
23
24#define LEADING 1
25#define ALL 2
26#define TRAILING 4
27
28
29 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
30 void IFile::printOn (std::ostream& out) {
31 for (iterator section_map=begin(); section_map!=end(); ++section_map) {
32 IFile_Section& section = *(*section_map).second;
33 out << "\n[" << (*section_map).first << "]\n";
34
35 for( IFile_Section::iterator item_map = section.begin();
36 item_map != section.end(); ++item_map){
37 IFile_Item& item = *(*item_map).second;
38 out << (*item_map).first << " = " << (item.mystring()) << "\n";
39 }
40 }
41 }
42
43 void IFile::print(){printOn(std::cout); std::cout.flush();}
44
45 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46 int IFile::stricmp (const char *str1, const char *str2)
47 {
48 while ( *str1 && *str2 && toupper(*str1)==toupper(*str2) )
49 {
50 str1++;
51 str2++;
52 }
53
54 return (toupper(*str1) - toupper(*str2));
55 }
56
57 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58 void IFile::stripBlanks (char *str1, const char *str2, int flags)
59 {
60 if (flags & ALL)
61 {
62 while ( *str2 )
63 {
64 if (*str2==' ' || *str2=='\t')
65 str2++;
66 else
67 *str1++ = *str2++;
68 }
69 *str1=0;
70 }
71 else
72 {
73 if (flags & LEADING)
74 while ( *str2 && (*str2==' ' || *str2=='\t'))
75 str2++;
76
77 strcpy (str1, str2);
78
79 if (flags & TRAILING)
80 {
81 str1 += strlen (str1);
82
83 do str1--; while (*str1==' ' || *str1=='\t');
84 *++str1 = 0;
85 }
86 }
87 }
88
89 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
91 {
92 iterator it = begin();
93 while (it != end())
94 delete (*it++).second;
95
96 }
97 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99 {
100 iterator it = begin();
101 while (it != end())
102 delete (*it++).second;
103 }
104
105 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
106 IFile::IFile (const DOMDocument* doc)
107 {
108 // check that argument is non-null
109 if (doc == 0) {
110 // FATAL_MACRO("Attempt to construct IFile from null DOMDocument");
111 std::cerr << "Attempt to construct IFile from null DOMDocument"
112 << std::endl;
113 std::cerr.flush();
114 exit(1);
115 }
116 // If so, call service to do the actual work
117 domToIni(doc);
118 }
119
120 IFile::IFile (const DOMElement* doc)
121 {
122 // check that argument is non-null
123 if (doc == 0) {
124 // FATAL_MACRO("Attempt to construct IFile from null DOMElement");
125 std::cerr << "Attempt to construct IFile from null DOMDocument"
126 << std::endl;
127 std::cerr.flush();
128 exit(1);
129 }
130 // If so, call service to do the actual work
131 domToIni(doc);
132 }
133
134
135 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
136 IFile::IFile (const char *filename)
137 {
138 using facilities::Util;
139
140 XmlParser parser;
141
142 parser.doSchema(true);
143
144 std::string filenameStr = filename;
145 Util::expandEnvVar(&filenameStr);
146
147 // What if this fails (e.g., file doesn't exist or is not
148 // well-formed)?? How to report it?
149 DOMDocument* doc = parser.parse(filenameStr.c_str());
150
151 // Check it's a good doc.
152 if (doc == 0) {
153 std::cerr << "Attempt to construct IFile from null DOMDocument"
154 << std::endl;
155 std::cerr.flush();
156 exit(1);
157 // FATAL_MACRO("Attempt to construct IFile from null DomDocument");
158 }
159
160 // If so, initialize IFile from it
161 domToIni(doc);
162 }
163
164 // Work of constructor minus parsing
165 void IFile::domToIni(const DOMDocument* doc) {
166 DOMElement* root = doc->getDocumentElement();
167
168 // Now invoke element version to do the work
169 domToIni(root);
170 }
171
172 void IFile::domToIni(const DOMElement* root) {
173 // Done this way, any child elements which are *not* sections
174 // will simply be ignored. Another strategy would be to look
175 // at all children and complain if any are not sections
176 std::vector<DOMElement*> sections;
177 Dom::getChildrenByTagName(root, "section", sections);
178 unsigned int nChild = sections.size();
179
180 for (unsigned int iChild = 0; iChild < nChild; iChild++) {
181 addSection(sections[iChild]);
182 }
183 }
184
185 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
186 void IFile::addSection(const DOMElement* section) {
187 std::string tagName = Dom::getTagName(section);
188
189 if (tagName.compare("section") ) {
190 std::string errorString =
191 "Expecting tagName==section, found " + tagName;
192 FATAL_MACRO(errorString);
193 }
194
195 // start a section
196 std::string sectName = Dom::getAttribute(section, "name");
197 IFile_Section* curSection = new IFile_Section(sectName);
198 (*this)[curSection->title()]=curSection;
199
200 std::vector<DOMElement*> children;
201
202 Dom::getChildrenByTagName(section, "*", children);
203
204 unsigned int nChild = children.size();
205 for (unsigned int iChild = 0; iChild < nChild; iChild++) {
206 DOMElement* child = children[iChild];
207 std::string tagName = Dom::getTagName(child);
208 if (!(tagName.compare("section")) ) {
209 addSection(child);
210 }
211 else if (!(tagName.compare("item")) ) {
212 std::string itemName = Dom::getAttribute(child, "name");
213 std::string itemValue = Dom::getAttribute(child, "value");
214
215 // Make the new item
216 IFile_Item* newItem =
217 new IFile_Item(itemName, itemValue);
218 // Add it to the section map
219 (*curSection)[newItem->title()]= newItem;
220 }
221 else {
222 std::string errorString = "unexpected tag in initialization:"
223 + tagName;
224 FATAL_MACRO(errorString);
225 } // end if..else
226 } // end for
227
228 }
229
230 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
231 bool IFile::contains (const char *section, const char *item)
232 {
233 return (IFile::_getstring (section, item, 0) != 0);
234 }
235
236
237 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
238 const char *IFile::_getstring(const char *sectionname, const char *itemname,
239 int failFlag)
240 {
241 char hitem[1000], hsection[1000];
242 IFile_Item *item = 0;
243 IFile_Section *section =0;
244
245 stripBlanks (hitem, itemname, ALL);
246 stripBlanks (hsection, sectionname, ALL);
247
248 const_iterator entry = find(std::string(hsection));
249
250 if (entry != end() ) {
251 section = (*entry).second;
252
253 IFile_Section::const_iterator it = section->find(std::string(hitem));
254 item = (it != section->end() ) ?item = (*it).second : 0;
255
256 }
257
258 if (item != 0) {
259#ifdef DEBUG
260 INFO ("getstring: [" << hsection << "]" << hitem << ": ->" <<
261 (item->string()) << "<-");
262#endif
263 return item->mystring().c_str();
264 }
265 else if (failFlag)
266 {
267 if (section == 0) {
268 std::string errorString =
269 std::string("cannot find section [") + sectionname + "]";
270 FATAL_MACRO (errorString);
271 }
272 else {
273 std::string errorString =
274 std::string("cannot find item '") + itemname + "' in section ["
275 + sectionname + "]";
276 FATAL_MACRO (errorString);
277 }
278 return 0;
279 }
280
281 else return 0;
282 }
283
284 // getting data from [section]item, exiting when not found
285 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
286 const char *IFile::getString (const char *section, const char *item)
287 {
288 return _getstring(section, item);
289 }
290
291 // setting data in [section]
292 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
293 void IFile::setString(const char *sectionname, const char *itemname,
294 const char* newString)
295 {
296 char hitem[1000], hsection[1000];
297 IFile_Item *item =0;
298 IFile_Section *section=0;
299
300 stripBlanks (hitem, itemname, ALL);
301 stripBlanks (hsection, sectionname, ALL);
302
303 iterator it = find(std::string(hsection));
304
305 if ( it != end() ) {
306 section = (*it).second;
307
308 if (section->contains(hitem) )
309 item = section->lookUp(hitem);
310 }
311
312 if (item) item->mystring()=newString;
313 }
314
315 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
316 double IFile::getDouble (const char *section, const char *item)
317 {
318 // double hf;
319 std::string hilf (IFile::_getstring (section, item));
320
321 try {
323 }
324 catch (facilities::WrongType ex) {
325 std::cerr << ("from xmlBase::IFile::getDouble ") << std::endl;
326 // FATAL_MACRO
327 std::cerr << ex.getMsg() << std::endl;
328 throw(IFileException(" "));
329 }
330 }
331
332
333 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
334 int IFile::getInt (const char *section, const char *item)
335 {
336 // int hf;
337 std::string hilf (IFile::_getstring (section, item));
338
339 try {
341 }
342 catch (facilities::WrongType ex) {
343 std::cerr << ("from xmlBase::IFile::getInt ") << std::endl;
344 std::cerr << ex.getMsg() << std::endl;
345 throw(IFileException(" "));
346 }
347 }
348
349
350 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
351 int IFile::getBool (const char *section, const char *item)
352 {
353 std::string hilf (IFile::_getstring (section, item));
354
355 if (hilf == "yes")
356 return (1);
357 else if (hilf == "true")
358 return (1);
359 else if (hilf == "1")
360 return (1);
361 else if (hilf == "no")
362 return (0);
363 else if (hilf == "false")
364 return (0);
365 else if (hilf == "0")
366 return (0);
367 else {
368 std::string errorString("[");
369 errorString += section + std::string("]") + item + " = \'" + hilf
370 + "\' is not boolean";
371 FATAL_MACRO (errorString);
372 return (0);
373 }
374 }
375
376
377 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
378 IFile::intVector IFile::getIntVector (const char *section, const char *item)
379 {
380 intVector iv;
381 char buffer[1024];
382
383 strncpy(buffer, IFile::_getstring(section,item), sizeof(buffer) -1);
384 if ( strlen(buffer) >= sizeof(buffer) ) {
385 FATAL_MACRO("string returned from _getstring is too long");
386 return iv;
387 }
388
389 char *vString = strtok(buffer,"}");
390 vString = strtok(buffer,"{");
391
392 char *test = strtok(vString,",");
393 while (test != NULL) {
394 iv.push_back(atoi(test));
395 test = strtok((char*)NULL,",");
396 }
397 if (iv.size() <= 0) {
398 std::string hilf (buffer);
399 std::string errorString("[");
400 errorString += section + std::string("]") + item + " = \'"
401 + hilf + "\' is not an integer vector";
402 FATAL_MACRO (errorString);
403
404 }
405 return (iv);
406 }
407
408 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
410 const char *item)
411 {
412 doubleVector dv;
413 char buffer[1024];
414
415 strncpy(buffer, IFile::_getstring(section,item), sizeof(buffer) );
416 if (strlen(buffer) >= sizeof(buffer) ) {
417 FATAL_MACRO("string from _getstring() too long");
418 return dv;
419 }
420 char *vString = strtok(buffer,"}");
421 vString = strtok(buffer,"{");
422
423 char *test = strtok(vString,",");
424 while (test != NULL) {
425 dv.push_back(atof(test));
426 test = strtok((char*)NULL,",");
427 }
428 if (dv.size() <= 0) {
429 std::string hilf (buffer);
430 std::string errorString("[");
431 errorString += section + std::string("]") + item + " = \'"
432 + hilf + "\' is not an double vector";
433 FATAL_MACRO (errorString);
434 }
435 return (dv);
436 }
437
438 // getting data from [section]item, with def. values provided
439 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
440 int IFile::getInt (const char *section, const char *item, int defValue) {
441 return ( contains(section, item) )? getInt( section, item ):defValue;
442 }
443 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
444 int IFile::getBool (const char *section, const char *item, int defValue)
445 {
446 return ( contains(section, item) )? getBool( section, item ):defValue;
447 }
448 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
449 double IFile::getDouble(const char *section, const char *item,
450 double defValue) {
451 return ( contains(section, item) )? getDouble( section, item ):defValue;
452 }
453 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
454 const char *IFile::getString (const char *section, const char *item,
455 const char *defValue) {
456 return ( contains(section, item) )? getString( section, item ):defValue;
457 }
458 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
459 IFile::intVector IFile::getIntVector (const char *section, const char *item,
460 intVector defValues) {
461 return (contains(section, item))? getIntVector(section, item)
462 : defValues;
463 }
464 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
466 const char *item,
467 doubleVector defValues) {
468 return (contains(section, item))? getDoubleVector(section, item):defValues;
469 }
470} // end namespace xmlBase
471
std::string test
Definition: CalibModel.cxx:43
std::string root
Definition: CalibModel.cxx:39
@ INFO
Definition: EvtReport.hh:52
#define LEADING
Definition: IFile.cxx:24
#define ALL
Definition: IFile.cxx:25
#define TRAILING
Definition: IFile.cxx:26
static double stringToDouble(const std::string &InStr)
static int stringToInt(const std::string &InStr)
Exception class used when converting from string to numeric type.
static std::string getTagName(const DOMElement *node)
Definition: Dom.cxx:142
static void getChildrenByTagName(const DOMElement *parent, const std::string &tagName, std::vector< DOMElement * > &children, bool clear=true)
Definition: Dom.cxx:160
static std::string getAttribute(const DOMElement *elt, const char *attName)
Definition: Dom.cxx:222
std::string & mystring()
Definition: IFile.h:49
virtual int getInt(const char *section, const char *item)
Definition: IFile.cxx:334
std::vector< double > doubleVector
Definition: IFile.h:95
void setString(const char *section, const char *item, const char *newString)
Definition: IFile.cxx:293
void print()
Definition: IFile.cxx:43
virtual intVector getIntVector(const char *section, const char *item)
Definition: IFile.cxx:378
std::vector< int > intVector
Definition: IFile.h:94
virtual bool contains(const char *section, const char *item)
Definition: IFile.cxx:231
static void stripBlanks(char *str1, const char *str2, int flags)
Definition: IFile.cxx:58
virtual doubleVector getDoubleVector(const char *section, const char *item)
Definition: IFile.cxx:409
friend class IFile_Item
Definition: IFile.h:138
friend class IFile_Section
Definition: IFile.h:137
virtual const char * getString(const char *section, const char *item)
Definition: IFile.cxx:286
virtual double getDouble(const char *section, const char *item)
Definition: IFile.cxx:316
virtual ~IFile()
Definition: IFile.cxx:90
virtual void printOn(std::ostream &out=std::cout)
Definition: IFile.cxx:30
static int stricmp(const char *str1, const char *str2)
Definition: IFile.cxx:46
virtual int getBool(const char *section, const char *item)
Definition: IFile.cxx:351
DOMDocument * parse(const char *const filename, const std::string &docType=std::string(""))
Parse an xml file, returning document node if successful.
Definition: XmlParser.cxx:108
void doSchema(bool doit)
Call this method to turn on schema processing (else it's off)
Definition: XmlParser.cxx:92