e90e4ac192de230a62158c4f14c352b2c3af09cd
[platform/upstream/libzypp.git] / zypp / target / HardLocksFile.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/target/HardLocksFile.h
10  *
11 */
12 #ifndef ZYPP_TARGET_HARDLOCKSFILE_H
13 #define ZYPP_TARGET_HARDLOCKSFILE_H
14
15 #include <iosfwd>
16
17 #include "zypp/base/PtrTypes.h"
18
19 #include "zypp/Pathname.h"
20 #include "zypp/pool/PoolTraits.h"
21 #include "zypp/PoolQuery.h"
22
23 ///////////////////////////////////////////////////////////////////
24 namespace zypp
25 { /////////////////////////////////////////////////////////////////
26   ///////////////////////////////////////////////////////////////////
27   namespace target
28   { /////////////////////////////////////////////////////////////////
29
30     ///////////////////////////////////////////////////////////////////
31     //
32     //  CLASS NAME : HardLocksFile
33     //
34     /** Save and restore hardlocks.
35      */
36     class HardLocksFile
37     {
38       friend std::ostream & operator<<( std::ostream & str, const HardLocksFile & obj );
39       public:
40
41         typedef pool::PoolTraits::HardLockQueries Data;
42
43       public:
44         /** Ctor taking the file to read/write. */
45         HardLocksFile( const Pathname & file_r )
46         : _file( file_r )
47         {}
48
49         /** Return the file path. */
50         const Pathname & file() const
51         { return _file; }
52
53         /** Return the data.
54          * The file is read once on demand. Returns empty \ref Data if
55          * the file does not exist or is not readable.
56         */
57         const Data & data() const
58         {
59           if ( !_dataPtr )
60           {
61             _dataPtr.reset( new Data );
62             Data & mydata( *_dataPtr );
63             load( _file, mydata );
64           }
65           return *_dataPtr;
66         }
67
68         /** Store new \ref Data.
69          * Write the new \ref Data to file, unless we know it
70          * did not change. The directory containing file must
71          * exist.
72         */
73         void setData( const Data & data_r )
74         {
75           if ( !_dataPtr )
76           {
77             if ( data_r.empty() )
78               return;   // bsc#1096803: Prevent against empty commit without Target having been been loaded (!_dataPtr )
79             _dataPtr.reset( new Data );
80           }
81
82           if ( differs( *_dataPtr, data_r ) )
83           {
84             store( _file, data_r );
85             *_dataPtr = data_r;
86           }
87         }
88
89       private:
90         /** Helper testing whether two \ref Data differ. */
91         bool differs( const Data & lhs, const Data & rhs ) const
92         {
93           if ( lhs.size() != rhs.size() )
94             return true;
95           // Complete diff is too expensive and not necessary here.
96           // Just check for the same sequence of items.
97           Data::const_iterator rit = rhs.begin();
98           for_( it, lhs.begin(), lhs.end() )
99           {
100             if ( *it != *rit )
101               return true;
102             ++rit;
103           }
104           return false;
105         }
106         /** Read \ref Data from \c file_r. */
107         static void load( const Pathname & file_r, Data & data_r );
108         /** Write \ref Data to \c file_r. */
109         static void store( const Pathname & file_r, const Data & data_r );
110
111       private:
112         Pathname                 _file;
113         mutable scoped_ptr<Data> _dataPtr;
114     };
115     ///////////////////////////////////////////////////////////////////
116
117     /** \relates HardLocksFile Stream output */
118     std::ostream & operator<<( std::ostream & str, const HardLocksFile & obj );
119
120     /////////////////////////////////////////////////////////////////
121   } // namespace target
122   ///////////////////////////////////////////////////////////////////
123   /////////////////////////////////////////////////////////////////
124 } // namespace zypp
125 ///////////////////////////////////////////////////////////////////
126 #endif // ZYPP_TARGET_HARDLOCKSFILE_H