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