updated data:: resolvable classes.
[platform/upstream/libzypp.git] / zypp / base / String.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/String.h
10  *
11 */
12 #ifndef ZYPP_BASE_STRING_H
13 #define ZYPP_BASE_STRING_H
14
15 #include <iosfwd>
16 #include <string>
17 #include <boost/regex.hpp>
18
19 ///////////////////////////////////////////////////////////////////
20 namespace zypp
21 { /////////////////////////////////////////////////////////////////
22   ///////////////////////////////////////////////////////////////////
23   /** String related utilities and \ref ZYPP_STR_REGEX.
24    \see \ref ZYPP_STR_REGEX
25   */
26   namespace str
27   { /////////////////////////////////////////////////////////////////
28
29     ///////////////////////////////////////////////////////////////////
30     /** Printf style construction of std::string. */
31     std::string form( const char * format, ... )
32     __attribute__ ((format (printf, 1, 2)));
33
34     ///////////////////////////////////////////////////////////////////
35     /** Return string describing the \a error_r code.
36      * Like ::strerror, but the numerical value is included in
37      * the string as well.
38     */
39     std::string strerror( int errno_r );
40
41     ///////////////////////////////////////////////////////////////////
42     /** Assert \c free called for allocated <tt>char *</tt>.
43      * \code
44      * ...
45      * SafeBuf safe;
46      * vasprintf( &safe._buf, format, ap );
47      * return safe.asString();
48      * \endcode
49      *
50      * \ingroup g_RAII
51     */
52     struct SafeBuf
53     {
54       char * _buf;
55       SafeBuf() : _buf( 0 ) {}
56       ~SafeBuf() { if ( _buf ) free( _buf ); }
57       std::string asString() const
58       { return _buf ? std::string(_buf) : std::string(); }
59     };
60
61     ///////////////////////////////////////////////////////////////////
62     /** \defgroup ZYPP_STR_REGEX Regular expressions
63      *
64      * Namespace zypp::str regular expressions \b using the
65      * boost regex library
66      * \url http://www.boost.org/libs/regex/doc/index.html.
67      *
68      * \li \c regex
69      * \li \c regex_match
70      * \li \c regex_search
71      * \li \c regex_replace
72      * \li \c match_results
73      * \li \c cmatch
74      * \li \c wcmatch
75      * \li \c smatch
76      * \li \c wsmatch
77     */
78
79     //@{
80     /** regex */
81     using boost::regex;
82     using boost::regex_match;
83     using boost::regex_search;
84     using boost::regex_replace;
85     using boost::match_results;
86     using boost::match_extra;
87     using boost::cmatch;
88     using boost::wcmatch;
89     using boost::smatch;
90     using boost::wsmatch;
91     //@}
92
93     /**
94      * helper to debug regular expressions matches
95      */
96     std::ostream & dumpRegexpResult( const boost::smatch &what, std::ostream & str );
97
98     ///////////////////////////////////////////////////////////////////
99     /** \name String representation of number.
100      *
101      * Optional second argument sets the minimal string width (' ' padded).
102      * Negative values will cause the number to be left adjusted within the string.
103      *
104      * Default width is 0.
105      * \code
106      * numstring(42)           -> "42"
107      * numstring(42, 4)        -> "  42"
108      * numstring(42,-4)        -> "42  "
109      * \endcode
110      **/
111     //@{
112     inline std::string numstring( char n,               int w = 0 ) { return form( "%*hhd",  w, n ); }
113     inline std::string numstring( unsigned char n,      int w = 0 ) { return form( "%*hhu",  w, n ); }
114     inline std::string numstring( short n,              int w = 0 ) { return form( "%*hd",   w, n ); }
115     inline std::string numstring( unsigned short n,     int w = 0 ) { return form( "%*hu",   w, n ); }
116     inline std::string numstring( int n,                int w = 0 ) { return form( "%*d",    w, n ); }
117     inline std::string numstring( unsigned n,           int w = 0 ) { return form( "%*u",    w, n ); }
118     inline std::string numstring( long n,               int w = 0 ) { return form( "%*ld",   w, n ); }
119     inline std::string numstring( unsigned long n,      int w = 0 ) { return form( "%*lu",   w, n ); }
120     inline std::string numstring( long long n,          int w = 0 ) { return form( "%*lld",  w, n ); }
121     inline std::string numstring( unsigned long long n, int w = 0 ) { return form( "%*llu",  w, n ); }
122     //@}
123
124     ///////////////////////////////////////////////////////////////////
125     /** \name String representation of number as hex value with leading '0x'.
126      * Optional second argument sets the minimal
127      * string width (0 padded). Negative values will cause the number to be left adjusted
128      * within the string. Default width is 10 (4 for char).
129      * <PRE>
130      * hexstring(42)           -> "0x0000002a"
131      * hexstring(42, 4)        -> "0x2a"
132      * hexstring(42,-4)        -> "0x2a"
133      * </PRE>
134      **/
135     //@{
136     inline std::string hexstring( char n,               int w = 4 ) { return form( "%#0*hhx", w, n ); }
137     inline std::string hexstring( unsigned char n,      int w = 4 ) { return form( "%#0*hhx", w, n ); }
138     inline std::string hexstring( short n,              int w = 10 ){ return form( "%#0*hx",  w, n ); }
139     inline std::string hexstring( unsigned short n,     int w = 10 ){ return form( "%#0*hx",  w, n ); }
140     inline std::string hexstring( int n,                int w = 10 ){ return form( "%#0*x",   w, n ); }
141     inline std::string hexstring( unsigned n,           int w = 10 ){ return form( "%#0*x",   w, n ); }
142     inline std::string hexstring( long n,               int w = 10 ){ return form( "%#0*lx",  w, n ); }
143     inline std::string hexstring( unsigned long n,      int w = 10 ){ return form( "%#0*lx",  w, n ); }
144     inline std::string hexstring( long long n,          int w = 0 ) { return form( "%#0*llx", w, n ); }
145     inline std::string hexstring( unsigned long long n, int w = 0 ) { return form( "%#0*llx", w, n ); }
146     //@}
147
148     ///////////////////////////////////////////////////////////////////
149     /** \name String representation of number as octal value with leading '0'.
150      * Optional second argument sets the minimal
151      * string width (0 padded). Negative values will cause the number to be left adjusted
152      * within the string. Default width is 5 (4 for char).
153      * <PRE>
154      * octstring(42)           -> "00052"
155      * octstring(42, 4)        -> "0052"
156      * octstring(42,-4)        -> "052 "
157      * </PRE>
158      **/
159     //@{
160     inline std::string octstring( char n,               int w = 4 ) { return form( "%#0*hho",  w, n ); }
161     inline std::string octstring( unsigned char n,      int w = 4 ) { return form( "%#0*hho",  w, n ); }
162     inline std::string octstring( short n,              int w = 5 ) { return form( "%#0*ho",   w, n ); }
163     inline std::string octstring( unsigned short n,     int w = 5 ) { return form( "%#0*ho",   w, n ); }
164     inline std::string octstring( int n,                int w = 5 ) { return form( "%#0*o",    w, n ); }
165     inline std::string octstring( unsigned n,           int w = 5 ) { return form( "%#0*o",    w, n ); }
166     inline std::string octstring( long n,               int w = 5 ) { return form( "%#0*lo",   w, n ); }
167     inline std::string octstring( unsigned long n,      int w = 5 ) { return form( "%#0*lo",   w, n ); }
168     inline std::string octstring( long long n,          int w = 0 ) { return form( "%#0*llo",  w, n ); }
169     inline std::string octstring( unsigned long long n, int w = 0 ) { return form( "%#0*llo",  w, n ); }
170     //@}
171
172     ///////////////////////////////////////////////////////////////////
173     /** Parsing numbers from string.
174     */
175     //@{
176     /** String to integer type determined by template arg.
177      * \note Only specializations are defined.
178      * \code
179      * time_t t = strtonum<time_t>( "42" );
180      * \endcode
181     */
182     template<typename _It>
183       _It strtonum( const std::string & str );
184
185     template<>
186       inline short              strtonum( const std::string & str ) { return ::strtol  ( str.c_str(), NULL, 0 ); }
187     template<>
188       inline int                strtonum( const std::string & str ) { return ::strtol  ( str.c_str(), NULL, 0 ); }
189     template<>
190       inline long               strtonum( const std::string & str ) { return ::strtol  ( str.c_str(), NULL, 0 ); }
191     template<>
192       inline long long          strtonum( const std::string & str ) { return ::strtoll ( str.c_str(), NULL, 0 ); }
193
194     template<>
195       inline unsigned short     strtonum( const std::string & str ) { return ::strtoul ( str.c_str(), NULL, 0 ); }
196     template<>
197       inline unsigned           strtonum( const std::string & str ) { return ::strtoul ( str.c_str(), NULL, 0 ); }
198     template<>
199       inline unsigned long      strtonum( const std::string & str ) { return ::strtoul ( str.c_str(), NULL, 0 ); }
200     template<>
201       inline unsigned long long strtonum( const std::string & str ) { return ::strtoull( str.c_str(), NULL, 0 ); }
202
203     /** String to integer type detemined 2nd function arg \a i.
204      * \code
205      * time_t t; strtonum( "42", t );
206      * \endcode
207     */
208     template<typename _It>
209       inline _It strtonum( const std::string & str, _It & i )
210       { return i = strtonum<_It>( str ); }
211     //@}
212
213     ///////////////////////////////////////////////////////////////////
214     /** \name Split. */
215     //@{
216     /** Split \a line_r into words.
217      * Any sequence of characters in \a sepchars_r is treated as
218      * delimiter. The words are passed to OutputIterator \a result_r.
219      * \code
220      * std::vector<std::string> words;
221      * str::split( "some line", std::back_inserter(words) )
222      * \endcode
223      *
224     */
225     template<class _OutputIterator>
226       unsigned split( const std::string & line_r,
227                       _OutputIterator     result_r,
228                       const std::string & sepchars_r = " \t" )
229       {
230         const char * beg = line_r.c_str();
231         const char * cur = beg;
232         // skip leading sepchars
233         while ( sepchars_r.find( *cur ) != std::string::npos )
234           ++cur;
235         unsigned ret = 0;
236         for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
237           {
238             // skip non sepchars
239             while( *cur && sepchars_r.find( *cur ) == std::string::npos )
240               ++cur;
241             // build string
242             *result_r = std::string( beg, cur-beg );
243             // skip sepchars
244             while ( sepchars_r.find( *cur ) != std::string::npos )
245               ++cur;
246           }
247         return ret;
248       }
249     //@}
250
251     ///////////////////////////////////////////////////////////////////
252     /** \name Join. */
253     //@{
254     /** Join strings using separator \a sep_r (defaults to BLANK). */
255     template <class _Iterator>
256       std::string join( _Iterator begin, _Iterator end,
257                         const std::string & sep_r = " " )
258       {
259         std::string res;
260         for ( _Iterator iter = begin; iter != end; ++ iter )
261           {
262             if ( iter != begin )
263               res += sep_r;
264             res += *iter;
265           }
266         return res;
267       }
268
269     /** Join strings using separator \a sep_r (defaults to BLANK). */
270     template <class _Container>
271       std::string join( const _Container & cont_r,
272                         const std::string & sep_r = " " )
273       { return join( cont_r.begin(), cont_r.end(), sep_r ); }
274     //@}
275
276
277     ///////////////////////////////////////////////////////////////////
278     /** \name Case conversion. */
279     //@{
280     /** Return lowercase version of \a s
281      * \todo improve
282     */
283     std::string toLower( const std::string & s );
284
285     /** Return uppercase version of \a s
286      * \todo improve
287     */
288     std::string toUpper( const std::string & s );
289     //@}
290
291     ///////////////////////////////////////////////////////////////////
292     /** \name Trimming whitepace.
293      * \todo optimize l/r trim.
294     */
295     //@{
296     /** To define how to trim. */
297     enum Trim {
298       NO_TRIM = 0x00,
299       L_TRIM  = 0x01,
300       R_TRIM  = 0x02,
301       TRIM    = (L_TRIM|R_TRIM)
302     };
303
304     std::string  trim( const std::string & s, const Trim trim_r = TRIM );
305
306     inline std::string ltrim( const std::string & s )
307     { return trim( s, L_TRIM ); }
308
309     inline std::string rtrim( const std::string & s )
310     { return trim( s, R_TRIM ); }
311     //@}
312
313     std::string stripFirstWord( std::string & line, const bool ltrim_first );
314
315     std::string getline( std::istream & str, bool trim = false );
316
317     std::string getline( std::istream & str, const Trim trim_r );
318
319     ///////////////////////////////////////////////////////////////////
320
321     /** \name String prefix handling.
322      */
323     //@{
324     /** Return whether \a str_r has prefix \a prefix_r. */
325     inline bool hasPrefix( const std::string & str_r, const std::string & prefix_r )
326     { return( str_r.substr( 0, prefix_r.size() ) == prefix_r ); }
327
328     /** Strip a \a prefix_r from \a str_r and return the resulting string. */
329     inline std::string stripPrefix( const std::string & str_r, const std::string & prefix_r )
330     { return( hasPrefix( str_r, prefix_r ) ? str_r.substr( prefix_r.size() ) : str_r ); }
331     //@}
332
333     /////////////////////////////////////////////////////////////////
334   } // namespace str
335   ///////////////////////////////////////////////////////////////////
336   /////////////////////////////////////////////////////////////////
337 } // namespace zypp
338 ///////////////////////////////////////////////////////////////////
339 #endif // ZYPP_BASE_STRING_H