libzypp  10.5.0
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 & 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         // else: dubious
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         // else: dubious
00070         break;
00071 
00072       case 32:
00073         if (  _type == md5Type() )
00074           return;
00075         if ( _type.empty() )
00076         {
00077           _type = md5Type();
00078           return;
00079         }
00080         // else: dubious
00081         break;
00082 
00083       case 0:
00084         return; // empty checksum is ok
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         // else: dubious
00094         break;
00095     }
00096 
00097     // dubious: Throw on malformed known types, otherwise log a warning.
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 } // namespace zypp