2 /*---------------------------------------------------------------------\
4 | |__ / \ / / . \ . \ |
9 \---------------------------------------------------------------------*/
10 /** \file zypp/Pathname.h
13 #ifndef ZYPP_PATHNAME_H
14 #define ZYPP_PATHNAME_H
19 ///////////////////////////////////////////////////////////////////
21 { /////////////////////////////////////////////////////////////////
25 ///////////////////////////////////////////////////////////////////
27 { /////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////
31 // CLASS NAME : Pathname
35 * \note For convenience Pathname is available as zypp::Pathname too.
37 * Always stores normalized paths (no inner '.' or '..' components
38 * and no consecutive '/'es). Concatenation automatically adds
39 * the path separator '/'.
41 * \todo Add support for handling extensions incl. stripping
42 * extensions from basename (basename("/path/foo.baa", ".baa") ==> "foo")
47 /** Default ctor: an empty path. */
51 /** Ctor from string. */
52 Pathname( const std::string & name_r )
53 { _assign( name_r ); }
55 /** Ctor from char*. */
56 Pathname( const char * name_r )
57 { _assign( name_r ? name_r : "" ); }
60 Pathname( const Pathname & rhs )
65 friend void swap( Pathname & lhs, Pathname & rhs )
68 swap( lhs._name, rhs._name );
72 Pathname( Pathname && tmp )
73 : _name( std::move( tmp._name ) )
77 Pathname & operator=( Pathname rhs )
78 { swap( *this, rhs ); return *this; }
80 /** Concatenate and assign. \see cat */
81 Pathname & operator/=( const Pathname & path_tv )
82 { return( *this = cat( *this, path_tv ) ); }
84 /** Concatenate and assign. \see cat
87 Pathname & operator+=( const Pathname & path_tv )
88 { return( *this = cat( *this, path_tv ) ); }
90 /** String representation. */
91 const std::string & asString() const
94 /** String representation as "(root)/path" */
95 static std::string showRoot( const Pathname & root_r, const Pathname & path_r );
97 /** String representation as "(root)/path", unless \a root is \c "/" or empty. */
98 static std::string showRootIf( const Pathname & root_r, const Pathname & path_r );
100 /** Url representation using \c scheme_r schema . */
101 Url asUrl( const std::string & scheme_r ) const;
102 /** \overload using \c dir schema. */
104 /** \overload using \c dir schema. */
105 Url asDirUrl() const;
106 /** \overload using \c file schema. */
107 Url asFileUrl() const;
109 /** String representation. */
110 const char * c_str() const
111 { return _name.c_str(); }
113 /** Test for an empty path. */
114 bool empty() const { return _name.empty(); }
115 /** Test for an absolute path. */
116 bool absolute() const { return *_name.c_str() == '/'; }
117 /** Test for a relative path. */
118 bool relative() const { return !( absolute() || empty() ); }
120 /** Test for "" or "/". */
121 bool emptyOrRoot() const { return( _name.empty() || _name == "/" ); }
123 /** Return all but the last component od this path. */
124 Pathname dirname() const { return dirname( *this ); }
125 static Pathname dirname( const Pathname & name_r );
127 /** Return the last component of this path. */
128 std::string basename() const { return basename( *this ); }
129 static std::string basename( const Pathname & name_r );
131 /** Return all of the characters in name after and including
132 * the last dot in the last element of name. If there is no dot
133 * in the last element of name then returns the empty string.
135 std::string extension() const { return extension( *this ); }
136 static std::string extension( const Pathname & name_r );
138 /** Return this path, adding a leading '/' if relative. */
139 Pathname absolutename() const { return absolutename( *this ); }
140 static Pathname absolutename( const Pathname & name_r )
141 { return name_r.relative() ? cat( "/", name_r ) : name_r; }
143 /** Return this path, removing a leading '/' if absolute.*/
144 Pathname relativename() const { return relativename( *this ); }
145 static Pathname relativename( const Pathname & name_r )
146 { return name_r.absolute() ? cat( ".", name_r ) : name_r; }
148 /** Return \c path_r prefixed with \c root_r, unless it is already prefixed. */
149 static Pathname assertprefix( const Pathname & root_r, const Pathname & path_r );
151 /** Return \c path_r with any \c root_r dir prefix striped. */
152 static Pathname stripprefix( const Pathname & root_r, const Pathname & path_r );
154 /** Concatenation of pathnames.
156 * "foo" / "baa" ==> "foo/baa"
157 * "foo/" / "baa" ==> "foo/baa"
158 * "foo" / "/baa" ==> "foo/baa"
159 * "foo/" / "/baa" ==> "foo/baa"
162 Pathname cat( const Pathname & r ) const { return cat( *this, r ); }
163 static Pathname cat( const Pathname & l, const Pathname & r );
165 /** Append string \a r to the last component of the path.
167 * "foo/baa".extend( ".h" ) ==> "foo/baa.h"
170 Pathname extend( const std::string & r ) const { return extend( *this, r ); }
171 static Pathname extend( const Pathname & l, const std::string & r );
175 void _assign( const std::string & name_r );
177 ///////////////////////////////////////////////////////////////////
179 /** \relates Pathname */
180 inline bool operator==( const Pathname & l, const Pathname & r )
181 { return l.asString() == r.asString(); }
183 /** \relates Pathname */
184 inline bool operator!=( const Pathname & l, const Pathname & r )
185 { return l.asString() != r.asString(); }
187 /** \relates Pathname Concatenate two Pathname. */
188 inline Pathname operator/( const Pathname & l, const Pathname & r )
189 { return Pathname::cat( l, r ); }
191 /** \relates Pathname Concatenate two Pathname.
194 inline Pathname operator+( const Pathname & l, const Pathname & r )
195 { return Pathname::cat( l, r ); }
197 /** \relates Pathname */
198 inline bool operator<( const Pathname & l, const Pathname & r )
199 { return l.asString() < r.asString(); }
201 ///////////////////////////////////////////////////////////////////
203 /** \relates Pathname Stream output */
204 inline std::ostream & operator<<( std::ostream & str, const Pathname & obj )
205 { return str << obj.asString(); }
207 /////////////////////////////////////////////////////////////////
208 } // namespace filesystem
209 ///////////////////////////////////////////////////////////////////
211 /** Dragged into namespace zypp. */
212 using filesystem::Pathname;
214 /////////////////////////////////////////////////////////////////
216 ///////////////////////////////////////////////////////////////////
217 #endif // ZYPP_PATHNAME_H