DatBackupManager.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //
  2. // Created by kikab on 04.06.2018.
  3. //
  4. #include <DatFile.h>
  5. #include <DatSubsystems/DatBackupManager.h>
  6. #include "DatSubsystems/DatBackupManager.h"
  7. #include "EasyLogging++/easylogging++.h"
  8. namespace LOTRO_DAT {
  9. DatBackupManager::DatBackupManager(DatFile *datFilePtr) {}
  10. /*!
  11. * \author Gi1dor
  12. * \date 11.07.2018
  13. * Проверка доступности и корректности бэкапа dat файла
  14. * \param[in] backup_datname путь к файлу бэкапа
  15. * \returns true - если файл доступен для чтения его структура корректна. Иначе false
  16. */
  17. bool DatBackupManager::CheckIfBackupAvailable(const std::string &backup_datname) {
  18. DatFile file;
  19. return file.Initialise(backup_datname, 0).result == SUCCESS && file.Initialized();
  20. }
  21. /*!
  22. * \author Gi1dor
  23. * \date 11.07.2018
  24. * Создание резервной копии инициализированного Dat файла.
  25. *
  26. * \param[in] backup_datname путь к файлу создаваемого бэкапа
  27. */
  28. DatOperationResult<> DatBackupManager::CreateBackup(const std::string &backup_datname) {
  29. FILE* file = fopen(backup_datname.c_str(), "w+b");
  30. if (!file)
  31. return DatOperationResult<>(ERROR, "CREATEBACKUP: cannot open file " + backup_datname);
  32. auto operation = CopyDatFile(*dat, file);
  33. fclose(file);
  34. if (operation.result != SUCCESS)
  35. return DatOperationResult<>(ERROR, "CREATEBACKUP: Error in copy dat file");
  36. return DatOperationResult<>(SUCCESS);
  37. }
  38. /*!
  39. * \author Gi1dor
  40. * \date 11.07.2018
  41. * Восстановление dat файла из резервной копии. Если восстановление не удалось, DatFile будет деинициализирован.
  42. * \param[in] backup_datname путь к файлу резервной копии
  43. */
  44. DatOperationResult<> DatBackupManager::RestoreFromBackup(const std::string &backup_datname) {
  45. if (!CheckIfBackupAvailable(backup_datname))
  46. return DatOperationResult<>(ERROR, "RESTOREFROMBACKUP: incorrect backup file " + backup_datname);
  47. DatFile backup_file;
  48. backup_file.Initialise(backup_datname, 0);
  49. std::string dat_filename = dat->GetIO().GetFilename().value;
  50. dat->Deinitialize();
  51. FILE* file = fopen(backup_datname.c_str(), "w+b");
  52. if (!file)
  53. return DatOperationResult<>(ERROR, "RESTOREFROMBACKUP: cannot open file " + backup_datname);
  54. auto operation = CopyDatFile(backup_file, file);
  55. fclose(file);
  56. if (operation.result == ERROR)
  57. return DatOperationResult<>(ERROR, "RESTOREFROMBACKUP: error in copy dat file");
  58. dat->Initialise(dat_filename, dat->GetDatID());
  59. return DatOperationResult<>(SUCCESS);
  60. }
  61. /*!
  62. * \author Gi1dor
  63. * \date 11.07.2018
  64. * Удаление резервной копии.
  65. * \param[in] backup_datname путь к файлу резервной копии
  66. */
  67. DatOperationResult<> DatBackupManager::RemoveBackup(const std::string &backup_datname) {
  68. if (remove(backup_datname.c_str()) != 0)
  69. LOG(INFO) << "Removed backup file " << backup_datname;
  70. return DatOperationResult<>(SUCCESS);
  71. }
  72. /*!
  73. * \author Gi1dor
  74. * \date 11.07.2018
  75. * Копирует содержимое dat файла в файл target
  76. * \param[in] source dat файл для копирования. Должен быть проинициализирован
  77. * \param[in] target файл для записи. Должен быть открыт на запись.
  78. * \warning Файл target после выполнения функции НЕ будет закрыт. Требуется закрыть командой fclose;
  79. */
  80. DatOperationResult<> DatBackupManager::CopyDatFile(DatFile &source, FILE *target) {
  81. long long parts_count =
  82. source.GetIO().file_size / COPY_BLOCK_SIZE + (source.GetIO().file_size % COPY_BLOCK_SIZE != 0);
  83. long long newfile_size = 0;
  84. long long elapsed_size = source.GetIO().file_size - newfile_size;
  85. BinaryData data(COPY_BLOCK_SIZE);
  86. for (unsigned i = 0; i < parts_count; i++) {
  87. auto operation = source.GetIO().ReadData(data, std::min((long long)(COPY_BLOCK_SIZE), elapsed_size), newfile_size);
  88. if (operation.result == ERROR)
  89. return DatOperationResult<>(ERROR, "Copy failed. Read data error");
  90. fwrite(data.data(), data.size(), 1, target);
  91. newfile_size += std::min((long long)(COPY_BLOCK_SIZE), elapsed_size);
  92. elapsed_size -= std::min((long long)(COPY_BLOCK_SIZE), elapsed_size);
  93. }
  94. return DatOperationResult<>(SUCCESS);
  95. }
  96. }