ATLAS Offline Software
IOVDbParser.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // IOVDbParser.cxx
6 // implementation for simple XML parser for IOVDbSvc
7 
8 #include "GaudiKernel/MsgStream.h"
9 #include "IOVDbParser.h"
10 #include "IOVDbStringFunctions.h"
11 
12 IOVDbParser::IOVDbParser(const std::string & input, MsgStream& log) :
13  m_valid(true)
14 {
15  // parse the input string as XML, decode into Key/Value pairs
16  m_keys.clear();
17  // slot for the data outside of XML
18  m_keys[""]="";
19  // work through the string to build list of tags
20  std::string::size_type iofs=0;
21  std::string::size_type len=input.size();
22  while (iofs!=std::string::npos && iofs<len) {
23  // look for the start of the next XML tag
24  std::string::size_type iofs1=input.find('<',iofs);
25  if (iofs1>iofs && iofs1!=std::string::npos) {
26  // take any unmarked-up text into the 'outside' data slot
27  m_keys[""]+=IOVDbNamespace::spaceStrip(input.substr(iofs,iofs1-iofs));
28  }
29  if (iofs1!=std::string::npos) {
30  // have an opening XML tag - process it
31  // first find the end of the tag, either '>' or ' ', whichever first
32  std::string::size_type iofs2=input.find('>',iofs1);
33  std::string::size_type iofs3=input.find("/>",iofs1);
34  bool noClosingTag = (iofs2 == std::string::npos);
35  if (noClosingTag){
36  log << MSG::FATAL <<
37  "Badly formed XML string, no closing tag in " << input << endmsg;
38  m_valid=false;
39  iofs=std::string::npos;
40  return;
41  }
42  if (iofs2!=std::string::npos && iofs2<iofs3) {
43  // found a closing >, so tag is standard <tag>value</tag> form
44  std::string tag=IOVDbNamespace::spaceStrip(input.substr(iofs1+1,iofs2-iofs1-1));
45  // now need to find the closing </tag>
46  std::string::size_type iofs4=input.find("</"+tag,iofs2+1);
47  if (iofs4!=std::string::npos) {
48  // found closing tag, store tag and text
49  m_keys[tag]=IOVDbNamespace::spaceStrip(input.substr(iofs2+1,iofs4-iofs2-1));
50  // advance to the next part of the string, after '>' on closing tag
51  iofs=input.find('>',iofs4);
52  if (iofs == std::string::npos) {
53  log << MSG::FATAL <<
54  "Badly formed XML string, no closing tag in " << input << endmsg;
55  m_valid=false;
56  iofs=std::string::npos;
57  return;
58  } else {
59  iofs+=1;
60  }
61  } else {
62  log << MSG::FATAL <<
63  "Badly formed XML string, no closing tag in " << input << endmsg;
64  m_valid=false;
65  iofs=std::string::npos;
66  return;
67  }
68  } else if (iofs3!=std::string::npos) {
69  // found a />, so tag is of form <tag values info/>
70  // find the end of the tag part to see if a value is present
71  std::string::size_type iofs4=input.find(' ',iofs1+1);
72  std::string value,tag;
73  if (iofs4!=std::string::npos && iofs4<iofs3) {
74  value=IOVDbNamespace::spaceStrip(input.substr(iofs4,iofs3-iofs4));
75  tag=IOVDbNamespace::spaceStrip(input.substr(iofs1+1,iofs4-iofs1-1));
76  } else {
77  tag=input.substr(iofs1+1,iofs3-iofs1-1);
78  value="";
79  }
81  // advance to next part of string after closing />
82  iofs=iofs3+2;
83  } else {
84  // found a < but no closing >
85  log << MSG::FATAL << "Badly formed XML string, no closing > in input " <<
86  input << endmsg;
87  iofs=std::string::npos;
88  m_valid=false;
89  return;
90  }
91  } else {
92  // no more < in input, take the rest into 'outside' data slot
93  m_keys[""]+=IOVDbNamespace::spaceStrip(input.substr(iofs));
94  iofs=len;
95  }
96  }
97  this->clean(); //rectify obsolete key names
98  if (log.level()<=MSG::VERBOSE) {
99  log << MSG::VERBOSE << "parseXML processed input string: " << input << endmsg;
100  for (KeyValMap::const_iterator itr=m_keys.begin();itr!=m_keys.end();++itr) {
101  log << MSG::VERBOSE << "Key: " << itr->first << " value:" <<
102  itr->second << endmsg;
103  }
104  }
105 }
106 
107 bool
108 IOVDbParser::getKey(const std::string& key, const std::string& defvalue,
109  std::string& value) const {
110  // check if key is present in keyval, if so set value to it
111  // if not set value to supplied default
112  // return true or false depending on whether a matching key was found
113  if (!m_valid) {
114  value=defvalue;
115  return false;
116  }
117  const auto [theValue,found] = at(key,defvalue);
118  value=theValue;
119  return found;
120 }
121 
122 std::pair<std::string, bool>
123 IOVDbParser::at(const std::string & searchKey, const std::string &defaultValue) const{
124  KeyValMap::const_iterator it = m_keys.find(searchKey);
125  if (it != m_keys.end()) {
126  //may contain return or newline character
127  return std::pair<std::string, bool>(IOVDbNamespace::spaceStrip(it->second), true);
128  }
129  return std::pair<std::string, bool> (defaultValue, false);
130 }
131 
132 std::string
134  return at("").first;
135 }
136 
137 std::string
139  return at("key",folderName()).first;
140 }
141 
142 bool
144  return at("key").second;
145 }
146 
147 std::string
149  return at("tag").first;
150 }
151 
152 std::string
154  return at("eventStoreName","StoreGateSvc").first;
155 }
156 
157 bool
159  return (at("timeStamp").first=="time");
160 }
161 
162 std::string
164  return at("cache").first;
165 }
166 
167 int
169  auto valuePair=at("cachehint");
170  return valuePair.second ? std::stoi(valuePair.first) : 0;
171 }
172 
173 bool
175  return at("named").second;
176 }
177 
178 bool
180  return at("metaOnly").second;
181 }
182 
183 bool
185  return at("extensible").second;
186 }
187 
188 
189 CLID
190 IOVDbParser::classId(MsgStream& msg) const{
191  CLID result{};
192  auto [addrHeader,foundHeader]=at("addrHeader");
193  if (foundHeader) {
195  msg << MSG::DEBUG <<"Decode addrHeader "<< addrHeader << endmsg;
196  IOVDbParser addrH(addrHeader,msg);
197  if (auto addrPair=addrH.at("address_header");addrPair.second) {
198  result = IOVDbNamespace::parseClid(addrPair.first);
199  msg << MSG::DEBUG << "Got CLID " << result << " from " << addrPair.first << endmsg;
200  }
201  }
202  return result;
203 }
204 
205 std::string
207  return at("addrHeader").first;
208 }
209 
210 std::vector<std::string>
212  const auto & symLinkString = at("symlinks").first;
213  return IOVDbNamespace::parseLinkNames(symLinkString);
214 }
215 
216 bool
218  return at("noover").second;
219 }
220 
221 
223  auto it=m_keys.find("dbConnection");
224  if (it!=m_keys.end()) {
225  std::string connection=std::move(it->second);
226  m_keys.erase(it);
227  m_keys["db"]=std::move(connection);
228  }
229  }
230 
231 
232 unsigned
234  unsigned keyCounter=0;
235  for (const auto& otherKeyValue : other.m_keys) {
236  const std::string& otherKey=otherKeyValue.first;
237  const std::string& otherValue=otherKeyValue.second;
238  if (otherKey.empty()) continue; //Ignore Foldername
239  if (otherKey=="prefix") continue; //Ignore prefix
240  KeyValMap::iterator it=m_keys.find(otherKey);
241  if (it==m_keys.end()) {
242  log << MSG::INFO << "Folder " << m_keys[""] << ", adding new key " << otherKey
243  << " with value " << otherValue << endmsg;
244  m_keys[otherKey]=otherValue;
245  }
246  else {
247  log << MSG::INFO << "Folder " << m_keys[""] << ", Key: " << otherKey
248  << "Overriding existing value " << m_keys[otherKey] << " to new value " << otherValue << endmsg;
249  it->second=otherValue;
250  }
251  ++keyCounter;
252  } //End loop over keys in other
253  return keyCounter;
254 }
255 
256 bool
258  return ((this->m_keys) == other.m_keys);
259 }
260 
261 bool
262 IOVDbParser::overridesIov(MsgStream& msg) const{
263  //no check on folder time unit compatibility
264  return overridesIovImpl(msg, false);
265 }
266 
267 bool
268 IOVDbParser::overridesIov(MsgStream& msg, const bool folderIs_nsOfEpoch) const {
269  //check folder time unit compatibility
270  return overridesIovImpl(msg ,true, folderIs_nsOfEpoch);
271 }
272 
273 bool
274 IOVDbParser::overridesIovImpl(MsgStream& msg, const bool performFolderCheck,const bool folderIs_nsOfEpoch) const{
275  bool overrideIs_nsEpochIov{true};
276  const bool overridingTimestamp=(m_keys.find("forceTimestamp")!=m_keys.end());
277  const bool overridingRun=(m_keys.find("forceRunNumber")!=m_keys.end());
278  const bool overridingLumi=(m_keys.find("forceLumiblockNumber")!=m_keys.end());
279  //check for nonsense scenarios:
280  //1. overriding Lumi but not the Run number
281  if (overridingLumi and not overridingRun){
282  msg << MSG::WARNING<<"Trying to override lumi block without specifying the run"<<endmsg;
283  return false;
284  }
285  //2. Trying to override both
286  if (overridingRun and overridingTimestamp){
287  msg << MSG::WARNING<<"Trying to override using both run-lumi and ns timestamp"<<endmsg;
288  return false;
289  }
290  // now we are consistent, so set the 'is_ns' variable if it's different from default
291  if (overridingRun) overrideIs_nsEpochIov=false;
292  //3. Overriding a folder in ns format with a run-lumi IOV, or folder in run-lumi with ns timestamp
293  if (performFolderCheck and (overrideIs_nsEpochIov != folderIs_nsOfEpoch)){
294  msg << MSG::WARNING<<"Trying to override run-lumi for a ns folder, or ns for a run-lumi folder"<<endmsg;
295  return false;
296  }
297  return (overridingTimestamp or overridingRun);
298 }
299 
300 unsigned long long
302  unsigned long long value{};
303  if (not overridesIov(msg)) return value;
304  auto pTsPair = m_keys.find("forceTimestamp");
305  if (pTsPair!=m_keys.end()){
306  value = IOVDbNamespace::iovFromTimeString(pTsPair->second);
307  }
308  else {
309  auto pRunPair = m_keys.find("forceRunNumber");
310  auto pLumiPair = m_keys.find("forceLumiblockNumber");
311  const auto & runString = (pRunPair!=m_keys.end()) ? pRunPair->second : "";
312  const auto & lumiString = (pLumiPair!=m_keys.end()) ? pLumiPair->second : "";
313  //could check that values were actually given here
315  }
316  return value;
317 }
318 
319 std::string
321  std::stringstream retval;
322  retval <<"Folder:";
323  retval << folderName();
324  retval << ", Attributes: ";
325  auto it=m_keys.begin();
326  auto it_e=m_keys.end();
327  for (;it!=it_e;++it) {
328  if (it->first.empty()) continue;
329  retval << "[" << it->first << ":" << it->second << "] ";
330  }
331  return retval.str();
332 
333 }
334 MsgStream& operator<<(MsgStream& os, const IOVDbParser& fldr) {
335  os << fldr.toString();
336  return os;
337 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
IOVDbParser::noTagOverride
bool noTagOverride() const
Definition: IOVDbParser.cxx:217
IOVDbNamespace::spaceStrip
std::string spaceStrip(const std::string &input)
Trim leading and trailing spaces,return a new trimmed string.
Definition: IOVDbStringFunctions.cxx:11
operator<<
MsgStream & operator<<(MsgStream &os, const IOVDbParser &fldr)
Definition: IOVDbParser.cxx:334
IOVDbParser::operator==
bool operator==(const IOVDbParser &other) const
Definition: IOVDbParser.cxx:257
get_generator_info.result
result
Definition: get_generator_info.py:21
python.Constants.FATAL
int FATAL
Definition: Control/AthenaCommon/python/Constants.py:19
IOVDbParser::cachehint
int cachehint() const
Definition: IOVDbParser.cxx:168
skel.it
it
Definition: skel.GENtoEVGEN.py:396
IOVDbParser::onlyReadMetadata
bool onlyReadMetadata() const
Definition: IOVDbParser.cxx:179
athena.value
value
Definition: athena.py:124
IOVDbParser::overridesIov
bool overridesIov(MsgStream &msg) const
return true if this description overrides the timestamp or runlumi
Definition: IOVDbParser.cxx:262
IOVDbNamespace::iovFromTimeString
unsigned long long iovFromTimeString(const std::string &iovString)
Take a string integer giving a time in seconds and convert it to a ULL in nanoseconds.
Definition: IOVDbStringFunctions.cxx:31
IOVDbParser::m_valid
bool m_valid
Definition: IOVDbParser.h:59
IOVDbNamespace::parseLinkNames
std::vector< std::string > parseLinkNames(const std::string &linktext)
Parse string of format "A:X::B:C" to "A" , "X::B", "C".
Definition: IOVDbStringFunctions.cxx:178
IOVDbParser::named
bool named() const
Definition: IOVDbParser.cxx:174
IOVDbNamespace::replaceServiceType71
bool replaceServiceType71(std::string &addrHeader)
Definition: IOVDbStringFunctions.cxx:212
LArCellBinning_test.retval
def retval
Definition: LArCellBinning_test.py:112
IOVDbStringFunctions.h
LArConditions2Ntuple.fldr
string fldr
Definition: LArConditions2Ntuple.py:235
IOVDbNamespace::iovFromLumiBlockString
unsigned long long iovFromLumiBlockString(const std::string &lbString)
String representation of lumiblock just converted to LL (as in original code) and returned as a ULL.
Definition: IOVDbStringFunctions.cxx:45
IOVDbParser::at
std::pair< std::string, bool > at(const std::string &searchKey, const std::string &defaultValue="") const
'at' accessor with an optional default; the bool is true if the key was found
Definition: IOVDbParser.cxx:123
IOVDbParser::extensible
bool extensible() const
Definition: IOVDbParser.cxx:184
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
IOVDbParser::cache
std::string cache() const
Definition: IOVDbParser.cxx:163
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
IOVDbParser.h
IOVDbParser::IOVDbParser
IOVDbParser()=delete
IOVDbParser::iovOverrideValue
unsigned long long iovOverrideValue(MsgStream &msg) const
Definition: IOVDbParser.cxx:301
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
IOVDbParser::key
std::string key() const
Definition: IOVDbParser.cxx:138
IOVDbParser::toString
std::string toString() const
Definition: IOVDbParser.cxx:320
IOVDbParser::tag
std::string tag() const
Definition: IOVDbParser.cxx:148
IOVDbParser::getKey
bool getKey(const std::string &key, const std::string &devvalue, std::string &value) const
original 'getKey' method, now implemented using 'at'
Definition: IOVDbParser.cxx:108
IOVDbParser
Definition: IOVDbParser.h:19
IOVDbParser::timebaseIs_nsOfEpoch
bool timebaseIs_nsOfEpoch() const
Definition: IOVDbParser.cxx:158
IOVDbParser::symLinks
std::vector< std::string > symLinks() const
Definition: IOVDbParser.cxx:211
IOVDbParser::overridesIovImpl
bool overridesIovImpl(MsgStream &msg, const bool performFolderCheck, const bool folderIs_nsOfEpoch=true) const
implementation of overridesIov, with or without check on folder compatibility
Definition: IOVDbParser.cxx:274
IOVDbParser::applyOverrides
unsigned applyOverrides(const IOVDbParser &other, MsgStream &log)
Definition: IOVDbParser.cxx:233
IOVDbParser::folderName
std::string folderName() const
give the folder name contained in the parsed description
Definition: IOVDbParser.cxx:133
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
IOVDbParser::clean
void clean()
Definition: IOVDbParser.cxx:222
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
IOVDbParser::hasKey
bool hasKey() const
Definition: IOVDbParser.cxx:143
DeMoScan.first
bool first
Definition: DeMoScan.py:536
DEBUG
#define DEBUG
Definition: page_access.h:11
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
IOVDbParser::classId
CLID classId(MsgStream &msg) const
Definition: IOVDbParser.cxx:190
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
IOVDbNamespace::parseClid
int parseClid(const std::string &addrHeaderStr)
Extract the Class ID (an integer) from a string of form <addrHeader><address_header service_type="256...
Definition: IOVDbStringFunctions.cxx:59
IOVDbParser::addressHeader
std::string addressHeader() const
Definition: IOVDbParser.cxx:206
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
IOVDbParser::eventStoreName
std::string eventStoreName() const
Definition: IOVDbParser.cxx:153
IOVDbParser::m_keys
KeyValMap m_keys
Definition: IOVDbParser.h:61
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
IOVDbNamespace::iovFromRunString
unsigned long long iovFromRunString(const std::string &runString)
Take a string run number and convert it to an ULL representing run<<32.
Definition: IOVDbStringFunctions.cxx:38