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