// Copyright (c) 2014-2016 Thomas Fussell // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE // // @license: http://www.opensource.org/licenses/mit-license.php // @author: see AUTHORS file #include #include #include #ifdef __APPLE__ #include #elif defined(__linux) #include #include #include #endif #include #include namespace { #ifdef _MSC_VER char system_separator() { return '\\'; } bool is_root(const std::string &part) { return part == "/" || (part.size() == 2 && part.back() == ':' && part.front() >= 'A' && part.front() <= 'Z'); } #else char system_separator() { return '/'; } bool is_root(const std::string &part) { return part == "/"; } #endif std::vector split_path(const std::string &path, char delim) { std::vector split; std::string::size_type previous_index = 0; auto separator_index = path.find(delim); while (separator_index != std::string::npos) { auto part = path.substr(previous_index, separator_index - previous_index); split.push_back(part); previous_index = separator_index + 1; separator_index = path.find(delim, previous_index); } // Don't add trailing slash if (previous_index < path.size()) { split.push_back(path.substr(previous_index)); } return split; } bool file_exists(const std::string &path) { struct stat info; return stat(path.c_str(), &info) == 0 && (info.st_mode & S_IFREG); } bool directory_exists(const std::string path) { struct stat info; return stat(path.c_str(), &info) == 0 && (info.st_mode & S_IFDIR); } } // namespace namespace xlnt { char path::system_separator() { return ::system_separator(); } path::path() { } path::path(const std::string &path_string) : internal_(path_string) { } // general attributes bool path::is_relative() const { return !is_absolute(); } bool path::is_absolute() const { auto split_path = split(); return !split_path.empty() && ::is_root(split_path.front()); } bool path::is_root() const { return ::is_root(internal_); } path path::parent() const { if (is_root()) return *this; auto split_path = split(); split_path.pop_back(); if (split_path.empty()) { return path(""); } path result; for (const auto &component : split_path) { result = result.append(component); } return result; } std::string path::filename() const { auto split_path = split(); return split_path.empty() ? "" : split_path.back(); } std::string path::extension() const { auto base = filename(); auto last_dot = base.find_last_of('.'); return last_dot == std::string::npos ? "" : base.substr(last_dot + 1); } // conversion std::string path::string() const { return internal_; } std::vector path::split() const { return split_path(internal_, guess_separator()); } path path::resolve(const path &base_path) const { if (is_absolute()) { return *this; } path copy(base_path.internal_); for (const auto &part : split()) { copy = copy.append(part); } return copy; } // filesystem attributes bool path::exists() const { return is_file() || is_directory(); } bool path::is_directory() const { return directory_exists(string()); } bool path::is_file() const { return file_exists(string()); } // filesystem std::string path::read_contents() const { std::ifstream f(string()); std::ostringstream ss; ss << f.rdbuf(); return ss.str(); } // append path path::append(const std::string &to_append) const { path copy(internal_); if (!internal_.empty() && internal_.back() != guess_separator()) { copy.internal_.push_back(guess_separator()); } copy.internal_.append(to_append); return copy; } path path::append(const path &to_append) const { return append(to_append.string()); } char path::guess_separator() const { if (system_separator() == '/') return '/'; if (is_absolute()) return internal_.at(2); return internal_.find('/') == std::string::npos ? '/' : '\\'; } bool operator==(const path &left, const path &right) { return left.internal_ == right.internal_; } } // namespace xlnt