libzypp 9.41.1

CheckSum.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
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 & checksum )
00045   {
00046     *this = CheckSum( std::string(), checksum );
00047   }
00048 
00049   CheckSum::CheckSum( const std::string & type, const std::string & checksum )
00050   : _type( str::toLower( type ) )
00051   , _checksum( checksum )
00052   {
00053     switch ( checksum.size() )
00054     {
00055       case 64:
00056         if ( _type == sha256Type() )
00057           return;
00058         if ( _type.empty() || _type == shaType() )
00059         {
00060           _type = sha256Type();
00061           return;
00062         }
00063         // else: dubious
00064         break;
00065 
00066       case 40:
00067         if ( _type == sha1Type() )
00068           return;
00069         if ( _type.empty() || _type == shaType() )
00070         {
00071           _type = sha1Type();
00072           return;
00073         }
00074         // else: dubious
00075         break;
00076 
00077       case 32:
00078         if (  _type == md5Type() )
00079           return;
00080         if ( _type.empty() )
00081         {
00082           _type = md5Type();
00083           return;
00084         }
00085         // else: dubious
00086         break;
00087 
00088       case 0:
00089         return; // empty checksum is ok
00090         break;
00091 
00092       default:
00093         if ( _type.empty() )
00094         {
00095           WAR << "Can't determine type of " << checksum.size() << " byte checksum '" << _checksum << "'" << endl;
00096           return;
00097         }
00098         // else: dubious
00099         break;
00100     }
00101 
00102     // dubious: Throw on malformed known types, otherwise log a warning.
00103     std::string msg = str::form ( _("Dubious type '%s' for %u byte checksum '%s'"),
00104                                   _type.c_str(), checksum.size(), _checksum.c_str() );
00105     if (    _type == md5Type()
00106          || _type == shaType()
00107          || _type == sha1Type()
00108          || _type == sha256Type() )
00109     {
00110       ZYPP_THROW( CheckSumException( msg ) );
00111     }
00112     else
00113     {
00114       WAR << msg << endl;
00115     }
00116   }
00117 
00118   CheckSum::CheckSum( const std::string & type_r, std::istream & input_r )
00119   {
00120     if ( input_r.good() && ! type_r.empty() )
00121       {
00122         _type = str::toLower( type_r );
00123         _checksum = Digest::digest( _type, input_r );
00124         if ( ! input_r.eof() || _checksum.empty() )
00125           {
00126             _type = _checksum = std::string();
00127           }
00128       }
00129   }
00130 
00131   std::string CheckSum::type() const
00132   { return _type; }
00133 
00134   std::string CheckSum::checksum() const
00135   { return _checksum; }
00136 
00137   bool CheckSum::empty() const
00138   { return (checksum().empty() || type().empty()); }
00139 
00140   std::string CheckSum::asString() const
00141   {
00142     std::ostringstream str;
00143     str << *this;
00144     return str.str();
00145   }
00146 
00147   std::ostream & operator<<( std::ostream & str, const CheckSum & obj )
00148   {
00149     if ( obj.checksum().empty() )
00150       {
00151         return str << std::string("NoCheckSum");
00152       }
00153 
00154     return str << ( obj.type().empty() ? std::string("UNKNOWN") : obj.type() ) << '-' << obj.checksum();
00155   }
00156 
00158   bool operator==( const CheckSum & lhs, const CheckSum & rhs )
00159   { return lhs.checksum() == rhs.checksum() && lhs.type() == rhs.type(); }
00160 
00162   bool operator!=( const CheckSum & lhs, const CheckSum & rhs )
00163   { return ! ( lhs == rhs ); }
00164 
00166 } // namespace zypp