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 <y2util/stringutil.h>
00028
00030
00031
00035 struct _KVMap : public std::map<std::string,std::string> {
00036
00040 typedef std::map<std::string,std::string> map_type;
00041
00042 _KVMap()
00043 {}
00044 _KVMap( const map_type & kvmap_r )
00045 : std::map<std::string,std::string>( kvmap_r )
00046 {}
00047
00051 bool has( const std::string & key_r ) const {
00052 return( find( key_r ) != end() );
00053 }
00054
00056
00057
00073 struct Options {
00074 std::string _kvsplit;
00075 std::string _fsplit;
00076 std::string _kvjoin;
00077 std::string _fjoin;
00078 Options( const std::string & kvsplit_r, const std::string & fsplit_r )
00079 : _kvsplit( kvsplit_r )
00080 , _fsplit ( fsplit_r )
00081 , _kvjoin ( _kvsplit )
00082 , _fjoin ( _fsplit )
00083 {}
00084 Options( const std::string & kvsplit_r, const std::string & fsplit_r,
00085 const std::string & kvjoin_r )
00086 : _kvsplit( kvsplit_r )
00087 , _fsplit ( fsplit_r )
00088 , _kvjoin ( kvjoin_r )
00089 , _fjoin ( _fsplit )
00090 {}
00091 Options( const std::string & kvsplit_r, const std::string & fsplit_r,
00092 const std::string & kvjoin_r, const std::string & fjoin_r )
00093 : _kvsplit( kvsplit_r )
00094 , _fsplit ( fsplit_r )
00095 , _kvjoin ( kvjoin_r )
00096 , _fjoin ( fjoin_r )
00097 {}
00098 };
00099
00103 template<char kv, char f>
00104 struct CharSep : public Options { CharSep() : Options( string(1,kv), string(1,f) ) {} };
00105
00107
00112 static map_type split( const std::string & str_r,
00113 const Options & opts_r ) {
00114 map_type ret;
00115 std::vector<std::string> fields;
00116 stringutil::split( str_r, fields, opts_r._fsplit );
00117
00118 for ( unsigned i = 0; i < fields.size(); ++i ) {
00119 std::string::size_type pos = fields[i].find( opts_r._kvsplit );
00120 if ( pos == std::string::npos ) {
00121 ret[fields[i]] = "";
00122 } else {
00123 ret[fields[i].substr( 0, pos )] = fields[i].substr( pos+1 );
00124 }
00125 }
00126
00127 return ret;
00128 }
00129
00134 static std::string join( const map_type & kvmap_r,
00135 const Options & opts_r ) {
00136 std::string ret;
00137
00138 for ( map_type::const_iterator it = kvmap_r.begin(); it != kvmap_r.end(); ++it ) {
00139 if ( ! ret.empty() ) {
00140 ret += opts_r._fjoin;
00141 }
00142 ret += it->first;
00143 if ( !it->second.empty() ) {
00144 ret += opts_r._kvjoin + it->second;
00145 }
00146 }
00147
00148 return ret;
00149 }
00150
00151 };
00152
00154
00156
00157
00167 template<typename KVMapOpts>
00168 struct KVMap : public _KVMap {
00169
00170 KVMap()
00171 {}
00172 KVMap( const char * str_r )
00173 : _KVMap( split( (str_r?str_r:""), KVMapOpts() ) )
00174 {}
00175 KVMap( const std::string & str_r )
00176 : _KVMap( split( str_r, KVMapOpts() ) )
00177 {}
00178 KVMap( const map_type & map_r )
00179 : _KVMap( map_r )
00180 {}
00181
00182 ~KVMap() {}
00183
00184 std::string asString() const {
00185 return join( *this, KVMapOpts() );
00186 }
00187
00188 };
00189
00191
00192 template<typename KVMapOpts>
00193 std::ostream & operator<<( std::ostream & str, const KVMap<KVMapOpts> & obj ) {
00194 return str << obj.asString();
00195 }
00196
00198
00199 #endif // KVMap_h