backup
[platform/upstream/libzypp.git] / zypp / Pathname.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/Pathname.h
10  *
11 */
12 #ifndef ZYPP_PATHNAME_H
13 #define ZYPP_PATHNAME_H
14
15 #include <iosfwd>
16 #include <string>
17
18 ///////////////////////////////////////////////////////////////////
19 namespace zypp
20 { /////////////////////////////////////////////////////////////////
21
22   ///////////////////////////////////////////////////////////////////
23   //
24   //    CLASS NAME : Pathname
25   //
26   /** Pathname.
27    *
28    * Always stores normalized paths (no inner '.' or '..' components
29    * and no consecutive '/'es). Concatenation automatically adds
30    * the path separator '/'.
31    *
32    * \todo Add support for handling extensions incl. stripping
33    * extensions from basename (basename("/path/foo.baa", ".baa") ==> "foo")
34    * \todo Review. Maybe use COW pimpl, ckeck storage.
35   */
36   class Pathname
37   {
38   public:
39     /** Default ctor: an empty path. */
40     Pathname()
41     : prfx_i( 0 )
42     {}
43
44     /** Ctor from string. */
45     Pathname( const std::string & name_tv )
46     { _assign( name_tv ); }
47
48     /** Ctor from char*. */
49     Pathname( const char * name_tv )
50     { _assign( name_tv ? name_tv : "" ); }
51
52     /** Assign */
53     Pathname & operator=( const Pathname & path_tv )
54     {
55       prfx_i = path_tv.prfx_i;
56       name_t = path_tv.name_t;
57       return *this;
58     }
59
60     /** Concatenate and assing. \see cat */
61     Pathname & operator+=( const Pathname & path_tv )
62     { return( *this = cat( *this, path_tv ) ); }
63
64     /** String representation. */
65     const std::string & asString() const
66     { return name_t; }
67
68     /** Test for an empty path. */
69     bool empty()    const { return name_t.empty(); }
70     /** Test for an absolute path. */
71     bool absolute() const { return !empty() && name_t[prfx_i] == '/'; }
72     /** Test for a relative path. */
73     bool relative() const { return !empty() && name_t[prfx_i] != '/'; }
74
75     /** Return all but the last component od this path. */
76     Pathname dirname() const { return dirname( *this ); }
77     static Pathname dirname( const Pathname & name_tv );
78
79     /** Return the last component of this path. */
80     std::string basename() const { return basename( *this ); }
81     static std::string basename( const Pathname & name_tv );
82
83     /** Return this path, adding a leading '/' if relative. */
84     Pathname absolutename() const { return absolutename( *this ); }
85     static Pathname absolutename( const Pathname & name_tv )
86     { return name_tv.relative() ? cat( "/", name_tv ) : name_tv; }
87
88     /** Return this path, removing a leading '/' if absolute.*/
89     Pathname relativename() const { return relativename( *this ); }
90     static Pathname relativename( const Pathname & name_tv )
91     { return name_tv.absolute() ? cat( ".", name_tv ) : name_tv; }
92
93     /** Concatenation of pathnames.
94      * \code
95      *   "foo"  + "baa"  ==> "foo/baa"
96      *   "foo/" + "baa"  ==> "foo/baa"
97      *   "foo"  + "/baa" ==> "foo/baa"
98      *   "foo/" + "/baa" ==> "foo/baa"
99      * \endcode
100     */
101     Pathname cat( const Pathname & r ) const { return cat( *this, r ); }
102     static Pathname cat( const Pathname & l, const Pathname & r );
103
104     /** Append string \a r to the last component of the path.
105      * \code
106      *   "foo/baa".extend( ".h" ) ==> "foo/baa.h"
107      * \endcode
108     */
109     Pathname extend( const std::string & r ) const { return extend( *this, r ); }
110     static Pathname extend( const Pathname & l, const std::string & r );
111
112   private:
113     std::string::size_type prfx_i;
114     std::string            name_t;
115
116     void _assign( const std::string & name_tv );
117   };
118   ///////////////////////////////////////////////////////////////////
119
120   /** \relates Pathname */
121   inline bool operator==( const Pathname & l, const Pathname & r )
122   { return l.asString() == r.asString(); }
123
124   /** \relates Pathname */
125   inline bool operator!=( const Pathname & l, const Pathname & r )
126   { return l.asString() != r.asString(); }
127
128   /** \relates Pathname Concatenate two Pathname. */
129   inline Pathname operator+( const Pathname & l, const Pathname & r )
130   { return Pathname::cat( l, r ); }
131
132   ///////////////////////////////////////////////////////////////////
133
134   /** \relates Pathname Stream output */
135   inline std::ostream & operator<<( std::ostream & str, const Pathname & obj )
136   { return str << obj.asString(); }
137
138   /////////////////////////////////////////////////////////////////
139 } // namespace zypp
140 ///////////////////////////////////////////////////////////////////
141 #endif // ZYPP_PATHNAME_H