From fc91e7cbdd4e37702a28eef58b100e2b6a9c3f1b Mon Sep 17 00:00:00 2001 From: Bruno Date: Wed, 28 Jul 2021 19:03:38 +0200 Subject: [PATCH] Draft Function path_relative_to_path --- SystemToolkit.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++++++ SystemToolkit.h | 2 ++ 2 files changed, 84 insertions(+) diff --git a/SystemToolkit.cpp b/SystemToolkit.cpp index c021f5c..16be2ac 100644 --- a/SystemToolkit.cpp +++ b/SystemToolkit.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace std; @@ -333,3 +334,84 @@ void SystemToolkit::execute(const string& command) // std::thread (SystemToolkit::execute, // "gst-launch-1.0 udpsrc port=5000 ! application/x-rtp,encoding-name=JPEG,payload=26 ! rtpjpegdepay ! jpegdec ! autovideosink").detach();; + + +bool StringEQ( const std::string& a, const std::string& b ) +{ + if ( a.size() != b.size() ) + return false; + return ( strcmp( a.c_str(), b.c_str() ) == 0 ); +} + +// 7.3: http://www.oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html +// +void Tokenize(const string& str, vector& tokens, const string& delimiters) +{ + // Skip delimiters at beginning. + string::size_type lastPos = str.find_first_not_of(delimiters, 0); + // Find first "non-delimiter". + string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (string::npos != pos || string::npos != lastPos) + { + // Found a token, add it to the vector. + tokens.push_back(str.substr(lastPos, pos - lastPos)); + // Skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + // Find next "non-delimiter" + pos = str.find_first_of(delimiters, lastPos); + } +} + +// +// "c:\a\b\c" + "c:\a\x\file.txt" => "..\..\x\file.txt" +// http://mrpmorris.blogspot.com/2007/05/convert-absolute-path-to-relative-path.html +// +string SystemToolkit::path_relative_to_path( const string& absolutePath, const string& relativeTo ) +{ + vector< string > absoluteDirectories; + vector< string > relativeDirectories; + Tokenize( absolutePath, absoluteDirectories, "/" ); + Tokenize( relativeTo, relativeDirectories, "/" ); + + // Get the shortest of the two paths + size_t length = absoluteDirectories.size() < relativeDirectories.size() ? absoluteDirectories.size() : relativeDirectories.size(); + + // Use to determine where in the loop we exited + int lastCommonRoot = -1; + size_t index; + + // Find common root + for (index = 0; index < length; ++index) { + if (StringEQ( absoluteDirectories[index], relativeDirectories[index])) + lastCommonRoot = index; + else + break; + } + + // If we didn't find a common prefix then throw + if (lastCommonRoot == -1) + { + assert( 0 ); // "Paths do not have a common base" + return ""; + } + + string relativePath; + + // Add on the .. + for (index = lastCommonRoot + 1; index < relativeDirectories.size(); ++index) { + if (relativeDirectories[index].size() > 0) + relativePath += "../"; + } + + // Add on the folders + for (index = lastCommonRoot + 1; index < absoluteDirectories.size() - 1; ++index) + { + relativePath += absoluteDirectories[index]; + relativePath += "/"; + } + + relativePath += absoluteDirectories[absoluteDirectories.size() - 1]; + + return relativePath; +} diff --git a/SystemToolkit.h b/SystemToolkit.h index 1b6f08e..bc6db6f 100644 --- a/SystemToolkit.h +++ b/SystemToolkit.h @@ -51,6 +51,8 @@ namespace SystemToolkit // list all files of a directory mathing the given filter extension (if any) std::list list_directory(const std::string& path, const std::list &extensions); + std::string path_relative_to_path(const std::string& absolutePath, const std::string& relativeTo); + // true of file exists bool file_exists(const std::string& path);