Engine.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include "pch.h"
  2. #include "IEngine.h"
  3. #include "Crypto.h"
  4. #include <stdexcept>
  5. #include <filesystem>
  6. using namespace craftlab::fakeraid;
  7. namespace craftlab::fakeraid
  8. {
  9. class Engine : public IEngine
  10. {
  11. public:
  12. Engine(const std::vector<std::string>& path);
  13. void DirExistsOrThrow() const override;
  14. std::vector<std::string> GetRootPaths() const override;
  15. std::vector<std::string> GetPaths() const override;
  16. std::deque<std::string> GetCurrentDir() const override;
  17. FileAndSumListByRepositoryIndex ListFiles() override;
  18. void Cd(const std::string& dirName) override;
  19. private:
  20. FileAndSumList ListFiles(const std::string& root, int repositoryIndex);
  21. std::string BuildCurrentDirPath(const std::string& root ="") const;
  22. const std::vector<std::string> rootPaths;
  23. std::deque<std::string> currentDir;
  24. };
  25. }
  26. Engine::Engine(const std::vector<std::string>& path): rootPaths(path), currentDir()
  27. {}
  28. std::vector<std::string> Engine::GetRootPaths() const
  29. {
  30. return rootPaths;
  31. }
  32. std::vector<std::string> Engine::GetPaths() const
  33. {
  34. std::vector<std::string> paths;
  35. const std::string workingDir = BuildCurrentDirPath();
  36. std::transform(rootPaths.begin(), rootPaths.end(), std::back_inserter(paths), [&workingDir](const std::string& val) { return val + "/" + workingDir; });
  37. return paths;
  38. }
  39. std::deque<std::string> Engine::GetCurrentDir() const
  40. {
  41. return currentDir;
  42. }
  43. std::string Engine::BuildCurrentDirPath(const std::string& root) const
  44. {
  45. std::stringstream ss;
  46. ss << root;
  47. bool written = !root.empty();
  48. for (const std::string& path : currentDir)
  49. {
  50. if (written)
  51. ss << "/";
  52. ss << path;
  53. written = true;
  54. }
  55. return ss.str();
  56. }
  57. void Engine::Cd(const std::string& dirName)
  58. {
  59. currentDir.push_back(dirName);
  60. }
  61. FileAndSumList Engine::ListFiles(const std::string& root, int repositoryIndex)
  62. {
  63. FileAndSumList result;
  64. const std::string path = BuildCurrentDirPath(root);
  65. Crypto cryptoEngine;
  66. for (const std::filesystem::directory_entry& file : std::filesystem::directory_iterator(path))
  67. {
  68. if (file.is_directory() || file.is_regular_file())
  69. {
  70. FileAndSum fileInfos;
  71. fileInfos.fileName = file.path().filename().string();
  72. fileInfos.isDir = file.is_directory();
  73. fileInfos.repositoryIndex = repositoryIndex;
  74. try
  75. {
  76. cryptoEngine.Compute(path, fileInfos);
  77. }
  78. catch (std::runtime_error&)
  79. {}
  80. result.push_back(fileInfos);
  81. }
  82. }
  83. return result;
  84. }
  85. FileAndSumListByRepositoryIndex Engine::ListFiles()
  86. {
  87. FileAndSumListByRepositoryIndex result;
  88. int index = 0;
  89. for (const auto& i : rootPaths)
  90. {
  91. const FileAndSumList files = ListFiles(i, index++);
  92. result.FileAndSumListByRepositoryIndex.push_back(files);
  93. for (const FileAndSum& file : files)
  94. result.FileList[file.fileName] = file;
  95. }
  96. return result;
  97. }
  98. void Engine::DirExistsOrThrow() const
  99. {
  100. char errorBuffer[1024];
  101. for (const std::string& fullPath : GetPaths())
  102. {
  103. struct stat fileInfo;
  104. if (stat(fullPath.c_str(), &fileInfo))
  105. {
  106. strerror_s(errorBuffer, errno);
  107. throw std::runtime_error("cannot access " + fullPath + ": " + errorBuffer);
  108. }
  109. if (!(fileInfo.st_mode & S_IFDIR))
  110. {
  111. strerror_s(errorBuffer, ENOTDIR);
  112. throw std::runtime_error("cannot access " + fullPath + ": " + errorBuffer);
  113. }
  114. }
  115. }
  116. IEngine* EngineManager::Open(const std::vector<std::string>& path)
  117. {
  118. return new Engine(path);
  119. }