Imported Upstream version 17.0.0
[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     */
43     class Pathname
44     {
45     public:
46       /** Default ctor: an empty path. */
47       Pathname()
48       {}
49
50       /** Ctor from string. */
51       Pathname( const std::string & name_r )
52       { _assign( name_r ); }
53
54       /** Ctor from char*. */
55       Pathname( const char * name_r )
56       { _assign( name_r ? name_r : "" ); }
57
58       /** Copy Ctor */
59       Pathname( const Pathname & rhs )
60       : _name( rhs._name )
61       {}
62
63       /** Swap */
64       friend void swap( Pathname & lhs, Pathname & rhs )
65       {
66         using std::swap;
67         swap( lhs._name, rhs._name );
68       }
69 #ifndef SWIG // Swig treats it as syntax error
70       /** Move Ctor */
71       Pathname( Pathname && tmp )
72       : _name( std::move( tmp._name ) )
73       {}
74 #endif
75       /** Assign */
76       Pathname & operator=( Pathname rhs )
77       { swap( *this, rhs ); return *this; }
78
79       /** Concatenate and assign. \see cat */
80       Pathname & operator/=( const Pathname & path_tv )
81       { return( *this = cat( *this, path_tv ) ); }
82
83       /** Concatenate and assign. \see cat
84        * \deprecated: use /=
85       */
86       Pathname & operator+=( const Pathname & path_tv )
87       { return( *this = cat( *this, path_tv ) ); }
88
89       /** String representation. */
90       const std::string & asString() const
91       { return _name; }
92
93       /** String representation as "(root)/path" */
94       static std::string showRoot( const Pathname & root_r, const Pathname & path_r );
95
96       /** String representation as "(root)/path", unless \a root is \c "/" or empty. */
97       static std::string showRootIf( const Pathname & root_r, const Pathname & path_r );
98
99       /** Url representation using \c scheme_r schema . */
100       Url asUrl( const std::string & scheme_r ) const;
101       /** \overload using \c dir schema. */
102       Url asUrl() const;
103       /** \overload using \c dir schema. */
104       Url asDirUrl() const;
105       /** \overload using \c file schema. */
106       Url asFileUrl() const;
107
108       /** String representation. */
109       const char * c_str() const
110       { return _name.c_str(); }
111
112       /** Test for an empty path. */
113       bool empty()    const { return _name.empty(); }
114       /** Test for an absolute path. */
115       bool absolute() const { return *_name.c_str() == '/'; }
116       /** Test for a relative path. */
117       bool relative() const { return !( absolute() || empty() ); }
118
119       /** Test for "" or "/". */
120       bool emptyOrRoot() const { return( _name.empty() || _name == "/" ); }
121
122       /** Return all but the last component od this path. */
123       Pathname dirname() const { return dirname( *this ); }
124       static Pathname dirname( const Pathname & name_r );
125
126       /** Return the last component of this path. */
127       std::string basename() const { return basename( *this ); }
128       static std::string basename( const Pathname & name_r );
129
130       /** Return all of the characters in name after and including
131        * the last dot in the last element of name.  If there is no dot
132        * in the last element of name then returns the empty string.
133       */
134       std::string extension() const { return extension( *this ); }
135       static std::string extension( const Pathname & name_r );
136
137       /** Return this path, adding a leading '/' if relative. */
138       Pathname absolutename() const { return absolutename( *this ); }
139       static Pathname absolutename( const Pathname & name_r )
140       { return name_r.relative() ? cat( "/", name_r ) : name_r; }
141
142       /** Return this path, removing a leading '/' if absolute.*/
143       Pathname relativename() const { return relativename( *this ); }
144       static Pathname relativename( const Pathname & name_r )
145       { return name_r.absolute() ? cat( ".", name_r ) : name_r; }
146
147       /** Return \c path_r prefixed with \c root_r, unless it is already prefixed. */
148       static Pathname assertprefix( const Pathname & root_r, const Pathname & path_r );
149
150       /** Concatenation of pathnames.
151        * \code
152        *   "foo"  / "baa"  ==> "foo/baa"
153        *   "foo/" / "baa"  ==> "foo/baa"
154        *   "foo"  / "/baa" ==> "foo/baa"
155        *   "foo/" / "/baa" ==> "foo/baa"
156        * \endcode
157       */
158       Pathname cat( const Pathname & r ) const { return cat( *this, r ); }
159       static Pathname cat( const Pathname & l, const Pathname & r );
160
161       /** Append string \a r to the last component of the path.
162        * \code
163        *   "foo/baa".extend( ".h" ) ==> "foo/baa.h"
164        * \endcode
165       */
166       Pathname extend( const std::string & r ) const { return extend( *this, r ); }
167       static Pathname extend( const Pathname & l, const std::string & r );
168
169     private:
170       std::string _name;
171       void _assign( const std::string & name_r );
172     };
173     ///////////////////////////////////////////////////////////////////
174
175     /** \relates Pathname */
176     inline bool operator==( const Pathname & l, const Pathname & r )
177     { return l.asString() == r.asString(); }
178
179     /** \relates Pathname */
180     inline bool operator!=( const Pathname & l, const Pathname & r )
181     { return l.asString() != r.asString(); }
182
183     /** \relates Pathname Concatenate two Pathname. */
184     inline Pathname operator/( const Pathname & l, const Pathname & r )
185     { return Pathname::cat( l, r ); }
186
187     /** \relates Pathname Concatenate two Pathname.
188      * \deprecated: use /
189     */
190     inline Pathname operator+( const Pathname & l, const Pathname & r )
191     { return Pathname::cat( l, r ); }
192
193     /** \relates Pathname */
194     inline bool operator<( const Pathname & l, const Pathname & r )
195     { return l.asString() < r.asString(); }
196
197     ///////////////////////////////////////////////////////////////////
198
199     /** \relates Pathname Stream output */
200     inline std::ostream & operator<<( std::ostream & str, const Pathname & obj )
201     { return str << obj.asString(); }
202
203     /////////////////////////////////////////////////////////////////
204   } // namespace filesystem
205   ///////////////////////////////////////////////////////////////////
206
207   /** Dragged into namespace zypp. */
208   using filesystem::Pathname;
209
210   /////////////////////////////////////////////////////////////////
211 } // namespace zypp
212 ///////////////////////////////////////////////////////////////////
213 #endif // ZYPP_PATHNAME_H