Merge pull request #23 from openSUSE/drop_package_manager
[platform/upstream/libzypp.git] / zypp / RepoStatus.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/RepoStatus.cc
10  *
11 */
12 #include <iostream>
13 #include <sstream>
14 #include <fstream>
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/String.h"
17 #include "zypp/RepoStatus.h"
18 #include "zypp/PathInfo.h"
19
20 using namespace std;
21
22 ///////////////////////////////////////////////////////////////////
23 namespace zypp
24 { /////////////////////////////////////////////////////////////////
25
26   ///////////////////////////////////////////////////////////////////
27   //
28   //    CLASS NAME : RepoStatus::Impl
29   //
30   /** RepoStatus implementation. */
31   struct RepoStatus::Impl
32   {
33
34   public:
35
36     string checksum;
37     Date timestamp;
38
39     /** Offer default Impl. */
40     static shared_ptr<Impl> nullimpl()
41     {
42       static shared_ptr<Impl> _nullimpl( new Impl );
43       return _nullimpl;
44     }
45
46   private:
47     friend Impl * rwcowClone<Impl>( const Impl * rhs );
48     /** clone for RWCOW_pointer */
49     Impl * clone() const
50     { return new Impl( *this ); }
51   };
52   ///////////////////////////////////////////////////////////////////
53
54   /** \relates RepoStatus::Impl Stream output */
55   inline std::ostream & operator<<( std::ostream & str, const RepoStatus::Impl & obj )
56   {
57     return str << obj.checksum << " " << (time_t) obj.timestamp;
58   }
59
60   ///////////////////////////////////////////////////////////////////
61   //
62   //    CLASS NAME : RepoStatus
63   //
64   ///////////////////////////////////////////////////////////////////
65
66   ///////////////////////////////////////////////////////////////////
67   //
68   //    METHOD NAME : RepoStatus::RepoStatus
69   //    METHOD TYPE : Ctor
70   //
71   RepoStatus::RepoStatus()
72     : _pimpl( new Impl() )
73   {}
74
75   RepoStatus::RepoStatus( const Pathname &path )
76     : _pimpl( new Impl() )
77   {
78       PathInfo info(path);
79       if ( info.isExist() )
80       {
81         _pimpl->timestamp = Date(info.mtime());
82         if ( info.isFile() )
83           _pimpl->checksum = filesystem::sha1sum(path);
84         else // non files
85           _pimpl->checksum = str::numstring(info.mtime());
86       }
87   }
88
89   ///////////////////////////////////////////////////////////////////
90   //
91   //    METHOD NAME : RepoStatus::~RepoStatus
92   //    METHOD TYPE : Dtor
93   //
94   RepoStatus::~RepoStatus()
95   {}
96
97   RepoStatus RepoStatus::fromCookieFile( const Pathname &cookiefile )
98   {
99     std::ifstream file(cookiefile.c_str());
100     if (!file) {
101       WAR << "No cookie file " << cookiefile << endl;
102       return RepoStatus();
103     }
104
105     RepoStatus status;
106     std::string buffer;
107     file >> buffer;
108     status.setChecksum(buffer);
109     file >> buffer;
110     status.setTimestamp(Date(str::strtonum<time_t>(buffer)));
111     return status;
112   }
113
114   void RepoStatus::saveToCookieFile( const Pathname &cookiefile ) const
115   {
116     std::ofstream file(cookiefile.c_str());
117     if (!file) {
118       ZYPP_THROW (Exception( "Can't open " + cookiefile.asString() ) );
119     }
120     file << this->checksum() << " " << (int) this->timestamp() << endl << endl;
121     file.close();
122   }
123
124   bool RepoStatus::empty() const
125   {
126     return _pimpl->checksum.empty();
127   }
128
129   RepoStatus & RepoStatus::setChecksum( const string &checksum )
130   {
131     _pimpl->checksum = checksum;
132     return *this;
133   }
134
135   RepoStatus & RepoStatus::setTimestamp( const Date &timestamp )
136   {
137     _pimpl->timestamp = timestamp;
138     return *this;
139   }
140
141   string RepoStatus::checksum() const
142   { return _pimpl->checksum; }
143
144   Date RepoStatus::timestamp() const
145   { return _pimpl->timestamp; }
146
147   RepoStatus operator&&( const RepoStatus & lhs, const RepoStatus & rhs )
148   {
149     if ( lhs.empty() )
150       return rhs;
151     if ( rhs.empty() )
152       return lhs;
153
154     std::string lchk( lhs.checksum() );
155     std::string rchk( rhs.checksum() );
156     // order strings to assert && is kommutativ
157     stringstream ss( lchk < rchk ? lchk+rchk : rchk+lchk );
158
159     RepoStatus result;
160     result.setChecksum( CheckSum::sha1(ss).checksum() );
161     result.setTimestamp( lhs.timestamp() < rhs.timestamp() ? rhs.timestamp() : lhs.timestamp() );
162     return result;
163   }
164
165   /******************************************************************
166   **
167   **    FUNCTION NAME : operator<<
168   **    FUNCTION TYPE : std::ostream &
169   */
170   std::ostream & operator<<( std::ostream & str, const RepoStatus & obj )
171   {
172     return str << *obj._pimpl;
173   }
174
175   /////////////////////////////////////////////////////////////////
176 } // namespace zypp
177 ///////////////////////////////////////////////////////////////////