KVMap.h

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                                                                      |
00003 |                      __   __    ____ _____ ____                      |
00004 |                      \ \ / /_ _/ ___|_   _|___ \                     |
00005 |                       \ V / _` \___ \ | |   __) |                    |
00006 |                        | | (_| |___) || |  / __/                     |
00007 |                        |_|\__,_|____/ |_| |_____|                    |
00008 |                                                                      |
00009 |                               core system                            |
00010 |                                                    (C) SuSE Linux AG |
00011 \----------------------------------------------------------------------/
00012 
00013   File:       KVMap.h
00014 
00015   Author:     Michael Andres <ma@suse.de>
00016   Maintainer: Michael Andres <ma@suse.de>
00017 
00018   Purpose: Convenience stuff for handling (key,value) pairs
00019 
00020 /-*/
00021 #ifndef KVMap_h
00022 #define KVMap_h
00023 
00024 #include <iosfwd>
00025 #include <vector>
00026 #include <map>
00027 
00028 #include "zypp/base/String.h"
00029 
00030 namespace zypp {
00031   namespace kvmap {
00032 
00034     //
00035     //  CLASS NAME : KVMapBase::KVMapPolicy
00051     struct KVMapPolicy {
00052       std::string _kvsplit;
00053       std::string _fsplit;
00054       std::string _kvjoin;
00055       std::string _fjoin;
00056       KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r )
00057         : _kvsplit( kvsplit_r )
00058         , _fsplit ( fsplit_r )
00059         , _kvjoin ( _kvsplit )
00060         , _fjoin  ( _fsplit )
00061       {}
00062       KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r,
00063              const std::string & kvjoin_r )
00064         : _kvsplit( kvsplit_r )
00065         , _fsplit ( fsplit_r )
00066         , _kvjoin ( kvjoin_r )
00067         , _fjoin  ( _fsplit )
00068       {}
00069       KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r,
00070              const std::string & kvjoin_r, const std::string & fjoin_r )
00071         : _kvsplit( kvsplit_r )
00072         , _fsplit ( fsplit_r )
00073         , _kvjoin ( kvjoin_r )
00074         , _fjoin  ( fjoin_r )
00075       {}
00076     };
00077 
00079     //
00080     //  CLASS NAME : KVMapBase
00084     struct KVMapBase : public std::map<std::string,std::string> {
00085     
00089       typedef std::map<std::string,std::string> map_type;
00090     
00091       KVMapBase()
00092       {}
00093       KVMapBase( const map_type & kvmap_r )
00094         : std::map<std::string,std::string>( kvmap_r )
00095       {}
00096     
00100       bool has( const std::string & key_r ) const {
00101         return( find( key_r ) != end() );
00102       }
00103     
00107       template<char kv, char f>
00108       struct CharSep : public KVMapPolicy { CharSep() : KVMapPolicy( std::string(1,kv), std::string(1,f) ) {} };
00109     
00111     
00116       static map_type split( const std::string & str_r,
00117                          const KVMapPolicy & opts_r ) {
00118         map_type ret;
00119         std::vector<std::string> fields;
00120         str::split( str_r, std::back_inserter(fields), opts_r._fsplit );
00121     
00122         for ( unsigned i = 0; i < fields.size(); ++i ) {
00123           std::string::size_type pos = fields[i].find( opts_r._kvsplit );
00124           if ( pos == std::string::npos ) {
00125         ret[fields[i]] = "";
00126           } else {
00127         ret[fields[i].substr( 0, pos )] = fields[i].substr( pos+1 );
00128           }
00129         }
00130     
00131         return ret;
00132       }
00133     
00138       static std::string join( const map_type & kvmap_r,
00139                            const KVMapPolicy & opts_r ) {
00140         std::string ret;
00141     
00142         for ( map_type::const_iterator it = kvmap_r.begin(); it != kvmap_r.end(); ++it ) {
00143           if ( ! ret.empty() ) {
00144         ret += opts_r._fjoin;
00145           }
00146           ret += it->first;
00147           if ( !it->second.empty() ) {
00148         ret += opts_r._kvjoin + it->second;
00149           }
00150         }
00151     
00152         return ret;
00153       }
00154     
00155     };
00156 
00157 
00158 
00159   } // namespace kvmap
00160 
00162 
00164   //
00165   //    CLASS NAME : KVMap<KVMapOpts>
00175   template<typename KVMapOpts>
00176   struct KVMap : public kvmap::KVMapBase {
00177   
00178     KVMap()
00179     {}
00180     KVMap( const char * str_r )
00181       : kvmap::KVMapBase( split( (str_r?str_r:""), KVMapOpts() ) )
00182     {}
00183     KVMap( const std::string & str_r )
00184       : kvmap::KVMapBase( split( str_r, KVMapOpts() ) )
00185     {}
00186     KVMap( const map_type & map_r )
00187       : kvmap::KVMapBase( map_r )
00188     {}
00189   
00190     ~KVMap() {}
00191   
00192     std::string asString() const {
00193       return join( *this, KVMapOpts() );
00194     }
00195   
00196   };
00197 
00199 
00200   template<typename KVMapOpts>
00201   std::ostream & operator<<( std::ostream & str, const KVMap<KVMapOpts> & obj )
00202   { return str << obj.asString(); }
00203 
00205 } // namespace zypp
00206 
00207 #endif // KVMap_h

doxygen