#pragma once
#include <string>
#include <memory>
#ifdef SHARED_LIBZIP
#include <zip.h>
#else
#include "ext/libzip/zip.h"
#endif
#include "Common/CommonTypes.h"
#include "Common/File/Path.h"
enum class IdentifiedFileType {
ERROR_IDENTIFYING,
PSP_PBP_DIRECTORY,
PSP_PBP,
PSP_ELF,
PSP_ISO,
PSP_ISO_NP,
PSP_DISC_DIRECTORY,
UNKNOWN_BIN,
UNKNOWN_ELF,
UNKNOWN_ISO,
ARCHIVE_RAR,
ARCHIVE_ZIP,
ARCHIVE_7Z,
PSP_PS1_PBP,
ISO_MODE2,
NORMAL_DIRECTORY,
PSP_SAVEDATA_DIRECTORY,
PPSSPP_SAVESTATE,
PPSSPP_GE_DUMP,
UNKNOWN,
};
class FileLoader {
public:
enum class Flags {
NONE,
HINT_UNCACHED,
};
virtual ~FileLoader() {}
virtual bool IsRemote() {
return false;
}
virtual bool Exists() = 0;
virtual bool ExistsFast() {
return Exists();
}
virtual bool IsDirectory() = 0;
virtual s64 FileSize() = 0;
virtual Path GetPath() const = 0;
virtual std::string GetFileExtension() const {
return GetPath().GetFileExtension();
}
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) = 0;
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) {
return ReadAt(absolutePos, 1, bytes, data, flags);
}
virtual void Cancel() {}
virtual std::string LatestError() const {
return "";
}
};
class ProxiedFileLoader : public FileLoader {
public:
ProxiedFileLoader(FileLoader *backend) : backend_(backend) {}
~ProxiedFileLoader() {
delete backend_;
}
bool IsRemote() override {
return backend_->IsRemote();
}
bool Exists() override {
return backend_->Exists();
}
bool ExistsFast() override {
return backend_->ExistsFast();
}
bool IsDirectory() override {
return backend_->IsDirectory();
}
s64 FileSize() override {
return backend_->FileSize();
}
Path GetPath() const override {
return backend_->GetPath();
}
void Cancel() override {
backend_->Cancel();
}
std::string LatestError() const override {
return backend_->LatestError();
}
size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
return backend_->ReadAt(absolutePos, bytes, count, data, flags);
}
size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override {
return backend_->ReadAt(absolutePos, bytes, data, flags);
}
FileLoader *Steal() {
FileLoader *backend = backend_;
backend_ = nullptr;
return backend;
}
protected:
FileLoader *backend_;
};
inline u32 operator & (const FileLoader::Flags &a, const FileLoader::Flags &b) {
return (u32)a & (u32)b;
}
FileLoader *ConstructFileLoader(const Path &filename);
FileLoader *ResolveFileLoaderTarget(FileLoader *fileLoader);
Path ResolvePBPDirectory(const Path &filename);
Path ResolvePBPFile(const Path &filename);
IdentifiedFileType Identify_File(FileLoader *fileLoader, std::string *errorString);
bool UmdReplace(const Path &filepath, FileLoader **fileLoader, std::string &error);
enum class ZipFileContents {
UNKNOWN,
PSP_GAME_DIR,
ISO_FILE,
TEXTURE_PACK,
SAVE_DATA,
FRAME_DUMP,
};
struct ZipFileInfo {
ZipFileContents contents;
int numFiles;
int stripChars;
int isoFileIndex;
int textureIniIndex;
bool ignoreMetaFiles;
std::string gameTitle;
std::string savedataTitle;
std::string savedataDetails;
std::string savedataDir;
std::string mTime;
s64 totalFileSize;
std::string contentName;
};
struct zip *ZipOpenPath(const Path &fileName);
void ZipClose(zip *z);
bool DetectZipFileContents(const Path &fileName, ZipFileInfo *info);
void DetectZipFileContents(struct zip *z, ZipFileInfo *info);