CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/FWCore/PluginManager/src/CacheParser.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     PluginManager
00004 // Class  :     CacheParser
00005 // 
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Wed Apr  4 14:30:46 EDT 2007
00011 // $Id: CacheParser.cc,v 1.6 2011/09/19 14:24:34 eulisse Exp $
00012 //
00013 
00014 // system include files
00015 #include <algorithm>
00016 #include <limits>
00017 #include "boost/version.hpp"
00018 
00019 // user include files
00020 #include "FWCore/PluginManager/interface/CacheParser.h"
00021 #include "FWCore/Utilities/interface/Exception.h"
00022 #include "FWCore/Utilities/interface/Algorithms.h"
00023 
00024 namespace edmplugin {
00025 //
00026 // constants, enums and typedefs
00027 //
00028 
00029 //
00030 // static data member definitions
00031 //
00032 
00033 //
00034 // constructors and destructor
00035 //
00036 //CacheParser::CacheParser(std::istream&)
00037 //{
00038 //}
00039 
00040 // CacheParser::CacheParser(const CacheParser& rhs)
00041 // {
00042 //    // do actual copying here;
00043 // }
00044 
00045 //CacheParser::~CacheParser()
00046 //{
00047 //}
00048 
00049 //
00050 // assignment operators
00051 //
00052 // const CacheParser& CacheParser::operator=(const CacheParser& rhs)
00053 // {
00054 //   //An exception safe implementation is
00055 //   CacheParser temp(rhs);
00056 //   swap(rhs);
00057 //
00058 //   return *this;
00059 // }
00060 
00061 //
00062 // member functions
00063 //
00064 
00065 //
00066 // const member functions
00067 //
00068 
00069 //
00070 // static member functions
00071 //
00072   static void checkForError(const std::istream& iIn,
00073                             unsigned long iRecordNumber,
00074                             const std::string& iContext)
00075 {
00076     if(iIn.eof()) {
00077       throw cms::Exception("PluginCacheParseFailed")<<"Unexpectedly reached end of file for line "
00078       <<iRecordNumber<<" just after '"<<iContext<<"'";
00079     }
00080     if(iIn.bad()) {
00081       throw cms::Exception("PluginCacheParseFailed")<<"Reading failed on line "<<iRecordNumber <<" just after '"<<iContext<<"'";
00082     }
00083 }
00084   
00085 bool
00086 CacheParser::readline(std::istream& iIn, const boost::filesystem::path& iDirectory,
00087          unsigned long iRecordNumber, PluginInfo &oInfo, std::string& oPluginType)
00088 {    
00089   static const std::string kNewLine("start of new line");
00090   std::string fileName;
00091   std::string pluginName;
00092   iIn >> fileName;
00093   if(iIn.eof()) { return false;}
00094   checkForError(iIn,iRecordNumber,kNewLine);
00095   CacheParser::restoreSpaces(fileName);
00096   iIn >> pluginName;
00097   checkForError(iIn,iRecordNumber,fileName);
00098   CacheParser::restoreSpaces(pluginName);
00099   iIn >> oPluginType;
00100   checkForError(iIn,iRecordNumber,oPluginType);
00101   CacheParser::restoreSpaces(oPluginType);
00102   
00103   oInfo.loadable_ = iDirectory / fileName;
00104   oInfo.name_ = pluginName;
00105   
00106   //ignore everything to the end of line
00107   iIn.ignore(std::numeric_limits<int>::max(),
00108              '\n');
00109   while(iIn.peek() == '\n') {
00110     iIn.get();
00111   }  
00112   return true;
00113 }
00114 
00115 namespace {
00116   struct CompPluginInfos {
00117     bool operator()(const PluginInfo& iLHS,
00118                     const PluginInfo& iRHS) const
00119   {
00120     return iLHS.name_ < iRHS.name_;
00121   }
00122   };
00123 }
00124 
00125 void
00126 CacheParser::read(std::istream& iIn, 
00127                   const boost::filesystem::path& iDirectory,
00128                   CacheParser::CategoryToInfos& iOut)
00129 {
00130   unsigned long recordNumber=0;
00131   
00132   std::string pluginType;
00133   
00134   PluginInfo info;
00135 
00136   while(iIn) {
00137     ++recordNumber;
00138     if( not readline(iIn,iDirectory,recordNumber,info,pluginType) ) {
00139       break;
00140     }
00141     iOut[pluginType].push_back(info);
00142   }
00143   //now do a sort which preserves any previous order for files
00144   for(CacheParser::CategoryToInfos::iterator it = iOut.begin(), itEnd=iOut.end();
00145       it != itEnd;
00146       ++it) {
00147     std::stable_sort(it->second.begin(),it->second.end(), CompPluginInfos());
00148   }
00149 }
00150 
00151 void
00152 CacheParser::write(const CategoryToInfos& iInfos, std::ostream& oOut)
00153 {
00154   //order the data more to our liking: library then object then type
00155   LoadableToPlugins ordered;
00156   
00157   for(CategoryToInfos::const_iterator it = iInfos.begin();
00158       it != iInfos.end();
00159       ++it) {
00160     std::string type(it->first);
00161     for(std::vector<PluginInfo>::const_iterator it2=it->second.begin();
00162         it2 != it->second.end();
00163         ++it2) {
00164       //remove any directory specification
00165 #if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 47
00166       std::string loadable(it2->loadable_.filename().string());
00167 #else
00168       std::string loadable(it2->loadable_.filename());
00169 #endif
00170       std::string name(it2->name_);
00171       ordered[loadable].push_back(NameAndType(name,type));
00172     }
00173   }
00174   write(ordered,oOut);
00175 }
00176 
00177 void 
00178 CacheParser::write(LoadableToPlugins& iIn, std::ostream& oOut)
00179 {
00180   for( LoadableToPlugins::iterator it = iIn.begin();
00181        it!=iIn.end();
00182        ++it) {
00183     std::string loadable(it->first.string());
00184     replaceSpaces(loadable);
00185     edm::sort_all(it->second);
00186     
00187     for(std::vector<std::pair<std::string,std::string> >::iterator it2 = it->second.begin();
00188         it2 != it->second.end();
00189         ++it2) {
00190       oOut << loadable <<" "<<replaceSpaces(it2->first)<<" "<<replaceSpaces(it2->second)<<"\n";
00191     }
00192   }
00193 }
00194 
00195 void 
00196 CacheParser::read(std::istream& iIn, LoadableToPlugins& oOut)
00197 {
00198   unsigned long recordNumber=0;
00199   
00200   std::string pluginType;
00201   
00202   PluginInfo info;
00203   NameAndType pat;
00204   boost::filesystem::path empty;
00205   
00206   while(iIn) {
00207     ++recordNumber;
00208     if( not readline(iIn,empty,recordNumber,info,pat.second) ) {
00209       break;
00210     }
00211     pat.first = info.name_;
00212     oOut[info.loadable_].push_back(pat);
00213   }
00214 }
00215 
00216 std::string& 
00217 CacheParser::replaceSpaces(std::string& io)
00218 {
00219   std::string::size_type index=0;
00220   while(std::string::npos != (index = io.find_first_of(" \t\n",index))) {
00221     io[index]='%';
00222   }
00223   return io;
00224 }
00225 
00226 std::string& CacheParser::restoreSpaces(std::string& io)
00227 {
00228   std::string::size_type index=0;
00229   while(std::string::npos != (index = io.find_first_of("%",index))) {
00230     io[index]=' ';
00231   }
00232   return io;
00233 }
00234 }