1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Pathname.h
12 #ifndef ZYPP_PATHNAME_H
13 #define ZYPP_PATHNAME_H
18 ///////////////////////////////////////////////////////////////////
20 { /////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////
26 { /////////////////////////////////////////////////////////////////
28 ///////////////////////////////////////////////////////////////////
30 // CLASS NAME : Pathname
34 * \note For convenience Pathname is available as zypp::Pathname too.
36 * Always stores normalized paths (no inner '.' or '..' components
37 * and no consecutive '/'es). Concatenation automatically adds
38 * the path separator '/'.
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.
48 /** Default ctor: an empty path. */
53 /** Ctor from string. */
54 Pathname( const std::string & name_tv )
55 { _assign( name_tv ); }
57 /** Ctor from char*. */
58 Pathname( const char * name_tv )
59 { _assign( name_tv ? name_tv : "" ); }
62 Pathname & operator=( const Pathname & path_tv )
64 prfx_i = path_tv.prfx_i;
65 name_t = path_tv.name_t;
69 /** Concatenate and assing. \see cat */
70 Pathname & operator/=( const Pathname & path_tv )
71 { return( *this = cat( *this, path_tv ) ); }
73 /** Concatenate and assing. \see cat
76 Pathname & operator+=( const Pathname & path_tv )
77 { return( *this = cat( *this, path_tv ) ); }
79 /** String representation. */
80 const std::string & asString() const
83 /** Url representation using \c dir schema. */
86 /** String representation. */
87 const char * c_str() const
88 { return name_t.c_str(); }
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] != '/'; }
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 );
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 );
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.
109 std::string extension() const { return extension( *this ); }
110 static std::string extension( const Pathname & name_tv );
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; }
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; }
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 );
125 /** Concatenation of pathnames.
127 * "foo" / "baa" ==> "foo/baa"
128 * "foo/" / "baa" ==> "foo/baa"
129 * "foo" / "/baa" ==> "foo/baa"
130 * "foo/" / "/baa" ==> "foo/baa"
133 Pathname cat( const Pathname & r ) const { return cat( *this, r ); }
134 static Pathname cat( const Pathname & l, const Pathname & r );
136 /** Append string \a r to the last component of the path.
138 * "foo/baa".extend( ".h" ) ==> "foo/baa.h"
141 Pathname extend( const std::string & r ) const { return extend( *this, r ); }
142 static Pathname extend( const Pathname & l, const std::string & r );
145 std::string::size_type prfx_i;
148 void _assign( const std::string & name_tv );
150 ///////////////////////////////////////////////////////////////////
152 /** \relates Pathname */
153 inline bool operator==( const Pathname & l, const Pathname & r )
154 { return l.asString() == r.asString(); }
156 /** \relates Pathname */
157 inline bool operator!=( const Pathname & l, const Pathname & r )
158 { return l.asString() != r.asString(); }
160 /** \relates Pathname Concatenate two Pathname. */
161 inline Pathname operator/( const Pathname & l, const Pathname & r )
162 { return Pathname::cat( l, r ); }
164 /** \relates Pathname Concatenate two Pathname.
167 inline Pathname operator+( const Pathname & l, const Pathname & r )
168 { return Pathname::cat( l, r ); }
170 /** \relates Pathname */
171 inline bool operator<( const Pathname & l, const Pathname & r )
172 { return l.asString() < r.asString(); }
174 ///////////////////////////////////////////////////////////////////
176 /** \relates Pathname Stream output */
177 inline std::ostream & operator<<( std::ostream & str, const Pathname & obj )
178 { return str << obj.asString(); }
180 /////////////////////////////////////////////////////////////////
181 } // namespace filesystem
182 ///////////////////////////////////////////////////////////////////
184 /** Dragged into namespace zypp. */
185 using filesystem::Pathname;
187 /////////////////////////////////////////////////////////////////
189 ///////////////////////////////////////////////////////////////////
190 #endif // ZYPP_PATHNAME_H