File indexing completed on 2024-04-06 12:11:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <memory>
0015
0016 #include <stdexcept>
0017 #include <algorithm>
0018 #include <functional>
0019
0020 #include "Fireworks/Core/interface/FWConfiguration.h"
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 FWConfiguration::FWConfiguration(const FWConfiguration& rhs)
0038 : m_stringValues(rhs.m_stringValues ? new std::vector<std::string>(*(rhs.m_stringValues)) : nullptr),
0039 m_keyValues(rhs.m_keyValues ? new KeyValues(*(rhs.m_keyValues)) : nullptr),
0040 m_version(rhs.m_version) {}
0041
0042 FWConfiguration::~FWConfiguration() {}
0043
0044
0045
0046
0047 FWConfiguration& FWConfiguration::operator=(const FWConfiguration& rhs) {
0048
0049 FWConfiguration temp(rhs);
0050 swap(temp);
0051
0052 return *this;
0053 }
0054
0055
0056
0057
0058 FWConfiguration& FWConfiguration::addKeyValue(const std::string& iKey, const FWConfiguration& iConfig) {
0059 if (m_stringValues) {
0060 throw std::runtime_error("adding key/value to configuration containing string values");
0061 }
0062 if (not m_keyValues) {
0063 m_keyValues = std::make_unique<KeyValues>(1, std::make_pair(iKey, iConfig));
0064 } else {
0065 m_keyValues->push_back(std::make_pair(iKey, iConfig));
0066 }
0067 return *this;
0068 }
0069 FWConfiguration& FWConfiguration::addKeyValue(const std::string& iKey, FWConfiguration& iConfig, bool iDoSwap) {
0070 if (m_stringValues) {
0071 throw std::runtime_error("adding key/value to configuration containing string values");
0072 }
0073 if (m_stringValues) {
0074 throw std::runtime_error("adding key/value to configuration containing string values");
0075 }
0076 if (not m_keyValues) {
0077 if (not iDoSwap) {
0078 m_keyValues = std::make_unique<KeyValues>(1, std::make_pair(iKey, iConfig));
0079 } else {
0080 m_keyValues = std::make_unique<KeyValues>(1, std::make_pair(iKey, FWConfiguration()));
0081 m_keyValues->back().second.swap(iConfig);
0082 }
0083 } else {
0084 if (not iDoSwap) {
0085 m_keyValues->push_back(std::make_pair(iKey, iConfig));
0086 } else {
0087 m_keyValues->push_back(std::make_pair(iKey, FWConfiguration()));
0088 m_keyValues->back().second.swap(iConfig);
0089 }
0090 }
0091 return *this;
0092 }
0093
0094 FWConfiguration& FWConfiguration::addValue(const std::string& iValue) {
0095 if (m_keyValues) {
0096 throw std::runtime_error("adding string value to configuration containing key/value pairs");
0097 }
0098 if (not m_stringValues) {
0099 m_stringValues = std::make_unique<std::vector<std::string>>(1, iValue);
0100 } else {
0101 m_stringValues->push_back(iValue);
0102 }
0103 return *this;
0104 }
0105
0106 void FWConfiguration::swap(FWConfiguration& iRHS) {
0107 std::swap(m_version, iRHS.m_version);
0108 m_stringValues.swap(iRHS.m_stringValues);
0109 m_keyValues.swap(iRHS.m_keyValues);
0110 }
0111
0112
0113
0114
0115 const std::string& FWConfiguration::value(unsigned int iIndex) const {
0116 if (not m_stringValues) {
0117 throw std::runtime_error("no string values set");
0118 }
0119 return m_stringValues->at(iIndex);
0120 }
0121
0122 const FWConfiguration* FWConfiguration::valueForKey(const std::string& iKey) const {
0123 if (m_stringValues) {
0124 throw std::runtime_error("valueFoKey fails because configuration containing string values");
0125 }
0126 if (not m_keyValues) {
0127 throw std::runtime_error("valueForKey fails becuase no key/values set");
0128 }
0129 KeyValues::iterator itFind =
0130 std::find_if(m_keyValues->begin(),
0131 m_keyValues->end(),
0132 std::bind(std::equal_to<void>(),
0133 std::bind(&std::pair<std::string, FWConfiguration>::first, std::placeholders::_1),
0134 iKey));
0135 if (itFind == m_keyValues->end()) {
0136 return nullptr;
0137 }
0138 return &(itFind->second);
0139 }
0140
0141
0142
0143
0144 std::string attrEscape(std::string value) {
0145 std::string::size_type index = 0;
0146 index = 0;
0147 while (std::string::npos != (index = value.find('&', index))) {
0148 value.replace(index, 1, "&", 5);
0149
0150 index += 5;
0151 }
0152
0153 while (std::string::npos != (index = value.find('"', index))) {
0154 value.replace(index, 1, """, 6);
0155
0156 index += 6;
0157 }
0158
0159 index = 0;
0160 while (std::string::npos != (index = value.find('<', index))) {
0161 value.replace(index, 1, "<", 4);
0162
0163 index += 4;
0164 }
0165
0166 index = 0;
0167 while (std::string::npos != (index = value.find('>', index))) {
0168 value.replace(index, 1, ">", 4);
0169
0170 index += 4;
0171 }
0172
0173 return value;
0174 }
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 void FWConfiguration::streamTo(std::ostream& oTo, const FWConfiguration& iConfig, const std::string& name) {
0197 static int recursionLevel = -1;
0198 recursionLevel += 1;
0199 std::string indentation(recursionLevel, ' ');
0200 oTo << indentation << "<config name=\"" << name << "\" version=\"" << iConfig.version() << "\">\n";
0201 if (iConfig.stringValues()) {
0202 for (FWConfiguration::StringValues::const_iterator it = iConfig.stringValues()->begin();
0203 it != iConfig.stringValues()->end();
0204 ++it) {
0205 oTo << indentation << " <string>" << attrEscape(*it) << "</string>\n";
0206 }
0207 }
0208 if (iConfig.keyValues()) {
0209 for (FWConfiguration::KeyValues::const_iterator it = iConfig.keyValues()->begin(); it != iConfig.keyValues()->end();
0210 ++it) {
0211 FWConfiguration::streamTo(oTo, it->second, attrEscape(it->first));
0212 }
0213 }
0214 oTo << indentation << "</config>" << std::endl;
0215 recursionLevel -= 1;
0216 }
0217
0218
0219
0220