DatFileSystem.cpp 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //
  2. // Created by kikab on 04.06.2018.
  3. //
  4. #include <DatSubsystems/DatFileSystem.h>
  5. #include <EasyLogging++/easylogging++.h>
  6. #include <BinaryData.h>
  7. #include <DatFile.h>
  8. #include <SubFile.h>
  9. namespace LOTRO_DAT{
  10. DatFileSystem::DatFileSystem(DatFile *datFilePtr) : dat(datFilePtr) {
  11. LOG(INFO) << "Initialization of empty DatFileSystem";
  12. }
  13. DatOperationResult<BinaryData> DatFileSystem::GetFileData(long long file_id, long long int offset) {
  14. if (!dat)
  15. return DatOperationResult<BinaryData>(BinaryData(), ERROR, "DatFileSystem error: no connection with Dat (dat is nullptr)");
  16. if (dictionary_.count(file_id))
  17. return DatOperationResult<BinaryData>(BinaryData(), ERROR, "DatFileSystem error: no file found with id = " + std::to_string(file_id));
  18. auto file = dictionary_[file_id];
  19. LOG(DEBUG) << "Getting file " << file->file_id() << " data";
  20. BinaryData mfile_id(20);
  21. auto operation = dat->getIO().ReadData(mfile_id, 20, file->file_offset() + 8);
  22. if (operation.result == ERROR) {
  23. LOG(ERROR) << "Error while reading file " << file->file_id() << " header (offset = "
  24. << file->file_offset() << "); Message: " << operation.msg << "Aborting.";
  25. return DatOperationResult<BinaryData>(BinaryData(), ERROR, std::string("DatFileSystem error: Read ") + std::to_string(file_id) + " error." + operation.msg);
  26. }
  27. if (!mfile_id.CheckCompression() && file->file_id() != mfile_id.ToNumber<4>(0)) {
  28. LOG(ERROR) << "Bad DatFile::GetFileData() - file_id in SubFile ("
  29. << file->file_id()
  30. << ") doesn't match to file_id (" << mfile_id.ToNumber<4>(0) << ")in DatFile.";
  31. return DatOperationResult<BinaryData>(BinaryData(), ERROR, std::string("DatFileSystem error: Read ") + std::to_string(file_id) + " error: SubFile value differs from value in dict");
  32. }
  33. BinaryData data((unsigned)(file->file_size() + (8 - offset)));
  34. if (file->block_size() >= file->file_size() + 8) {
  35. dat->getIO().ReadData(data, file->file_size() + (8 - offset), file->file_offset() + offset);
  36. return DatOperationResult<BinaryData>(data, SUCCESS);
  37. }
  38. BinaryData fragments_count(4);
  39. dat->getIO().ReadData(fragments_count, 4, file->file_offset());
  40. long long fragments_number = fragments_count.ToNumber<4>(0);
  41. long long current_block_size = file->block_size() - offset - 8 * fragments_number;
  42. dat->getIO().ReadData(data, current_block_size, file->file_offset() + offset);
  43. BinaryData FragmentsDictionary(8 * unsigned(fragments_number));
  44. dat->getIO().ReadData(FragmentsDictionary, 8 * unsigned(fragments_number),
  45. file->file_offset() + file->block_size() - 8 * fragments_number);
  46. for (long long i = 0; i < fragments_number; i++) {
  47. long long fragment_size = FragmentsDictionary.ToNumber<4>(8 * i);
  48. long long fragment_offset = FragmentsDictionary.ToNumber<4>(8 * i + 4);
  49. dat->getIO().ReadData(data, std::min(fragment_size, file->file_size() - current_block_size), fragment_offset,
  50. current_block_size);
  51. current_block_size += fragment_size;
  52. }
  53. LOG(DEBUG) << "Successfully got file " << file->file_id() << " data";
  54. return DatOperationResult<BinaryData>(data, SUCCESS);
  55. }
  56. DatOperationResult<SubFile> DatFileSystem::GetFile(long long file_id) {
  57. }
  58. DatOperationResult<> DatFileSystem::UpdateFile(const SubFile &file) {
  59. }
  60. DatOperationResult<> DatFileSystem::MakeDirectories() {
  61. }
  62. DatOperationResult<> DatFileSystem::MakeDictionary() {
  63. }
  64. DatOperationResult<> DatFileSystem::CommitDirectories() {
  65. }
  66. DatOperationResult<> DatFileSystem::Init() {}
  67. DatOperationResult<> DatFileSystem::DeInit() {}
  68. }