diff options
Diffstat (limited to 'Source/cmFilePathChecksum.cxx')
-rw-r--r-- | Source/cmFilePathChecksum.cxx | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/Source/cmFilePathChecksum.cxx b/Source/cmFilePathChecksum.cxx new file mode 100644 index 0000000..47a223a --- /dev/null +++ b/Source/cmFilePathChecksum.cxx @@ -0,0 +1,85 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFilePathChecksum.h" + +#include "cmBase32.h" +#include "cmCryptoHash.h" +#include "cmMakefile.h" +#include "cmSystemTools.h" + +#include <vector> + +cmFilePathChecksum::cmFilePathChecksum() = default; + +cmFilePathChecksum::cmFilePathChecksum(std::string const& currentSrcDir, + std::string const& currentBinDir, + std::string const& projectSrcDir, + std::string const& projectBinDir) +{ + setupParentDirs(currentSrcDir, currentBinDir, projectSrcDir, projectBinDir); +} + +cmFilePathChecksum::cmFilePathChecksum(cmMakefile* makefile) +{ + setupParentDirs(makefile->GetCurrentSourceDirectory(), + makefile->GetCurrentBinaryDirectory(), + makefile->GetHomeDirectory(), + makefile->GetHomeOutputDirectory()); +} + +void cmFilePathChecksum::setupParentDirs(std::string const& currentSrcDir, + std::string const& currentBinDir, + std::string const& projectSrcDir, + std::string const& projectBinDir) +{ + this->parentDirs[0].first = cmSystemTools::GetRealPath(currentSrcDir); + this->parentDirs[1].first = cmSystemTools::GetRealPath(currentBinDir); + this->parentDirs[2].first = cmSystemTools::GetRealPath(projectSrcDir); + this->parentDirs[3].first = cmSystemTools::GetRealPath(projectBinDir); + + this->parentDirs[0].second = "CurrentSource"; + this->parentDirs[1].second = "CurrentBinary"; + this->parentDirs[2].second = "ProjectSource"; + this->parentDirs[3].second = "ProjectBinary"; +} + +std::string cmFilePathChecksum::get(std::string const& filePath) const +{ + std::string relPath; + std::string relSeed; + { + std::string const fileReal = cmSystemTools::GetRealPath(filePath); + std::string parentDir; + // Find closest project parent directory + for (auto const& pDir : this->parentDirs) { + if (!pDir.first.empty() && + cmsys::SystemTools::IsSubDirectory(fileReal, pDir.first)) { + parentDir = pDir.first; + relSeed = pDir.second; + break; + } + } + // Use file system root as fallback parent directory + if (parentDir.empty()) { + relSeed = "FileSystemRoot"; + cmsys::SystemTools::SplitPathRootComponent(fileReal, &parentDir); + } + // Calculate relative path from project parent directory + relPath = cmsys::SystemTools::RelativePath( + parentDir, cmsys::SystemTools::GetParentDirectory(fileReal)); + } + + // Calculate the file ( seed + relative path ) binary checksum + std::vector<unsigned char> hashBytes = + cmCryptoHash(cmCryptoHash::AlgoSHA256).ByteHashString(relSeed + relPath); + + // Convert binary checksum to string + return cmBase32Encoder().encodeString(hashBytes.data(), hashBytes.size(), + false); +} + +std::string cmFilePathChecksum::getPart(std::string const& filePath, + size_t length) const +{ + return get(filePath).substr(0, length); +} |