1#include "ResourceArchive.h"
3#include "Resources/ResourceStore.h"
5#include "Foundation/Logging/Logger.h"
6#include "Foundation/Platform/IO.h"
7#include "Foundation/Platform/Threads.h"
9#include <../miniz/miniz.h>
11#include <unordered_map>
20 mz_zip_archive archive = {};
22 std::unordered_map<std::string, mz_zip_archive_file_stat> entries;
28 int ResourceArchiveDummy() {
return 42; }
34 std::string archiveName(archivePath);
35 std::string fileName = archiveName;
38 if (!IO::exists(fileName)) {
40 fileName = IO::getPathRelativeToDll(archiveName, (
void *)&ResourceArchiveDummy);
43 if (!IO::exists(fileName)) {
45 fileName = IO::combine(IO::parentPath(IO::parentPath(fileName)), IO::fileName(archivePath));
47 if (!IO::exists(fileName)) {
50 auto cogsDir = IO::expandEnvironmentVariable(
"COGSDIR");
52 if (cogsDir.size() && (cogsDir !=
"%COGSDIR%")) {
53 fileName = cogsDir +
"/bin/" + archiveName;
55 if (!IO::exists(fileName)) {
57 fileName = archiveName;
61 LOG_WARNING(logger,
"Could not locate resource file %s, no COGSDIR environment variable found.", fileName.c_str());
69 if (contents.empty()) {
70 LOG_ERROR(logger,
"File or Resource not found? Empty resource archive. %s", fileName.c_str());
73 mz_uint numEntries = 0;
75 if (mz_zip_reader_init_mem(&storage->archive, contents.data(), contents.size(), 0)) {
76 numEntries = mz_zip_reader_get_num_files(&storage->archive);
77 LOG_DEBUG(logger,
"Loaded resource file (Entries=%u) %s.",
static_cast<uint32_t
>(numEntries), fileName.c_str());
79 LOG_ERROR(logger,
"Failed to open archive %s.", fileName.c_str());
83 LOG_WARNING(logger,
"Archive %s contains no entries.", fileName.c_str());
86 for (mz_uint i = 0; i < numEntries; ++i) {
87 mz_zip_archive_file_stat entry = {};
88 mz_zip_reader_file_stat(&storage->archive, i, &entry);
90 storage->entries[entry.m_filename] = entry;
94Cogs::Core::ResourceArchive::~ResourceArchive()
96 if (storage && storage->archive.m_archive_size) {
97 if (!mz_zip_reader_end(&storage->archive)) {
98 LOG_WARNING(logger,
"Failed to release zip archive.");
105 storage = std::move(other.storage);
110 storage = std::move(other.storage);
115bool Cogs::Core::ResourceArchive::hasResource(std::string_view path)
const
117 LockGuard lock(storage->m);
119 auto archiveIt = storage->entries.find(std::string(path));
121 return archiveIt != storage->entries.end();
126 LockGuard lock(storage->m);
128 auto archiveIt = storage->entries.find(std::string(path));
129 if (archiveIt != storage->entries.end()) {
130 const auto& entry = archiveIt->second;
132 mz_zip_reader_extract_to_mem(&storage->archive, entry.m_file_index, bytes.data(), bytes.size(), 0);
136 LOG_WARNING(logger,
"Internal Error: read of non-existing resource. Must check hasResource.");
Represents a resource archive used to load resources at runtime.
ResourceArchive(class ResourceStore *context, std::string_view archiveName)
Construct a resource archive with the given archive file.
ResourceArchive & operator=(ResourceArchive &&other)
Move assign operator.
Provides handling of reading and caching of external resources.
ResourceBuffer getResourceContents(std::string_view resourceName, ResourceStoreFlags flags=ResourceStoreFlags::None) const
Get the contents of the resource with the given name.
Log implementation class.
constexpr Log getLogger(const char(&name)[LEN]) noexcept