00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef KVMap_h
00022 #define KVMap_h
00023
00024 #include <iosfwd>
00025 #include <map>
00026
00027 #include "zypp/base/String.h"
00028
00029 namespace zypp {
00030 namespace kvmap {
00031
00033
00034
00050 struct KVMapPolicy {
00051 std::string _kvsplit;
00052 std::string _fsplit;
00053 std::string _kvjoin;
00054 std::string _fjoin;
00055 KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r )
00056 : _kvsplit( kvsplit_r )
00057 , _fsplit ( fsplit_r )
00058 , _kvjoin ( _kvsplit )
00059 , _fjoin ( _fsplit )
00060 {}
00061 KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r,
00062 const std::string & kvjoin_r )
00063 : _kvsplit( kvsplit_r )
00064 , _fsplit ( fsplit_r )
00065 , _kvjoin ( kvjoin_r )
00066 , _fjoin ( _fsplit )
00067 {}
00068 KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r,
00069 const std::string & kvjoin_r, const std::string & fjoin_r )
00070 : _kvsplit( kvsplit_r )
00071 , _fsplit ( fsplit_r )
00072 , _kvjoin ( kvjoin_r )
00073 , _fjoin ( fjoin_r )
00074 {}
00075 };
00076
00078
00079
00083 struct KVMapBase : public std::map<std::string,std::string> {
00084
00088 typedef std::map<std::string,std::string> map_type;
00089
00090 KVMapBase()
00091 {}
00092 KVMapBase( const map_type & kvmap_r )
00093 : std::map<std::string,std::string>( kvmap_r )
00094 {}
00095
00099 bool has( const std::string & key_r ) const {
00100 return( find( key_r ) != end() );
00101 }
00102
00106 template<char kv, char f>
00107 struct CharSep : public KVMapPolicy { CharSep() : KVMapPolicy( std::string(1,kv), std::string(1,f) ) {} };
00108
00110
00115 static map_type split( const std::string & str_r,
00116 const KVMapPolicy & opts_r ) {
00117 map_type ret;
00118 std::vector<std::string> fields;
00119 str::split( str_r, std::back_inserter(fields), opts_r._fsplit );
00120
00121 for ( unsigned i = 0; i < fields.size(); ++i ) {
00122 std::string::size_type pos = fields[i].find( opts_r._kvsplit );
00123 if ( pos == std::string::npos ) {
00124 ret[fields[i]] = "";
00125 } else {
00126 ret[fields[i].substr( 0, pos )] = fields[i].substr( pos+1 );
00127 }
00128 }
00129
00130 return ret;
00131 }
00132
00137 static std::string join( const map_type & kvmap_r,
00138 const KVMapPolicy & opts_r ) {
00139 std::string ret;
00140
00141 for ( map_type::const_iterator it = kvmap_r.begin(); it != kvmap_r.end(); ++it ) {
00142 if ( ! ret.empty() ) {
00143 ret += opts_r._fjoin;
00144 }
00145 ret += it->first;
00146 if ( !it->second.empty() ) {
00147 ret += opts_r._kvjoin + it->second;
00148 }
00149 }
00150
00151 return ret;
00152 }
00153
00154 };
00155
00156
00157
00158 }
00159
00161
00163
00164
00174 template<typename KVMapOpts>
00175 struct KVMap : public kvmap::KVMapBase {
00176
00177 KVMap()
00178 {}
00179 KVMap( const char * str_r )
00180 : kvmap::KVMapBase( split( (str_r?str_r:""), KVMapOpts() ) )
00181 {}
00182 KVMap( const std::string & str_r )
00183 : kvmap::KVMapBase( split( str_r, KVMapOpts() ) )
00184 {}
00185 KVMap( const map_type & map_r )
00186 : kvmap::KVMapBase( map_r )
00187 {}
00188
00189 ~KVMap() {}
00190
00191 std::string asString() const {
00192 return join( *this, KVMapOpts() );
00193 }
00194
00195 };
00196
00198
00199 template<typename KVMapOpts>
00200 std::ostream & operator<<( std::ostream & str, const KVMap<KVMapOpts> & obj )
00201 { return str << obj.asString(); }
00202
00204 }
00205
00206 #endif // KVMap_h