#pragma once #include #include #include #include #include #include #include #include "path.h" namespace cppfs { path path::current() { char buf[PATH_MAX + 1]; if (!getcwd(&buf[0], sizeof(buf)-1)) throw cppcore::error_exception(errno); return path(&buf[0]); } path::path(const std::string& p_path) : _status (path_status::none) , _path (p_path) , _parts () { if (!_path.empty()) { if (_path[0] == '.') { _status = path_status::relative; } else if (_path[0] == '/' || _path[0] == '\\') { _status = path_status::absoulte; } } bool ok = cppcore::string_split( _path, [](char c) { return c == '\\' || c == '/'; }, [this](auto&& s){ if (_parts.empty() && s.empty()) return true; if (s != ".") _parts.emplace_back(std::move(s)); return true; }); if (!ok) throw cppcore::exception("Error while splitting path into parts"); } file_type path::type() const { struct stat st; auto& s = str(); if (stat(s.c_str(), &st)) return file_type::unknown; switch (st.st_mode & S_IFMT) { case S_IFSOCK: return file_type::socket; case S_IFLNK: return file_type::symbolic_link; case S_IFREG: return file_type::file; case S_IFBLK: return file_type::block_device; case S_IFDIR: return file_type::directory; case S_IFCHR: return file_type::char_device; case S_IFIFO: return file_type::named_pipe; default: return file_type::unknown; } } std::string path::make_path() const { std::ostringstream ss; switch (_status) { case path_status::none: break; case path_status::absoulte: ss << constants::path_delimiter; break; case path_status::relative: ss << '.' << constants::path_delimiter; break; } bool first = true; for (auto& part : _parts) { if (first) first = false; else ss << constants::path_delimiter; ss << part; } return ss.str(); } }