1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
15 Author: Michael Andres <ma@suse.de>
16 Maintainer: Michael Andres <ma@suse.de>
18 Purpose: Convenience stuff for handling (key,value) pairs
27 #include "zypp/base/String.h"
32 ///////////////////////////////////////////////////////////////////
34 // CLASS NAME : KVMapBase::KVMapPolicy
36 * @short KVMapPolicy for conversion of KVMaps to/from string.
38 * <b>_kvsplit</b>: The string separating key from value
40 * <b>_fsplit</b>: (key,value) pairs are separated by any nonempty
41 * sequence of characers occurring in _fsplit
43 * <b>_kvjoin</b>: The string used to join key and value.
45 * <b>_fjoin</b>: The string used to separate (key,value) pairs.
47 * TODO: Maybe options for exact _fsplit handling and timming of values.
55 KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r )
56 : _kvsplit( kvsplit_r )
57 , _fsplit ( fsplit_r )
58 , _kvjoin ( _kvsplit )
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 )
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 )
77 ///////////////////////////////////////////////////////////////////
79 // CLASS NAME : KVMapBase
81 * @short Base class for KVMaps, (key,value) pairs
83 struct KVMapBase : public std::map<std::string,std::string> {
86 * (key,value) map type
88 typedef std::map<std::string,std::string> map_type;
92 KVMapBase( const map_type & kvmap_r )
93 : std::map<std::string,std::string>( kvmap_r )
97 * Test whether key is set.
99 bool has( const std::string & key_r ) const {
100 return( find( key_r ) != end() );
104 * @short KVMapPolicy for KVMaps using a single char as separator (e.g. mount options).
106 template<char kv, char f>
107 struct CharSep : public KVMapPolicy { CharSep() : KVMapPolicy( std::string(1,kv), std::string(1,f) ) {} };
109 ///////////////////////////////////////////////////////////////////
112 * Split str_r into (key,value) map, using the separators defined
115 static map_type split( const std::string & str_r,
116 const KVMapPolicy & opts_r ) {
118 std::vector<std::string> fields;
119 str::split( str_r, std::back_inserter(fields), opts_r._fsplit );
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 ) {
126 ret[fields[i].substr( 0, pos )] = fields[i].substr( pos+1 );
134 * Join (key,value) map into string, using the separators defined
137 static std::string join( const map_type & kvmap_r,
138 const KVMapPolicy & opts_r ) {
141 for ( map_type::const_iterator it = kvmap_r.begin(); it != kvmap_r.end(); ++it ) {
142 if ( ! ret.empty() ) {
143 ret += opts_r._fjoin;
146 if ( !it->second.empty() ) {
147 ret += opts_r._kvjoin + it->second;
160 ///////////////////////////////////////////////////////////////////
162 ///////////////////////////////////////////////////////////////////
164 // CLASS NAME : KVMap<KVMapOpts>
166 * @short A map of (key,value) strings.
168 * The template argument defines the @ref kvmap::Options for
171 * E.g. mount options (a comma separated list of key[=value] pairs)
172 * could be handled by KVMap<kvmap::KVMapBase::Comma>.
174 template<typename KVMapOpts>
175 struct KVMap : public kvmap::KVMapBase {
179 KVMap( const char * str_r )
180 : kvmap::KVMapBase( split( (str_r?str_r:""), KVMapOpts() ) )
182 KVMap( const std::string & str_r )
183 : kvmap::KVMapBase( split( str_r, KVMapOpts() ) )
185 KVMap( const map_type & map_r )
186 : kvmap::KVMapBase( map_r )
191 std::string asString() const {
192 return join( *this, KVMapOpts() );
197 ///////////////////////////////////////////////////////////////////
199 template<typename KVMapOpts>
200 std::ostream & operator<<( std::ostream & str, const KVMap<KVMapOpts> & obj )
201 { return str << obj.asString(); }
203 ///////////////////////////////////////////////////////////////////