CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Fireworks/Core/src/FWConfiguration.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWConfiguration
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Fri Feb 22 15:54:29 EST 2008
00011 // $Id: FWConfiguration.cc,v 1.6 2010/04/23 08:57:26 eulisse Exp $
00012 //
00013 
00014 // system include files
00015 #include <stdexcept>
00016 #include <algorithm>
00017 #include <boost/bind.hpp>
00018 
00019 // user include files
00020 #include "Fireworks/Core/interface/FWConfiguration.h"
00021 
00022 
00023 //
00024 // constants, enums and typedefs
00025 //
00026 
00027 //
00028 // static data member definitions
00029 //
00030 
00031 //
00032 // constructors and destructor
00033 //
00034 //FWConfiguration::FWConfiguration()
00035 //{
00036 //}
00037 
00038 FWConfiguration::FWConfiguration(const FWConfiguration& rhs) :
00039    m_stringValues( rhs.m_stringValues ? new std::vector<std::string>(*(rhs.m_stringValues)) : 0),
00040    m_keyValues( rhs.m_keyValues ? new KeyValues(*(rhs.m_keyValues)) : 0),
00041    m_version(rhs.m_version)
00042 {
00043 }
00044 
00045 FWConfiguration::~FWConfiguration()
00046 {
00047 }
00048 
00049 //
00050 // assignment operators
00051 //
00052 const FWConfiguration& FWConfiguration::operator=(const FWConfiguration& rhs)
00053 {
00054    //An exception safe implementation is
00055    FWConfiguration temp(rhs);
00056    swap(temp);
00057 
00058    return *this;
00059 }
00060 
00061 //
00062 // member functions
00063 //
00064 FWConfiguration&
00065 FWConfiguration::addKeyValue(const std::string& iKey, const FWConfiguration& iConfig)
00066 {
00067    if( m_stringValues ) {
00068       throw std::runtime_error("adding key/value to configuration containing string values");
00069    }
00070    if(not m_keyValues) {
00071       m_keyValues.reset(new KeyValues(1, std::make_pair(iKey,iConfig) ) );
00072    } else {
00073       m_keyValues->push_back(std::make_pair(iKey,iConfig));
00074    }
00075    return *this;
00076 }
00077 FWConfiguration&
00078 FWConfiguration::addKeyValue(const std::string&iKey, FWConfiguration& iConfig, bool iDoSwap)
00079 {
00080    if( m_stringValues ) {
00081       throw std::runtime_error("adding key/value to configuration containing string values");
00082    }
00083    if( m_stringValues ) {
00084       throw std::runtime_error("adding key/value to configuration containing string values");
00085    }
00086    if(not m_keyValues) {
00087       if(not iDoSwap) {
00088          m_keyValues.reset(new KeyValues(1, std::make_pair(iKey,iConfig) ) );
00089       } else {
00090          m_keyValues.reset(new KeyValues(1, std::make_pair(iKey,FWConfiguration()) ) );
00091          m_keyValues->back().second.swap(iConfig);
00092       }
00093    } else {
00094       if(not iDoSwap) {
00095          m_keyValues->push_back(std::make_pair(iKey,iConfig));
00096       } else {
00097          m_keyValues->push_back(std::make_pair(iKey,FWConfiguration()));
00098          m_keyValues->back().second.swap(iConfig);
00099       }
00100    }
00101    return *this;
00102 }
00103 
00104 FWConfiguration&
00105 FWConfiguration::addValue(const std::string& iValue)
00106 {
00107    if( m_keyValues ) {
00108       throw std::runtime_error("adding string value to configuration containing key/value pairs");
00109    }
00110    if( not m_stringValues ) {
00111       m_stringValues.reset( new std::vector<std::string>(1,iValue) );
00112    } else {
00113       m_stringValues->push_back(iValue);
00114    }
00115    return *this;
00116 }
00117 
00118 void
00119 FWConfiguration::swap(FWConfiguration& iRHS)
00120 {
00121    std::swap(m_version, iRHS.m_version);
00122    m_stringValues.swap(iRHS.m_stringValues);
00123    m_keyValues.swap(iRHS.m_keyValues);
00124 }
00125 
00126 //
00127 // const member functions
00128 //
00129 const std::string&
00130 FWConfiguration::value(unsigned int iIndex) const
00131 {
00132    if( not m_stringValues ) {
00133       throw std::runtime_error("no string values set");
00134    }
00135    return m_stringValues->at(iIndex);
00136 }
00137 
00138 const FWConfiguration*
00139 FWConfiguration::valueForKey(const std::string& iKey) const
00140 {
00141    if( m_stringValues ) {
00142       throw std::runtime_error("valueFoKey fails because configuration containing string values");
00143    }
00144    if(not m_keyValues) {
00145       throw std::runtime_error("valueForKey fails becuase no key/values set");
00146    }
00147    KeyValues::iterator itFind = std::find_if(m_keyValues->begin(),
00148                                              m_keyValues->end(),
00149                                              boost::bind(&std::pair<std::string,FWConfiguration>::first,_1) == iKey);
00150    if(itFind == m_keyValues->end()) {
00151       return 0;
00152    }
00153    return &(itFind->second);
00154 }
00155 
00156 
00160 std::string 
00161 attrEscape(std::string value)
00162 {
00163    std::string::size_type index=0;
00164    index = 0;
00165    while (std::string::npos != (index=value.find('&',index))){
00166       value.replace(index, 1,"&amp;", 5);
00167       // Do not check "&quot;" for quotes.
00168       index += 5;
00169    }
00170 
00171    while (std::string::npos != (index=value.find('"',index))){
00172       value.replace(index, 1,"&quot;", 6);
00173       // Do not check "&quot;" for quotes.
00174       index += 6;
00175    }
00176    
00177    index = 0;
00178    while (std::string::npos != (index=value.find('<',index))){
00179       value.replace(index, 1,"&lt;", 4);
00180       // Do not check "&quot;" for quotes.
00181       index += 4;
00182    }
00183 
00184    index = 0;
00185    while (std::string::npos != (index=value.find('>',index))){
00186       value.replace(index, 1,"&gt;", 4);
00187       // Do not check "&quot;" for quotes.
00188       index += 4;
00189    }
00190 
00191    return value;
00192 }
00193 
00214 void
00215 streamTo(std::ostream& oTo, const FWConfiguration& iConfig, const std::string &name)
00216 {
00217    static int recursionLevel = -1;
00218    recursionLevel += 1;
00219    std::string indentation(recursionLevel, ' ');
00220    oTo << indentation << "<config name=\"" << name 
00221                       << "\" version=\"" << iConfig.version() << "\">\n";
00222    if(iConfig.stringValues()) {
00223       for(FWConfiguration::StringValues::const_iterator it = iConfig.stringValues()->begin();
00224           it != iConfig.stringValues()->end();
00225           ++it) {
00226          oTo << indentation << "  <string>" << attrEscape(*it) << "</string>\n";
00227       }
00228    }
00229    if(iConfig.keyValues()) {
00230       for(FWConfiguration::KeyValues::const_iterator it = iConfig.keyValues()->begin();
00231           it != iConfig.keyValues()->end();
00232           ++it) {
00233          streamTo(oTo, it->second, attrEscape(it->first));
00234       }
00235    }
00236    oTo << indentation << "</config>" << std::endl;
00237    recursionLevel -= 1;
00238 }
00239 
00240 //
00241 // static member functions
00242 //