From 43afbab09ed6e2e4f1b458e9ac409c98a1a6ba17 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 21 Jan 2011 11:46:15 +0000 Subject: [PATCH] From Sukender, getPathRelative() method. --- include/osgDB/FileNameUtils | 5 +++++ src/osgDB/FileNameUtils.cpp | 43 +++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/include/osgDB/FileNameUtils b/include/osgDB/FileNameUtils index 70be87fea..1c931d36b 100644 --- a/include/osgDB/FileNameUtils +++ b/include/osgDB/FileNameUtils @@ -36,6 +36,11 @@ extern OSGDB_EXPORT std::string getNameLessExtension(const std::string& fileName extern OSGDB_EXPORT std::string getNameLessAllExtensions(const std::string& fileName); /** Gets file name without last extension (Ex: /a/b/c.Ext => c ; file.ext1.ext2 => file.ext1). */ extern OSGDB_EXPORT std::string getStrippedName(const std::string& fileName); +/** If 'to' is in a subdirectory of 'from' then this function returns the subpath, otherwise it just returns the file name. + * The function does \b not automagically resolve paths as the system does, so be careful to give canonical paths. + * However, the function interprets slashes ('/') ans backslashes ('\') as they were equal. + */ +extern OSGDB_EXPORT std::string getPathRelative(const std::string& from, const std::string& to); /** Converts forward slashes (/) to back slashes (\). */ diff --git a/src/osgDB/FileNameUtils.cpp b/src/osgDB/FileNameUtils.cpp index 2b2cd1663..3bdd411e2 100644 --- a/src/osgDB/FileNameUtils.cpp +++ b/src/osgDB/FileNameUtils.cpp @@ -320,3 +320,46 @@ std::string osgDB::getRealPath(const std::string& path) else return path; #endif } + +std::string osgDB::getPathRelative(const std::string& from, const std::string& to) +{ + std::string::size_type slash = to.find_last_of('/'); + std::string::size_type backslash = to.find_last_of('\\'); + if (slash == std::string::npos) + { + if (backslash == std::string::npos) return to; + slash = backslash; + } + else if (backslash != std::string::npos && backslash > slash) + { + slash = backslash; + } + + if (from.empty() || from.length() > to.length()) + return osgDB::getSimpleFileName(to); + + std::string::const_iterator itTo = to.begin(); + for (std::string::const_iterator itFrom = from.begin(); + itFrom != from.end(); ++itFrom, ++itTo) + { + char a = tolower(*itFrom), b = tolower(*itTo); + if (a == '\\') a = '/'; + if (b == '\\') b = '/'; + if (a != b || itTo == to.begin() + slash + 1) + { + return osgDB::getSimpleFileName(to); + } + } + + while (itTo != to.end() && (*itTo == '\\' || *itTo == '/')) + { + ++itTo; + } + + return std::string(itTo, to.end()); +} + +//std::string testA = getPathRelative("C:\\a\\b", "C:\\a/b/d/f"); +//std::string testB = getPathRelative("C:\\a\\d", "C:\\a/b/d/f"); +//std::string testC = getPathRelative("C:\\ab", "C:\\a/b/d/f"); +//std::string testD = getPathRelative("a/d", "a/d");