From dcffc1a4d5207bba49fba68b60c6218efc23a600 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Wed, 23 Jun 2021 23:21:01 +0200 Subject: [PATCH] [Base] Remove multiple trailing separators in path --- src/xenia/base/utf8.cc | 59 ++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/src/xenia/base/utf8.cc b/src/xenia/base/utf8.cc index 308117477..3f4775b7a 100644 --- a/src/xenia/base/utf8.cc +++ b/src/xenia/base/utf8.cc @@ -582,43 +582,40 @@ std::string find_name_from_path(const std::string_view path, auto it = end; --it; - // path is padded with separator - size_t padding = 0; - if (*it == uint32_t(separator)) { + // skip trailing separators at the end of the path + while (*it == uint32_t(separator)) { if (it == begin) { + // path is all separators, name is empty return std::string(); } --it; - padding = 1; } - // path is just separator - if (it == begin) { - return std::string(); - } + // update end so it is before any trailing separators + end = std::next(it); - // search for separator - while (it != begin) { - if (*it == uint32_t(separator)) { + // skip non-separators + while (*it != uint32_t(separator)) { + if (it == begin) { break; } --it; } - // no separator -- copy entire string (except trailing separator) - if (it == begin) { - return std::string(path.substr(0, path.size() - padding)); + // if the iterator is on a separator, advance + if (*it == uint32_t(separator)) { + ++it; } - auto length = byte_length(std::next(it), end); - auto offset = path.length() - length; - return std::string(path.substr(offset, length - padding)); + auto offset = byte_length(begin, it); + auto length = byte_length(it, end); + return std::string(path.substr(offset, length)); } std::string find_base_name_from_path(const std::string_view path, char32_t separator) { auto name = find_name_from_path(path, separator); - if (!name.size()) { + if (!name.length()) { return std::string(); } @@ -653,28 +650,34 @@ std::string find_base_path(const std::string_view path, char32_t separator) { auto it = end; --it; - // skip trailing separator - if (*it == uint32_t(separator)) { + // skip trailing separators at the end of the path + while (*it == uint32_t(separator)) { if (it == begin) { return std::string(); } --it; } - while (it != begin) { - if (*it == uint32_t(separator)) { - break; + // skip non-separators + while (*it != uint32_t(separator)) { + if (it == begin) { + // there are no separators, base path is empty + return std::string(); } --it; } - if (it == begin) { - return std::string(); + // skip trailing separators at the end of the base path + while (*it == uint32_t(separator)) { + if (it == begin) { + // base path is all separators, base path is empty + return std::string(); + } + --it; } - auto length = byte_length(it, end); - auto offset = path.length() - length; - return std::string(path.substr(0, offset)); + auto length = byte_length(begin, std::next(it)); + return std::string(path.substr(0, length)); } std::string canonicalize_path(const std::string_view path, char32_t separator) {