// See boost/filesystem/src/filesystem.cpp #include "filesystem.h" #include #include #include #include #include #include #include #include #include namespace std { namespace filesystem { typedef path::value_type value_type; typedef path::string_type string_type; typedef string_type::size_type size_type; inline size_type find_separator(const value_type* p, size_type size) noexcept { const value_type* sep = static_cast< const value_type* >(std::memchr(p, path::preferred_separator, size)); size_type pos = size; if (!!sep) pos = sep - p; return pos; } path operator/(path lhs, path const& rhs) { return lhs /= rhs; } path current_path() { char buf[path::max_path]; memset(buf, 0, path::max_path); const auto rv = _ksys_getcwd(buf, path::max_path - 1u); return (rv == NULL) ? path{} : path{buf}; } path absolute(path const& p) { if(p.empty() || is_absolute(p)) { return p; } return current_path() / p; } void scan_directory (path const& directory, std::list& paths) { static const auto scopedCloseDir = [](DIR* pdir) { closedir(pdir); }; std::unique_ptr pdir(opendir (directory.c_str()), scopedCloseDir); dirent *pent = NULL; while (pent = readdir (pdir.get())) { if (pent->d_name[0] == path::dot) { continue; } path fileName(directory.c_str()); fileName /= pent->d_name; if (is_directory(fileName)) { scan_directory (fileName, paths); } else if (is_regular_file(fileName)) { paths.emplace_back(std::move(fileName)); } } } // pos is position of the separator bool is_root_separator(string_type const& str, size_type root_dir_pos, size_type pos); // Returns: Size of the filename element that ends at end_pos (which is past-the-end position). 0 if no filename found. size_type find_filename_size(string_type const& str, size_type root_name_size, size_type end_pos); // Returns: starting position of root directory or size if not found. Sets root_name_size to length // of the root name if the characters before the returned position (if any) are considered a root name. size_type find_root_directory_start(const value_type* path, size_type size, size_type& root_name_size); // Finds position and size of the first element of the path void first_element(string_type const& src, size_type& element_pos, size_type& element_size, size_type size); // Finds position and size of the first element of the path inline void first_element(string_type const& src, size_type& element_pos, size_type& element_size) { first_element(src, element_pos, element_size, src.size()); } // Checks if the second string overlaps in memory with the first string inline bool is_overlapping(string_type const& str, const value_type* arg) { std::less< const value_type* > ptr_less{}; return !(ptr_less(arg, str.data()) || ptr_less(str.data() + str.size(), arg)); } inline size_type find_filename_size(string_type const& str, size_type root_name_size, size_type end_pos) { size_type pos = end_pos; while (pos > root_name_size) { --pos; if (path::is_directory_separator(str[pos])) { ++pos; // filename starts past the separator break; } } return end_pos - pos; } } // namespace filesystem } // namespace std