00001 #include "DataFormats/Provenance/interface/Hash.h" 00002 #include "FWCore/Utilities/interface/Algorithms.h" 00003 #include "FWCore/Utilities/interface/Digest.h" 00004 #include "FWCore/Utilities/interface/EDMException.h" 00005 00006 namespace edm { 00007 namespace detail { 00008 // This string is the 16-byte, non-printable version. 00009 std::string const& InvalidHash() { 00010 static std::string const invalid = cms::MD5Result().compactForm(); 00011 return invalid; 00012 } 00013 } 00014 00015 namespace hash_detail { 00016 value_type 00017 compactForm_(value_type const& hash) { 00018 if (isCompactForm_(hash)) { 00019 return hash; 00020 } 00021 value_type temp(hash); 00022 fixup_(temp); 00023 return temp; 00024 } 00025 00026 // 'Fix' the string data member of this Hash, i.e., if it is in 00027 // the hexified (32 byte) representation, make it be in the 00028 // 16-byte (unhexified) representation. 00029 void 00030 fixup_(value_type& hash) { 00031 switch (hash.size()) { 00032 case 16: { 00033 break; 00034 } 00035 case 32: { 00036 cms::MD5Result temp; 00037 temp.fromHexifiedString(hash); 00038 hash = temp.compactForm(); 00039 break; 00040 } 00041 case 0: { 00042 throw Exception(errors::LogicError) 00043 << "Empty edm::Hash<> instance:\n" << "\nPlease report this to the core framework developers"; 00044 } 00045 default: { 00046 throw Exception(errors::LogicError) 00047 << "edm::Hash<> instance with data in illegal state:\n" 00048 << hash 00049 << "\nPlease report this to the core framework developers"; 00050 } 00051 } 00052 } 00053 00054 bool 00055 isCompactForm_(value_type const& hash) { 00056 return 16 == hash.size(); 00057 } 00058 00059 bool 00060 isValid_(value_type const& hash) { 00061 return isCompactForm_(hash) ? (hash != detail::InvalidHash()) : (!hash.empty()); 00062 } 00063 00064 void 00065 throwIfIllFormed(value_type const& hash) { 00066 // Fixup not needed here. 00067 if (hash.size() % 2 == 1) { 00068 throw Exception(errors::LogicError) 00069 << "Ill-formed Hash instance. " 00070 << "Please report this to the core framework developers"; 00071 } 00072 } 00073 00074 void 00075 toString_(std::string& result, value_type const& hash) { 00076 value_type temp1(hash); 00077 fixup_(temp1); 00078 cms::MD5Result temp; 00079 copy_all(temp1, temp.bytes); 00080 result += temp.toString(); 00081 } 00082 00083 void 00084 toDigest_(cms::Digest& digest, value_type const& hash) { 00085 // FIXME: do we really need to go through a temporary value_type??? 00086 value_type temp1(hash); 00087 fixup_(temp1); 00088 cms::MD5Result temp; 00089 copy_all(temp1, temp.bytes); 00090 digest.append(temp.toString()); 00091 } 00092 00093 std::ostream& 00094 print_(std::ostream& os, value_type const& hash) { 00095 value_type temp1(hash); 00096 fixup_(temp1); 00097 cms::MD5Result temp; 00098 copy_all(temp1, temp.bytes); 00099 os << temp.toString(); 00100 return os; 00101 } 00102 } 00103 }