directory_models_archive_reader.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "directory_models_archive_reader.h"
  2. #include "yarchive.h"
  3. #include <util/folder/dirut.h>
  4. #include <util/folder/filelist.h>
  5. #include <util/folder/path.h>
  6. #include <util/memory/blob.h>
  7. #include <util/stream/file.h>
  8. #include <util/stream/input.h>
  9. #include <util/stream/mem.h>
  10. TDirectoryModelsArchiveReader::TDirectoryModelsArchiveReader(const TString& path, bool lockMemory, bool ownBlobs)
  11. : Path_(path)
  12. {
  13. Y_ENSURE(IsDir(path), "directory not found on this path");
  14. LoadFilesAndSubdirs("", lockMemory, ownBlobs);
  15. }
  16. TDirectoryModelsArchiveReader::~TDirectoryModelsArchiveReader() {}
  17. size_t TDirectoryModelsArchiveReader::Count() const noexcept {
  18. return Recs_.size();
  19. }
  20. TString TDirectoryModelsArchiveReader::KeyByIndex(size_t n) const {
  21. Y_ENSURE(n < Count(), "incorrect index " << n);
  22. return Recs_[n];
  23. }
  24. bool TDirectoryModelsArchiveReader::Has(const TStringBuf key) const {
  25. return BlobByKey_.contains(key) || PathByKey_.contains(key);
  26. }
  27. namespace {
  28. struct TBlobOwningStream : public TMemoryInput {
  29. TBlob Blob;
  30. TBlobOwningStream(TBlob blob)
  31. : TMemoryInput(blob.Data(), blob.Length())
  32. , Blob(blob)
  33. {}
  34. };
  35. }
  36. TAutoPtr<IInputStream> TDirectoryModelsArchiveReader::ObjectByKey(const TStringBuf key) const {
  37. return new TBlobOwningStream(BlobByKey(key));
  38. }
  39. TBlob TDirectoryModelsArchiveReader::ObjectBlobByKey(const TStringBuf key) const {
  40. return BlobByKey(key);
  41. }
  42. TBlob TDirectoryModelsArchiveReader::BlobByKey(const TStringBuf key) const {
  43. Y_ENSURE(Has(key), "key " << key << " not found");
  44. if (auto ptr = BlobByKey_.FindPtr(key); ptr) {
  45. return *ptr;
  46. }
  47. if (auto ptr = PathByKey_.FindPtr(key); ptr) {
  48. return TBlob::FromFile(*ptr);
  49. }
  50. Y_UNREACHABLE();
  51. }
  52. bool TDirectoryModelsArchiveReader::Compressed() const {
  53. return false;
  54. }
  55. TString TDirectoryModelsArchiveReader::NormalizePath(TString path) const {
  56. path = "/" + path;
  57. for (size_t i = 0; i < path.size(); i++) {
  58. if (path[i] == '\\')
  59. path[i] = '/';
  60. }
  61. return path;
  62. }
  63. void TDirectoryModelsArchiveReader::LoadFilesAndSubdirs(const TString& subPath, bool lockMemory, bool ownBlobs) {
  64. TFileList fileList;
  65. fileList.Fill(JoinFsPaths(Path_, subPath));
  66. const char* file;
  67. while ((file = fileList.Next()) != nullptr) {
  68. TString key = JoinFsPaths(subPath, TString(file));
  69. TString fullPath = JoinFsPaths(Path_, key);
  70. TBlob fileBlob;
  71. if (lockMemory) {
  72. fileBlob = TBlob::LockedFromFile(fullPath);
  73. } else {
  74. fileBlob = TBlob::FromFile(fullPath);
  75. }
  76. if (key.EndsWith(".archive")) {
  77. TArchiveReader reader(fileBlob);
  78. for (size_t i = 0, iEnd = reader.Count(); i < iEnd; ++i) {
  79. const TString archiveKey = reader.KeyByIndex(i);
  80. const TString normalizedPath = NormalizePath(JoinFsPaths(subPath, archiveKey.substr(1)));
  81. BlobByKey_.emplace(normalizedPath, reader.ObjectBlobByKey(archiveKey));
  82. Recs_.push_back(normalizedPath);
  83. }
  84. } else {
  85. const TString normalizedPath = NormalizePath(key);
  86. if (lockMemory || ownBlobs) {
  87. BlobByKey_.emplace(normalizedPath, fileBlob);
  88. } else {
  89. PathByKey_.emplace(normalizedPath, RealPath(fullPath));
  90. }
  91. Recs_.push_back(normalizedPath);
  92. }
  93. }
  94. TDirsList dirsList;
  95. dirsList.Fill(JoinFsPaths(Path_, subPath));
  96. const char* dir;
  97. while ((dir = dirsList.Next()) != nullptr) {
  98. LoadFilesAndSubdirs(JoinFsPaths(subPath, TString(dir)), lockMemory, ownBlobs);
  99. }
  100. }