unancient.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * unancient.cpp
  3. * -------------
  4. * Purpose: Implementation file for extracting modules from compressed files supported by libancient
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #include "stdafx.h"
  10. #include "unancient.h"
  11. #ifdef MPT_WITH_ANCIENT
  12. #include <ancient/ancient.hpp>
  13. #endif // MPT_WITH_ANCIENT
  14. OPENMPT_NAMESPACE_BEGIN
  15. #ifdef MPT_WITH_ANCIENT
  16. CAncientArchive::CAncientArchive(FileReader &file)
  17. : ArchiveBase(file)
  18. {
  19. inFile.Rewind();
  20. try
  21. {
  22. auto dataView = inFile.GetPinnedView();
  23. if(!ancient::Decompressor::detect(mpt::byte_cast<const std::uint8_t*>(dataView.data()), dataView.size()))
  24. {
  25. return;
  26. }
  27. ancient::Decompressor decompressor{mpt::byte_cast<const std::uint8_t*>(dataView.data()), dataView.size(), true, true};
  28. if(decompressor.getImageSize() || decompressor.getImageOffset())
  29. {
  30. // skip disk images
  31. return;
  32. }
  33. ArchiveFileInfo fileInfo;
  34. fileInfo.name = inFile.GetOptionalFileName().value_or(P_(""));
  35. fileInfo.type = ArchiveFileType::Normal;
  36. fileInfo.size = decompressor.getRawSize().value_or(0);
  37. contents.push_back(fileInfo);
  38. } catch(const ancient::Error &)
  39. {
  40. return;
  41. }
  42. }
  43. CAncientArchive::~CAncientArchive()
  44. {
  45. return;
  46. }
  47. bool CAncientArchive::ExtractFile(std::size_t index)
  48. {
  49. if(index >= contents.size())
  50. {
  51. return false;
  52. }
  53. data.clear();
  54. inFile.Rewind();
  55. try
  56. {
  57. auto dataView = inFile.GetPinnedView();
  58. ancient::Decompressor decompressor{mpt::byte_cast<const std::uint8_t*>(dataView.data()), dataView.size(), true, true};
  59. data = mpt::buffer_cast<std::vector<char>>(decompressor.decompress(true));
  60. } catch (const ancient::Error &)
  61. {
  62. return false;
  63. }
  64. return (data.size() > 0);
  65. }
  66. #endif // MPT_WITH_ANCIENT
  67. OPENMPT_NAMESPACE_END