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