Package.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include <fstream>
  2. #include <memory>
  3. #include "Package.h"
  4. #include "WallpaperEngine/Assets/AssetLoadException.h"
  5. #include "WallpaperEngine/Data/Parsers/PackageParser.h"
  6. #include "WallpaperEngine/Data/Utils/BinaryReader.h"
  7. #include "WallpaperEngine/Data/Utils/MemoryStream.h"
  8. #include <algorithm>
  9. using namespace WallpaperEngine::FileSystem;
  10. using namespace WallpaperEngine::FileSystem::Adapters;
  11. ReadStreamSharedPtr PackageAdapter::open (const std::filesystem::path& path) const {
  12. // find the file entry
  13. const auto it = std::ranges::find_if (this->package->files, [&path] (const auto& file) {
  14. return file->filename == path.string ();
  15. });
  16. if (it == this->package->files.end ()) {
  17. throw std::filesystem::filesystem_error ("Cannot find file", path, std::error_code ());
  18. }
  19. // read file into memory
  20. auto buffer = std::make_unique<char[]> (it->get ()->length);
  21. // go to the file's position and read into the buffer
  22. this->package->file->base ().seekg (it->get ()->offset + this->package->baseOffset, std::ios::beg);
  23. this->package->file->next (buffer.get (), it->get ()->length);
  24. // create a memory stream and return that
  25. return std::make_shared<MemoryStream> (std::move (buffer), it->get ()->length);
  26. }
  27. bool PackageAdapter::exists (const std::filesystem::path& path) const {
  28. for (const auto& file : this->package->files) {
  29. if (file->filename == path.string ()) {
  30. return true;
  31. }
  32. }
  33. return false;
  34. }
  35. std::filesystem::path PackageAdapter::physicalPath (const std::filesystem::path& path) const {
  36. throw std::filesystem::filesystem_error ("Package adapter does not support realpath", path, std::error_code ());
  37. }
  38. bool PackageFactory::handlesMountpoint (const std::filesystem::path& path) const {
  39. try {
  40. const auto finalpath = std::filesystem::canonical (path);
  41. const auto status = std::filesystem::status (finalpath);
  42. return std::filesystem::exists (finalpath) && std::filesystem::is_regular_file (status)
  43. && finalpath.extension () == ".pkg";
  44. } catch (std::filesystem::filesystem_error&) {
  45. return false;
  46. }
  47. }
  48. AdapterSharedPtr PackageFactory::create (const std::filesystem::path& path) const {
  49. const auto stream = std::make_shared<std::ifstream> (path, std::ios::binary);
  50. auto package = Data::Parsers::PackageParser::parse (stream);
  51. return std::make_unique<PackageAdapter> (std::move (package));
  52. }