CheckSum.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013 #include <sstream>
00014
00015 #include "zypp/base/Logger.h"
00016 #include "zypp/base/Gettext.h"
00017 #include "zypp/base/String.h"
00018
00019 #include "zypp/CheckSum.h"
00020 #include "zypp/Digest.h"
00021
00022 using std::endl;
00023
00025 namespace zypp
00026 {
00027
00028 const std::string & CheckSum::md5Type()
00029 { static std::string _type( "md5" ); return _type; }
00030
00031 const std::string & CheckSum::shaType()
00032 { static std::string _type( "sha" ); return _type; }
00033
00034 const std::string & CheckSum::sha1Type()
00035 { static std::string _type( "sha1" ); return _type; }
00036
00037 const std::string & CheckSum::sha256Type()
00038 { static std::string _type( "sha256" ); return _type; }
00039
00040
00041 CheckSum::CheckSum()
00042 {}
00043
00044 CheckSum::CheckSum( const std::string & type, const std::string & checksum )
00045 : _type( str::toLower( type ) )
00046 , _checksum( checksum )
00047 {
00048 switch ( checksum.size() )
00049 {
00050 case 64:
00051 if ( _type == sha256Type() )
00052 return;
00053 if ( _type.empty() || _type == shaType() )
00054 {
00055 _type = sha256Type();
00056 return;
00057 }
00058
00059 break;
00060
00061 case 40:
00062 if ( _type == sha1Type() )
00063 return;
00064 if ( _type.empty() || _type == shaType() )
00065 {
00066 _type = sha1Type();
00067 return;
00068 }
00069
00070 break;
00071
00072 case 32:
00073 if ( _type == md5Type() )
00074 return;
00075 if ( _type.empty() )
00076 {
00077 _type = md5Type();
00078 return;
00079 }
00080
00081 break;
00082
00083 case 0:
00084 return;
00085 break;
00086
00087 default:
00088 if ( _type.empty() )
00089 {
00090 WAR << "Can't determine type of " << checksum.size() << " byte checksum '" << _checksum << "'" << endl;
00091 return;
00092 }
00093
00094 break;
00095 }
00096
00097
00098 std::string msg = str::form ( _("Dubious type '%s' for %u byte checksum '%s'"),
00099 _type.c_str(), checksum.size(), _checksum.c_str() );
00100 if ( _type == md5Type()
00101 || _type == shaType()
00102 || _type == sha1Type()
00103 || _type == sha256Type() )
00104 {
00105 ZYPP_THROW( CheckSumException( msg ) );
00106 }
00107 else
00108 {
00109 WAR << msg << endl;
00110 }
00111 }
00112
00113 CheckSum::CheckSum( const std::string & type_r, std::istream & input_r )
00114 {
00115 if ( input_r.good() && ! type_r.empty() )
00116 {
00117 _type = str::toLower( type_r );
00118 _checksum = Digest::digest( _type, input_r );
00119 if ( ! input_r.eof() || _checksum.empty() )
00120 {
00121 _type = _checksum = std::string();
00122 }
00123 }
00124 }
00125
00126 std::string CheckSum::type() const
00127 { return _type; }
00128
00129 std::string CheckSum::checksum() const
00130 { return _checksum; }
00131
00132 bool CheckSum::empty() const
00133 { return (checksum().empty() || type().empty()); }
00134
00135 std::string CheckSum::asString() const
00136 {
00137 std::ostringstream str;
00138 str << *this;
00139 return str.str();
00140 }
00141
00142 std::ostream & operator<<( std::ostream & str, const CheckSum & obj )
00143 {
00144 if ( obj.checksum().empty() )
00145 {
00146 return str << std::string("NoCheckSum");
00147 }
00148
00149 return str << ( obj.type().empty() ? std::string("UNKNOWN") : obj.type() ) << '-' << obj.checksum();
00150 }
00151
00153 bool operator==( const CheckSum & lhs, const CheckSum & rhs )
00154 { return lhs.checksum() == rhs.checksum() && lhs.type() == rhs.type(); }
00155
00157 bool operator!=( const CheckSum & lhs, const CheckSum & rhs )
00158 { return ! ( lhs == rhs ); }
00159
00161 }