CMS 3D CMS Logo

Hash.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Provenance_Hash_h
00002 #define DataFormats_Provenance_Hash_h
00003 
00004 #include <string>
00005 
00006 #include "FWCore/Utilities/interface/Digest.h"
00007 #include "FWCore/Utilities/interface/EDMException.h"
00008 #include "FWCore/Utilities/interface/Algorithms.h"
00009 
00010 /*----------------------------------------------------------------------
00011   
00012 Hash:
00013 
00014 $Id: Hash.h,v 1.3 2007/11/07 04:32:38 wmtan Exp $
00015 
00016   Note: The call to 'fixup' in every member function is a temporary
00017   measure for backwards compatibility. It is necessary in every function
00018   because Root creates instances of the class *without* using the
00019   interface of the class, thus making it insufficient to assure that
00020   all constructors make corrected instances.
00021 
00022 ----------------------------------------------------------------------*/
00023 namespace edm {
00024 
00025   namespace detail
00026   {
00027     // This string is the 16-byte, non-printable version.
00028     std::string const& InvalidHash();
00029   }
00030 
00031   template <int I>
00032   class Hash {
00033   public:
00034     typedef std::string value_type;
00035 
00036     Hash();
00037     explicit Hash(value_type const& v);
00038 
00039     Hash(Hash<I> const&);
00040     Hash<I> const& operator=(Hash<I> const& iRHS);
00041 
00042     // For now, just check the most basic: a default constructed
00043     // ParameterSetID is not valid. This is very crude: we are
00044     // assuming that nobody created a ParameterSetID from an empty
00045     // string, nor from any string that is not a valid string
00046     // representation of an MD5 checksum.
00047     bool isValid() const;
00048 
00049     bool operator< (Hash<I> const& other) const;
00050     bool operator> (Hash<I> const& other) const;
00051     bool operator== (Hash<I> const& other) const;
00052     bool operator!= (Hash<I> const& other) const;
00053     std::ostream& print(std::ostream& os) const;
00054     void swap(Hash<I>& other);
00055 
00056     // Return the 16-byte (non-printable) string form.
00057     value_type compactForm() const;
00058     
00059     bool isCompactForm()const;
00060     
00061   private:
00062 
00065     void throwIfIllFormed() const;
00066 
00067     // 'Fix' the string data member of this Hash, i.e., if it is in
00068     // the hexified (32 byte) representation, make it be in the
00069     // 16-byte (unhexified) representation.
00070     void fixup();
00071     
00072     template< typename Op>
00073       bool
00074       compareUsing(Hash<I> const& iOther, Op op) const {
00075         if(this->isCompactForm() == iOther.isCompactForm()) {
00076           return op(this->hash_,iOther.hash_);
00077         }
00078         Hash<I> tMe(*this);
00079         Hash<I> tOther(iOther);
00080         return op(tMe.hash_,tOther.hash_);
00081       }
00082 
00083     value_type hash_;
00084   };
00085 
00086 
00087   //--------------------------------------------------------------------
00088   //
00089   // Implementation details follow...
00090   //--------------------------------------------------------------------
00091 
00092 
00093   template <int I>
00094   inline
00095   Hash<I>::Hash() : 
00096     hash_() 
00097   {
00098     fixup();
00099   }
00100 
00101   template <int I>
00102   inline
00103   Hash<I>::Hash(typename Hash<I>::value_type const& v) :
00104     hash_(v)
00105   {
00106     fixup();
00107   }
00108 
00109   template <int I>
00110   inline
00111   Hash<I>::Hash(Hash<I> const& iOther):
00112     hash_(iOther.hash_)
00113   {
00114       fixup();
00115   }
00116 
00117   template <int I>
00118   inline
00119   Hash<I> const& 
00120   Hash<I>::operator=(Hash<I> const& iRHS)
00121   {
00122     hash_=iRHS.hash_;
00123     fixup();
00124     return *this;
00125   }
00126   
00127   template <int I>
00128   inline
00129   bool 
00130   Hash<I>::isValid() const
00131   {
00132     return isCompactForm() ? (hash_ != edm::detail::InvalidHash()) : (hash_.size()!=0);
00133   }
00134   
00135   template <int I>
00136   inline
00137   bool
00138   Hash<I>::operator< (Hash<I> const& other) const
00139   {
00140     return this->compareUsing(other, std::less<std::string >());
00141   }
00142 
00143   template <int I>
00144   inline
00145   bool 
00146   Hash<I>::operator> (Hash<I> const& other) const 
00147   {
00148     return this->compareUsing(other, std::greater<std::string >());
00149   }
00150 
00151   template <int I>
00152   inline
00153   bool 
00154   Hash<I>::operator== (Hash<I> const& other) const 
00155   {
00156     return this->compareUsing(other, std::equal_to<std::string >());
00157   }
00158 
00159   template <int I>
00160   inline
00161   bool 
00162   Hash<I>::operator!= (Hash<I> const& other) const 
00163   {
00164     return this->compareUsing(other, std::not_equal_to<std::string >());
00165   }
00166 
00167   template <int I>
00168   inline
00169   std::ostream& 
00170   Hash<I>::print(std::ostream& os) const
00171   {
00172     Hash<I> tMe(*this);
00173     cms::MD5Result temp;
00174     copy_all(tMe.hash_, temp.bytes);
00175     os << temp.toString();
00176     return os;
00177   }
00178 
00179   template <int I>
00180   inline
00181   void 
00182   Hash<I>::swap(Hash<I>& other) 
00183   {
00184     fixup();
00185     hash_.swap(other.hash_);
00186     fixup();
00187   }
00188 
00189   template <int I>
00190   inline
00191   typename Hash<I>::value_type
00192   Hash<I>::compactForm() const
00193   {
00194     if (this->isCompactForm()) {
00195       return hash_;
00196     }
00197     Hash<I> tMe(*this);
00198     return tMe.compactForm();
00199   }
00200 
00201   template <int I>
00202   inline
00203   void 
00204   Hash<I>::throwIfIllFormed() const 
00205   {
00206     // Fixup not needed here.
00207     if (hash_.size() % 2 == 1)
00208       {
00209         throw edm::Exception(edm::errors::LogicError)
00210           << "Ill-formed Hash instance. "
00211           << "Please report this to the core framework developers";
00212       }
00213   }
00214 
00215   // Note: this template is not declared 'inline' because of the
00216   // switch statement.
00217 
00218   template <int I>
00219   void 
00220   Hash<I>::fixup() {
00221     switch (hash_.size()) {
00222       case 0:
00223       {
00224         hash_ = edm::detail::InvalidHash();
00225       } 
00226       case 16: 
00227       {
00228         break;
00229       }
00230       case 32:
00231       {
00232         cms::MD5Result temp;
00233         temp.fromHexifiedString(hash_);
00234         hash_ = temp.compactForm();
00235         break;
00236       }
00237       default:
00238       {
00239         throw edm::Exception(edm::errors::LogicError)
00240           << "edm::Hash<> instance with data in illegal state:\n"
00241           << hash_
00242           << "\nPlease report this to the core framework developers";
00243       }
00244     }
00245   }
00246 
00247   template <int I>
00248   inline
00249   bool Hash<I>::isCompactForm() const {
00250     return 16 == hash_.size();
00251   }
00252   
00253 
00254   // Free swap function
00255   template <int I>
00256   inline
00257   void
00258   swap(Hash<I>& a, Hash<I>& b) 
00259   {
00260     a.swap(b);
00261   }
00262 
00263   template <int I>
00264   inline
00265   std::ostream&
00266   operator<< (std::ostream& os, Hash<I> const& h)
00267   {
00268     return h.print(os);
00269   }
00270 
00271 }
00272 #endif

Generated on Tue Jun 9 17:31:33 2009 for CMSSW by  doxygen 1.5.4