Imported Upstream version 16.3.2
[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             _dataPtr.reset( new Data );
77
78           if ( differs( *_dataPtr, data_r ) )
79           {
80             store( _file, data_r );
81             *_dataPtr = data_r;
82           }
83         }
84
85       private:
86         /** Helper testing whether two \ref Data differ. */
87         bool differs( const Data & lhs, const Data & rhs ) const
88         {
89           if ( lhs.size() != rhs.size() )
90             return true;
91           // Complete diff is too expensive and not necessary here.
92           // Just check for the same sequence of items.
93           Data::const_iterator rit = rhs.begin();
94           for_( it, lhs.begin(), lhs.end() )
95           {
96             if ( *it != *rit )
97               return true;
98             ++rit;
99           }
100           return false;
101         }
102         /** Read \ref Data from \c file_r. */
103         static void load( const Pathname & file_r, Data & data_r );
104         /** Write \ref Data to \c file_r. */
105         static void store( const Pathname & file_r, const Data & data_r );
106
107       private:
108         Pathname                 _file;
109         mutable scoped_ptr<Data> _dataPtr;
110     };
111     ///////////////////////////////////////////////////////////////////
112
113     /** \relates HardLocksFile Stream output */
114     std::ostream & operator<<( std::ostream & str, const HardLocksFile & obj );
115
116     /////////////////////////////////////////////////////////////////
117   } // namespace target
118   ///////////////////////////////////////////////////////////////////
119   /////////////////////////////////////////////////////////////////
120 } // namespace zypp
121 ///////////////////////////////////////////////////////////////////
122 #endif // ZYPP_TARGET_HARDLOCKSFILE_H