Subfile.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. //
  2. // Created by Иван_Архипов on 01.11.2017.
  3. //
  4. #include "Subfile.h"
  5. #include "BinaryData.h"
  6. #include "DatFile.h"
  7. #include "SubfileData.h"
  8. #include "EasyLogging++/easylogging++.h"
  9. #include <algorithm>
  10. const long long MAXSIZE = 50ll * 1024ll * 1024ll; // Setting maximal file size 50 MB; Files with size more than 50 mb
  11. // will be recognized as incorrect and passed.
  12. // This should be done because of not completely correct implementation
  13. // of Subfiles and Subdirectories search in DatFile.
  14. namespace LOTRO_DAT {
  15. Subfile::Subfile() = default;
  16. Subfile::Subfile(DatFile *dat, const BinaryData &header) {
  17. category = 0;
  18. dat_ = dat;
  19. unknown1_ = header.ToNumber<4>(0); // unknown1
  20. file_id_ = header.ToNumber<4>(4); // file_id
  21. file_offset_ = header.ToNumber<4>(8); // file_offset
  22. file_size_ = header.ToNumber<4>(12); // block_size
  23. timestamp_ = header.ToNumber<4>(16); // timestamp
  24. version_ = header.ToNumber<4>(20); // version
  25. block_size_ = header.ToNumber<4>(24); // block_size
  26. unknown2_ = header.ToNumber<4>(28); // unknown2
  27. }
  28. Subfile::Subfile(DatFile *dat, long long dictionary_offset, long long unknown1, long long file_id,
  29. long long file_offset,
  30. long long file_size, long long timestamp, long long version, long long block_size, long long unknown2) :
  31. category(0), dat_(dat), dictionary_offset_(dictionary_offset), unknown1_(unknown1), file_id_(file_id),
  32. file_offset_(file_offset),
  33. file_size_(file_size), timestamp_(timestamp), version_(version), block_size_(block_size), unknown2_(unknown2) {
  34. if (file_size_ > MAXSIZE) {
  35. LOG(ERROR) << "Bad Subfile::Subfile() - File size of file " << file_id << " with offset " << file_offset
  36. <<" is too much... Maybe it's incorrect..?";
  37. file_id_ = -1;
  38. return;
  39. }
  40. }
  41. /// Typical getters of private fields, if there's need for getting information about SubFile from outside class.
  42. long long Subfile::dictionary_offset() const {
  43. return dictionary_offset_;
  44. }
  45. long long Subfile::unknown1() const {
  46. return unknown1_;
  47. }
  48. long long Subfile::file_id() const {
  49. return file_id_;
  50. }
  51. long long Subfile::file_offset() const {
  52. return file_offset_;
  53. }
  54. long long Subfile::file_size() const {
  55. return file_size_;
  56. }
  57. long long Subfile::timestamp() const {
  58. return timestamp_;
  59. }
  60. long long Subfile::version() const {
  61. return version_;
  62. }
  63. long long Subfile::block_size() const {
  64. return block_size_;
  65. }
  66. long long Subfile::unknown2() const {
  67. return unknown2_;
  68. }
  69. /// bool Subfile::FileType(...);
  70. /// Virtual function, can (and should) be redefined in child class, otherwise an exception will be thrown while exporting/importing file.
  71. /// Returns enum FILE_TYPE value, which is declared in DatFile.h
  72. FILE_TYPE Subfile::FileType() const {
  73. LOG(ERROR) << "INCORRECT IMPLEMENTATION!";
  74. return UNKNOWN;
  75. }
  76. /// std::string Subfile::Extension()
  77. /// Virtual function, can (and should) be redefined in child class, otherwise an exception will be thrown while exporting/importing file.
  78. /// Returns std::string with extension, beggined with '.', ex. ".jpg", ".txt" and so on;
  79. std::string Subfile::Extension() const {
  80. LOG(ERROR) << "INCORRECT IMPLEMENTATION!";
  81. return ".subfile";
  82. }
  83. /// bool Subfile::PrepareForExport(...);
  84. /// Virtual function, can be redefined in child class, otherwise an exception will be thrown while exporting file.
  85. /// Takes constant BinaryData& file_data, which contains all file data in .dat file, except first 8 bytes before file_id.
  86. /// Takes references to export_size - amount of exported files/strings, and content of exported data such as:
  87. /// 1) field binary_data - exported as RAW data
  88. /// 2) field text_data - UTF-16 text, exporting in UTF-8
  89. /// 3) field options - YAML field, which consists of some parameters of file such as file_id, extension and so on.
  90. /// Returns true if preparation was success. Otherwise returns false;
  91. SubfileData Subfile::PrepareForExport(const BinaryData &) {
  92. LOG(ERROR) << "INCORRECT IMPLEMENTATION!";
  93. return SubfileData();
  94. }
  95. /// BinaryData Subfile::PrepareForImport(...);
  96. /// Virtual function, can be redefined in child class, otherwise an exception will be thrown while importing file.
  97. /// Takes constant BinaryData& file_data, which contains all file data in .dat file, including first 8 bytes befire file_id.
  98. /// 1) const field binary_data - exported as RAW data
  99. /// 2) const field text_data - UTF-16 text, exporting in UTF-8
  100. /// 3) const field options - YAML field, which consists of some parameters of file such as file_id, extension and so on.
  101. /// Returns BinaryData - bytes array, prepared for writing in .dat file
  102. BinaryData Subfile::MakeForImport(const BinaryData &, const SubfileData &) {
  103. LOG(ERROR) << "INCORRECT IMPLEMENTATION!";
  104. return BinaryData(0);
  105. }
  106. BinaryData Subfile::MakeHeaderData() const {
  107. BinaryData header = BinaryData::FromNumber<4>(unknown1_)
  108. + BinaryData::FromNumber<4>(file_id_)
  109. + BinaryData::FromNumber<4>(file_offset_)
  110. + BinaryData::FromNumber<4>(file_size_)
  111. + BinaryData::FromNumber<4>(timestamp_)
  112. + BinaryData::FromNumber<4>(version_)
  113. + BinaryData::FromNumber<4>(block_size_)
  114. + BinaryData::FromNumber<4>(unknown2_);
  115. return header;
  116. }
  117. bool Subfile::operator==(const Subfile &b) const {
  118. return unknown1_ == b.unknown1_
  119. && file_id_ == b.file_id_
  120. && file_offset_ == b.file_offset_
  121. && file_size_ == b.file_size_
  122. && timestamp_ == b.timestamp_
  123. && version_ == b.version_
  124. && block_size_ == b.block_size_
  125. && unknown2_ == b.unknown2_;
  126. }
  127. bool Subfile::operator!=(const Subfile &b) const {
  128. return !(*this == b);
  129. }
  130. Subfile &Subfile::operator=(const Subfile &b) {
  131. if (*this == b)
  132. return *this;
  133. category = b.category;
  134. dat_ = b.dat_;
  135. unknown1_ = b.unknown1_; // unknown1
  136. file_id_ = b.file_id_; // file_id
  137. file_offset_ = b.file_offset_; // file_offset
  138. file_size_ = b.file_size_; // block_size
  139. timestamp_ = b.timestamp_; // timestamp
  140. version_ = b.version_; // version
  141. block_size_ = b.block_size_; // block_size
  142. unknown2_ = b.unknown2_; // unknown2
  143. return *this;
  144. }
  145. };