1 // boost/filesystem/path.hpp -----------------------------------------------//
3 // (C) Copyright Beman Dawes 2002. Permission to copy, use, modify, sell and
4 // distribute this software is granted provided this copyright notice appears
5 // in all copies. This software is provided "as is" without express or implied
6 // warranty, and with no claim as to its suitability for any purpose.
9 // See http://www.boost.org/libs/filesystem for documentation.
11 //----------------------------------------------------------------------------//
13 #ifndef BOOST_FILESYSTEM_PATH_HPP
14 #define BOOST_FILESYSTEM_PATH_HPP
16 #include <boost/iterator_adaptors.hpp>
20 //----------------------------------------------------------------------------//
32 std::string name; // cache current element.
33 const path * path_ptr; // path being iterated over.
34 std::string::size_type pos; // position of name in
35 // path_ptr->string(). The
36 // end() iterator is indicated by
37 // pos == path_ptr->string().size()
39 const std::string & operator*() const { return name; }
42 bool operator==( const path_itr_imp & rhs ) const
43 { return path_ptr == rhs.path_ptr && pos == rhs.pos; }
47 enum path_format { native }; // ugly enough to discourage use
48 // except when actually needed
50 // path -------------------------------------------------------------------//
55 // compiler generates copy constructor, copy assignment, and destructor
59 path( const std::string & src );
60 path( const char * src );
62 path( const std::string & src, path_format );
63 path( const char * src, path_format );
66 path & operator /=( const path & rhs );
67 path operator /( const path & rhs ) const
68 { return path( *this ) /= rhs; }
70 // conversion functions:
71 const std::string & string() const { return m_path; }
72 std::string native_file_string() const;
73 std::string native_directory_string() const;
75 // decomposition functions:
76 path root_path() const;
77 std::string root_name() const;
78 std::string root_directory() const;
79 path relative_path() const;
80 std::string leaf() const;
81 path branch_path() const;
84 bool empty() const { return m_path.empty(); } // name consistent with std containers
86 bool is_complete() const;
88 bool has_root_path() const;
89 bool has_root_name() const;
90 bool has_root_directory() const;
91 bool has_relative_path() const;
92 bool has_leaf() const { return !m_path.empty(); }
93 bool has_branch_path() const;
95 // iteration over the names in the path:
96 typedef boost::iterator_adaptor<
98 boost::default_iterator_policies,
102 std::bidirectional_iterator_tag,
106 iterator begin() const;
110 itr.base().path_ptr = this;
111 itr.base().pos = m_path.size();
116 // Note: This is an implementation for POSIX and Windows, where there
117 // are only minor differences between generic and system-specific
118 // constructor input formats. Private members might be quite different
119 // in other implementations, particularly where there were wide
120 // differences between generic and system-specific argument formats,
121 // or between native_file_string() and native_directory_string() formats.
125 friend class directory_iterator;
126 friend struct boost::filesystem::detail::path_itr_imp;
128 enum source_context { generic, platform, nocheck };
130 void m_path_append( const std::string & src,
131 source_context context = generic );
133 public: // should be private, but friend functions don't work for me
134 void m_replace_leaf( const char * new_leaf );
137 // path non-member functions ---------------------------------------------//
139 inline path operator / ( const char * lhs, const path & rhs )
140 { return path( lhs ) /= rhs; }
142 inline path operator / ( const std::string & lhs, const path & rhs )
143 { return path( lhs ) /= rhs; }
145 // error checking --------------------------------------------------------//
147 // TODO: write a program that probes valid file and directory names. Ask
148 // Boost people to report results from many operating systems. Use results
149 // to adjust generic_name().
151 // generic_name() is extremely permissive; its intent is not to ensure
152 // general portablity, but rather to detect names so trouble-prone that
153 // they likely represent coding errors or gross misconceptions.
155 // Any characters are allowed except:
157 // Those characters < ' ', including '\0'. These are the so-called
158 // control characters, in both ASCII (and its decendents) and EBCDIC.
159 // Hard to imagine how these could be useful in a generic path name.
161 // < > : " / \ | * ? These have special meaning to enough operating
162 // systems that use in a generic name would be a serious problem.
164 // The names "." and ".." are not allowed.
165 // An empty name (null string) is not allowed.
166 // Names beginning or ending with spaces are not allowed.
168 bool generic_name( const std::string & name );
170 // posix_name() is based on POSIX (IEEE Std 1003.1-2001)
171 // "Portable Filename Character Set" rules.
172 // http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap03.html
174 // That character set only allows 0-9, a-z, A-Z, '.', '_', and '-'.
175 // Note that such names are also portable to other popular operating
176 // systems, such as Windows.
178 bool posix_name( const std::string & name );
180 const path & check_posix_leaf( const path & ph );
181 // Throws: if !posix_name( ph.leaf() )
183 // Note: Although useful in its own right, check_posix_leaf() also serves
184 // as an example. A user might provide similar functions; behavior might
185 // be to assert or warn rather than throw. A user provided function
186 // could also check the entire path instead of just the leaf; a leaf
187 // check is often, but not always, the required behavior.
188 // Rationale: For the "const path &" rather than "void" return is to
189 // allow (and encourage portability checking) uses like:
190 // create_directory( check_posix_leaf( "foo" ) );
191 // While there is some chance of misuse (by passing through a reference
192 // to a temporary), the benefits outweigh the costs.
194 // For Boost, we often tighten name restrictions for maximum portability:
196 // * The portable POSIX character restrictions, plus
197 // * Maximum name length 31 characters (for Classic Mac OS).
198 // * Lowercase only (so code written on case-insensitive platforms like
199 // Windows works properly when used on case-sensitive systems like
201 // * Directory names do not contain '.', as this is not a valid character
202 // for directory names on some systems.
204 // TODO: provide some check_boost_xxx functions once error handling
205 // approach ratified.
207 bool boost_file_name( const std::string & name );
208 bool boost_directory_name( const std::string & name );
210 } // namespace filesystem
213 #endif // BOOST_FILESYSTEM_PATH_HPP