- Create the cache directly from the schema (installed) file.
[platform/upstream/libzypp.git] / zypp / KVMap.h
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                    (C) SuSE Linux AG |
11 \----------------------------------------------------------------------/
12
13   File:       KVMap.h
14
15   Author:     Michael Andres <ma@suse.de>
16   Maintainer: Michael Andres <ma@suse.de>
17
18   Purpose: Convenience stuff for handling (key,value) pairs
19
20 /-*/
21 #ifndef KVMap_h
22 #define KVMap_h
23
24 #include <iosfwd>
25 #include <map>
26
27 #include "zypp/base/String.h"
28
29 namespace zypp {
30   namespace kvmap {
31
32     ///////////////////////////////////////////////////////////////////
33     //
34     //  CLASS NAME : KVMapBase::KVMapPolicy
35     /**
36      * @short KVMapPolicy for conversion of KVMaps to/from string.
37      *
38      * <b>_kvsplit</b>: The string separating key from value
39      *
40      * <b>_fsplit</b>:  (key,value) pairs are separated by any nonempty
41      * sequence of characers occurring in _fsplit
42      *
43      * <b>_kvjoin</b>: The string used to join key and value.
44      *
45      * <b>_fjoin</b>: The string used to separate (key,value) pairs.
46      *
47      * TODO: Maybe options for exact _fsplit handling and timming of values.
48      *
49      **/
50     struct KVMapPolicy {
51       std::string _kvsplit;
52       std::string _fsplit;
53       std::string _kvjoin;
54       std::string _fjoin;
55       KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r )
56         : _kvsplit( kvsplit_r )
57         , _fsplit ( fsplit_r )
58         , _kvjoin ( _kvsplit )
59         , _fjoin  ( _fsplit )
60       {}
61       KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r,
62              const std::string & kvjoin_r )
63         : _kvsplit( kvsplit_r )
64         , _fsplit ( fsplit_r )
65         , _kvjoin ( kvjoin_r )
66         , _fjoin  ( _fsplit )
67       {}
68       KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r,
69              const std::string & kvjoin_r, const std::string & fjoin_r )
70         : _kvsplit( kvsplit_r )
71         , _fsplit ( fsplit_r )
72         , _kvjoin ( kvjoin_r )
73         , _fjoin  ( fjoin_r )
74       {}
75     };
76
77     ///////////////////////////////////////////////////////////////////
78     //
79     //  CLASS NAME : KVMapBase
80     /**
81      * @short Base class for KVMaps, (key,value) pairs
82      **/
83     struct KVMapBase : public std::map<std::string,std::string> {
84     
85       /**
86        * (key,value) map type
87        **/
88       typedef std::map<std::string,std::string> map_type;
89     
90       KVMapBase()
91       {}
92       KVMapBase( const map_type & kvmap_r )
93         : std::map<std::string,std::string>( kvmap_r )
94       {}
95     
96       /**
97        * Test whether key is set.
98        **/
99       bool has( const std::string & key_r ) const {
100         return( find( key_r ) != end() );
101       }
102     
103       /**
104        * @short KVMapPolicy for KVMaps using a single char as separator (e.g. mount options).
105        **/
106       template<char kv, char f>
107       struct CharSep : public KVMapPolicy { CharSep() : KVMapPolicy( std::string(1,kv), std::string(1,f) ) {} };
108     
109       ///////////////////////////////////////////////////////////////////
110     
111       /**
112        * Split str_r into (key,value) map, using the separators defined
113        * by opts_r.
114        **/
115       static map_type split( const std::string & str_r,
116                          const KVMapPolicy & opts_r ) {
117         map_type ret;
118         std::vector<std::string> fields;
119         str::split( str_r, std::back_inserter(fields), opts_r._fsplit );
120     
121         for ( unsigned i = 0; i < fields.size(); ++i ) {
122           std::string::size_type pos = fields[i].find( opts_r._kvsplit );
123           if ( pos == std::string::npos ) {
124         ret[fields[i]] = "";
125           } else {
126         ret[fields[i].substr( 0, pos )] = fields[i].substr( pos+1 );
127           }
128         }
129     
130         return ret;
131       }
132     
133       /**
134        * Join (key,value) map into string, using the separators defined
135        * by opts_r.
136        **/
137       static std::string join( const map_type & kvmap_r,
138                            const KVMapPolicy & opts_r ) {
139         std::string ret;
140     
141         for ( map_type::const_iterator it = kvmap_r.begin(); it != kvmap_r.end(); ++it ) {
142           if ( ! ret.empty() ) {
143         ret += opts_r._fjoin;
144           }
145           ret += it->first;
146           if ( !it->second.empty() ) {
147         ret += opts_r._kvjoin + it->second;
148           }
149         }
150     
151         return ret;
152       }
153     
154     };
155
156
157
158   } // namespace kvmap
159
160   ///////////////////////////////////////////////////////////////////
161
162   ///////////////////////////////////////////////////////////////////
163   //
164   //    CLASS NAME : KVMap<KVMapOpts>
165   /**
166    * @short A map of (key,value) strings.
167    *
168    * The template argument defines the @ref kvmap::Options for
169    * split and join.
170    *
171    * E.g. mount options (a comma separated list of key[=value] pairs)
172    * could be handled by KVMap<kvmap::KVMapBase::Comma>.
173    **/
174   template<typename KVMapOpts>
175   struct KVMap : public kvmap::KVMapBase {
176   
177     KVMap()
178     {}
179     KVMap( const char * str_r )
180       : kvmap::KVMapBase( split( (str_r?str_r:""), KVMapOpts() ) )
181     {}
182     KVMap( const std::string & str_r )
183       : kvmap::KVMapBase( split( str_r, KVMapOpts() ) )
184     {}
185     KVMap( const map_type & map_r )
186       : kvmap::KVMapBase( map_r )
187     {}
188   
189     ~KVMap() {}
190   
191     std::string asString() const {
192       return join( *this, KVMapOpts() );
193     }
194   
195   };
196
197   ///////////////////////////////////////////////////////////////////
198
199   template<typename KVMapOpts>
200   std::ostream & operator<<( std::ostream & str, const KVMap<KVMapOpts> & obj )
201   { return str << obj.asString(); }
202
203 ///////////////////////////////////////////////////////////////////
204 } // namespace zypp
205
206 #endif // KVMap_h