0632536b9ffe75052d22cd6b02eb3020683a265b
[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   class Url;
23
24   ///////////////////////////////////////////////////////////////////
25   namespace filesystem
26   { /////////////////////////////////////////////////////////////////
27
28     ///////////////////////////////////////////////////////////////////
29     //
30     //  CLASS NAME : Pathname
31     //
32     /** Pathname.
33      *
34      * \note For convenience Pathname is available as zypp::Pathname too.
35      *
36      * Always stores normalized paths (no inner '.' or '..' components
37      * and no consecutive '/'es). Concatenation automatically adds
38      * the path separator '/'.
39      *
40      * \todo Add support for handling extensions incl. stripping
41      * extensions from basename (basename("/path/foo.baa", ".baa") ==> "foo")
42      * \todo Review. Maybe use COW pimpl, check storage.
43      * \todo \b EXPLICIT ctors.
44     */
45     class Pathname
46     {
47     public:
48       /** Default ctor: an empty path. */
49       Pathname()
50       : prfx_i( 0 )
51       {}
52
53       /** Ctor from string. */
54       Pathname( const std::string & name_tv )
55       { _assign( name_tv ); }
56
57       /** Ctor from char*. */
58       Pathname( const char * name_tv )
59       { _assign( name_tv ? name_tv : "" ); }
60
61       /** Assign */
62       Pathname & operator=( const Pathname & path_tv )
63       {
64         prfx_i = path_tv.prfx_i;
65         name_t = path_tv.name_t;
66         return *this;
67       }
68
69       /** Concatenate and assing. \see cat */
70       Pathname & operator/=( const Pathname & path_tv )
71       { return( *this = cat( *this, path_tv ) ); }
72
73       /** Concatenate and assing. \see cat
74        * \deprecated: use /=
75       */
76       Pathname & operator+=( const Pathname & path_tv )
77       { return( *this = cat( *this, path_tv ) ); }
78
79       /** String representation. */
80       const std::string & asString() const
81       { return name_t; }
82
83       /** Url representation using \c dir schema. */
84       Url asUrl() const;
85
86       /** String representation. */
87       const char * c_str() const
88       { return name_t.c_str(); }
89
90       /** Test for an empty path. */
91       bool empty()    const { return name_t.empty(); }
92       /** Test for an absolute path. */
93       bool absolute() const { return !empty() && name_t[prfx_i] == '/'; }
94       /** Test for a relative path. */
95       bool relative() const { return !empty() && name_t[prfx_i] != '/'; }
96
97       /** Return all but the last component od this path. */
98       Pathname dirname() const { return dirname( *this ); }
99       static Pathname dirname( const Pathname & name_tv );
100
101       /** Return the last component of this path. */
102       std::string basename() const { return basename( *this ); }
103       static std::string basename( const Pathname & name_tv );
104
105       /** Return all of the characters in name after and including
106        * the last dot in the last element of name.  If there is no dot
107        * in the last element of name then returns the empty string.
108       */
109       std::string extension() const { return extension( *this ); }
110       static std::string extension( const Pathname & name_tv );
111
112       /** Return this path, adding a leading '/' if relative. */
113       Pathname absolutename() const { return absolutename( *this ); }
114       static Pathname absolutename( const Pathname & name_tv )
115       { return name_tv.relative() ? cat( "/", name_tv ) : name_tv; }
116
117       /** Return this path, removing a leading '/' if absolute.*/
118       Pathname relativename() const { return relativename( *this ); }
119       static Pathname relativename( const Pathname & name_tv )
120       { return name_tv.absolute() ? cat( ".", name_tv ) : name_tv; }
121
122       /** Return \c path_r prefixed with \c root_r, unless it is already prefixed. */
123       static Pathname assertprefix( const Pathname & root_r, const Pathname & path_r );
124
125       /** Concatenation of pathnames.
126        * \code
127        *   "foo"  / "baa"  ==> "foo/baa"
128        *   "foo/" / "baa"  ==> "foo/baa"
129        *   "foo"  / "/baa" ==> "foo/baa"
130        *   "foo/" / "/baa" ==> "foo/baa"
131        * \endcode
132       */
133       Pathname cat( const Pathname & r ) const { return cat( *this, r ); }
134       static Pathname cat( const Pathname & l, const Pathname & r );
135
136       /** Append string \a r to the last component of the path.
137        * \code
138        *   "foo/baa".extend( ".h" ) ==> "foo/baa.h"
139        * \endcode
140       */
141       Pathname extend( const std::string & r ) const { return extend( *this, r ); }
142       static Pathname extend( const Pathname & l, const std::string & r );
143
144     private:
145       std::string::size_type prfx_i;
146       std::string            name_t;
147
148       void _assign( const std::string & name_tv );
149     };
150     ///////////////////////////////////////////////////////////////////
151
152     /** \relates Pathname */
153     inline bool operator==( const Pathname & l, const Pathname & r )
154     { return l.asString() == r.asString(); }
155
156     /** \relates Pathname */
157     inline bool operator!=( const Pathname & l, const Pathname & r )
158     { return l.asString() != r.asString(); }
159
160     /** \relates Pathname Concatenate two Pathname. */
161     inline Pathname operator/( const Pathname & l, const Pathname & r )
162     { return Pathname::cat( l, r ); }
163
164     /** \relates Pathname Concatenate two Pathname.
165      * \deprecated: use /
166     */
167     inline Pathname operator+( const Pathname & l, const Pathname & r )
168     { return Pathname::cat( l, r ); }
169
170     /** \relates Pathname */
171     inline bool operator<( const Pathname & l, const Pathname & r )
172     { return l.asString() < r.asString(); }
173
174     ///////////////////////////////////////////////////////////////////
175
176     /** \relates Pathname Stream output */
177     inline std::ostream & operator<<( std::ostream & str, const Pathname & obj )
178     { return str << obj.asString(); }
179
180     /////////////////////////////////////////////////////////////////
181   } // namespace filesystem
182   ///////////////////////////////////////////////////////////////////
183
184   /** Dragged into namespace zypp. */
185   using filesystem::Pathname;
186
187   /////////////////////////////////////////////////////////////////
188 } // namespace zypp
189 ///////////////////////////////////////////////////////////////////
190 #endif // ZYPP_PATHNAME_H