CMS 3D CMS Logo

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