From 20b9217cd8e034d7f567183fe2bcb35bfa84dc98 Mon Sep 17 00:00:00 2001 From: Thomas Fussell Date: Wed, 10 Aug 2016 00:09:54 -1000 Subject: [PATCH] encapsulate URIs with a class and improve path interface --- include/xlnt/packaging/relationship.hpp | 13 +- include/xlnt/packaging/uri.hpp | 81 ++++++++++++ include/xlnt/utils/path.hpp | 156 +++++++----------------- 3 files changed, 138 insertions(+), 112 deletions(-) create mode 100644 include/xlnt/packaging/uri.hpp diff --git a/include/xlnt/packaging/relationship.hpp b/include/xlnt/packaging/relationship.hpp index 05c88e08..be186300 100644 --- a/include/xlnt/packaging/relationship.hpp +++ b/include/xlnt/packaging/relationship.hpp @@ -26,6 +26,7 @@ #include #include +#include #include namespace xlnt { @@ -102,7 +103,7 @@ public: relationship(); - relationship(const std::string &id, type t, const path &target, target_mode mode); + relationship(const std::string &id, type t, const uri &source, const uri &target, target_mode mode); /// /// Returns a string of the form rId# that identifies the relationship. @@ -122,7 +123,12 @@ public: /// /// Returns the URI of the package part this relationship points to. /// - path get_target_uri() const; + uri get_source() const; + + /// + /// Returns the URI of the package part this relationship points to. + /// + uri get_target() const; /// /// Returns true if and only if rhs is equal to this relationship. @@ -137,7 +143,8 @@ public: private: std::string id_; type type_; - path target_uri_; + uri source_; + uri target_; target_mode target_mode_; }; diff --git a/include/xlnt/packaging/uri.hpp b/include/xlnt/packaging/uri.hpp new file mode 100644 index 00000000..4c5488f1 --- /dev/null +++ b/include/xlnt/packaging/uri.hpp @@ -0,0 +1,81 @@ +// 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 +#pragma once + +#include + +#include + +namespace xlnt { + +/// +/// +/// +class XLNT_CLASS uri +{ +public: + uri(); + uri(const uri &base, const uri &relative); + uri(const uri &base, const path &relative); + uri(const std::string &uri_string); + + bool is_relative() const; + bool is_absolute() const; + + std::string get_scheme() const; + std::string get_authority() const; + bool has_authentication() const; + std::string get_authentication() const; + std::string get_username() const; + std::string get_password() const; + std::string get_host() const; + bool has_port() const; + std::size_t get_port() const; + path get_path() const; + bool has_query() const; + std::string get_query() const; + bool has_fragment() const; + std::string get_fragment() const; + + std::string to_string() const; + + uri make_absolute(const uri &base); + uri make_reference(const uri &base); + +private: + bool absolute_; + std::string scheme_; + bool has_authentication_; + std::string username_; + std::string password_; + std::string host_; + bool has_port_; + std::size_t port_; + bool has_query_; + std::string query_; + bool has_fragment_; + std::string fragment_; + path path_; +}; + +} // namespace xlnt diff --git a/include/xlnt/utils/path.hpp b/include/xlnt/utils/path.hpp index 57f924bc..67b448b3 100644 --- a/include/xlnt/utils/path.hpp +++ b/include/xlnt/utils/path.hpp @@ -33,37 +33,13 @@ namespace xlnt { /// /// Encapsulates a path that points to location in a filesystem. /// -class XLNT_CLASS path : public hashable +class XLNT_CLASS path { public: - /// - /// The parts of this path are held in a container of this type. - /// - using container = std::vector; - - /// - /// Expose the container's iterator as the iterator for this class. - /// - using iterator = container::iterator; - /// - /// Expose the container's const_iterator as the const_iterator for this class. - /// - using const_iterator = container::const_iterator; - - /// - /// Expose the container's reverse_iterator as the reverse_iterator for this class. - /// - using reverse_iterator = container::reverse_iterator; - - /// - /// Expose the container's const_reverse_iterator as the const_reverse_iterator for this class. - /// - using const_reverse_iterator = container::const_reverse_iterator; - /// /// The system-specific path separator character (e.g. '/' or '\'). /// - static char separator(); + static char system_separator(); /// /// Construct an empty path. @@ -93,7 +69,7 @@ public: bool is_absolute() const; /// - /// Return true iff this path is the root of the host's filesystem. + /// Return true iff this path is the root directory. /// bool is_root() const; @@ -106,27 +82,38 @@ public: /// /// Return the last component of this path. /// - std::string basename() const; + std::string filename() const; /// - /// Return the part of the path following the last . in the basename. + /// Return the part of the path following the last dot in the filename. /// std::string extension() const; + /// + /// Return a pair of strings resulting from splitting the filename on the last dot. + /// + std::pair split_extension() const; + // conversion /// /// Create a string representing this path separated by the provided /// separator or the system-default separator if not provided. /// - std::string to_string(char sep = separator()) const; + std::vector split() const; + + /// + /// Create a string representing this path separated by the provided + /// separator or the system-default separator if not provided. + /// + std::string string() const; /// /// If this path is relative, append each component of this path /// to base_path and return the resulting absolute path. Otherwise, /// the the current path will be returned and base_path will be ignored. /// - path make_absolute(const path &base_path) const; + path resolve(const path &base_path) const; // filesystem attributes @@ -158,95 +145,46 @@ public: // mutators - /// - /// Append the provided part to this path and return a reference to this same path - /// so calls can be chained. - /// - path &append(const std::string &to_append); - /// /// Append the provided part to this path and return the result. /// path append(const std::string &to_append) const; - /// - /// Append the provided part to this path and return a reference to this same path - /// so calls can be chained. - /// - path &append(const path &to_append); - /// /// Append the provided part to this path and return the result. /// path append(const path &to_append) const; - // iterators - - /// - /// An iterator to the first element in this path. - /// - iterator begin(); - - /// - /// An iterator to one past the last element in this path. - /// - iterator end(); - - /// - /// An iterator to the first element in this path. - /// - const_iterator begin() const; - - /// - /// A const iterator to one past the last element in this path. - /// - const_iterator end() const; - - /// - /// An iterator to the first element in this path. - /// - const_iterator cbegin() const; - - /// - /// A const iterator to one past the last element in this path. - /// - const_iterator cend() const; - - /// - /// A reverse iterator to the last element in this path. - /// - reverse_iterator rbegin(); - - /// - /// A reverse iterator to one before the first element in this path. - /// - reverse_iterator rend(); - - /// - /// A const reverse iterator to the last element in this path. - /// - const_reverse_iterator rbegin() const; - - /// - /// A const reverse iterator to one before the first element in this path. - /// - const_reverse_iterator rend() const; - - /// - /// A const reverse iterator to the last element in this path. - /// - const_reverse_iterator crbegin() const; - - /// - /// A const reverse iterator to one before the first element in this path. - /// - const_reverse_iterator crend() const; - -protected: - std::string to_hash_string() const override; - private: - container parts_; + /// + /// Returns the character that separates directories in the path. + /// On POSIX style filesystems, this is always '/'. + /// On Windows, this is the character that separates the drive letter from + /// the rest of the path for absolute paths with a drive letter, '/' if the path + /// is absolute and starts with '/', and '/' or '\' for relative paths + /// depending on which splits the path into more directory components. + /// + char guess_separator() const; + + /// + /// A string that represents this path. + /// + std::string internal_; }; } // namespace xlnt + +namespace std { + +template <> +struct hash +{ + size_t operator()(const path &p) const + { + return hasher(p); + } + + hash hasher; +}; + +} // namespace std