8#include <unordered_map>
12#include <tsl/htrie_map.h>
47 [[nodiscard]]
static std::unique_ptr<PackFile>
open(
const std::string& path,
const EntryCallback& callback =
nullptr);
53 [[nodiscard]]
virtual constexpr std::string_view
getGUID()
const = 0;
57 requires requires (
const T&) {{T::GUID} -> std::convertible_to<std::string_view>;}
59 return this->
getGUID() == T::GUID;
91 [[nodiscard]]
bool hasEntry(
const std::string& path,
bool includeUnbaked =
true)
const;
94 [[nodiscard]] std::optional<Entry>
findEntry(
const std::string& path_,
bool includeUnbaked =
true)
const;
97 [[nodiscard]]
virtual std::optional<std::vector<std::byte>>
readEntry(
const std::string& path_)
const = 0;
100 [[nodiscard]] std::optional<std::string>
readEntryText(
const std::string& path)
const;
102 [[nodiscard]]
virtual constexpr bool isReadOnly() const noexcept {
107 void addEntry(
const std::string& entryPath,
const std::string& filepath,
EntryOptions options = {});
110 void addEntry(
const std::string& path, std::vector<std::byte>&& buffer, EntryOptions options = {});
113 void addEntry(
const std::string& path,
const std::byte* buffer, uint64_t bufferLen, EntryOptions options = {});
116 void addDirectory(
const std::string& entryBaseDir,
const std::string& dir, EntryOptions options = {});
122 virtual bool renameEntry(
const std::string& oldPath_,
const std::string& newPath_);
125 virtual bool renameDirectory(
const std::string& oldDir_,
const std::string& newDir_);
128 virtual bool removeEntry(
const std::string& path_);
137 bool extractEntry(
const std::string& entryPath,
const std::string& filepath)
const;
140 bool extractDirectory(
const std::string& dir_,
const std::string& outputDir)
const;
143 bool extractAll(
const std::string& outputDir,
bool createUnderPackFileDir =
true)
const;
155 [[nodiscard]] std::size_t
getEntryCount(
bool includeUnbaked =
true)
const;
161 void runForAllEntries(
const std::string& parentDir,
const EntryCallback& operation,
bool recursive =
true,
bool includeUnbaked =
true)
const;
164 [[nodiscard]] std::string_view
getFilepath()
const;
185 [[nodiscard]]
virtual explicit operator std::string()
const;
191 explicit PackFile(std::string fullFilePath_);
195 void runForAllEntriesInternal(
const std::string& parentDir,
const std::function<
void(
const std::string&,
Entry&)>& operation,
bool recursive =
true,
bool includeUnbaked =
true);
201 [[nodiscard]] std::string
getBakeOutputDir(
const std::string& outputDir)
const;
207 [[nodiscard]] std::string
cleanEntryPath(
const std::string& path)
const;
226 [[nodiscard]]
constexpr bool isReadOnly() const noexcept final {
230 [[nodiscard]]
explicit operator std::string()
const override;
242#define VPKPP_REGISTER_PACKFILE_OPEN(extension, function) \
243 static inline const OpenFactoryFunction& SOURCEPP_UNIQUE_NAME(packFileOpenTypeFactoryFunction) = PackFile::registerOpenExtensionForTypeFactory(extension, function)
245#define VPKPP_REGISTER_PACKFILE_OPEN_EXECUTABLE(function) \
246 static inline const OpenFactoryFunction& SOURCEPP_UNIQUE_NAME(packFileOpenExecutable0TypeFactoryFunction) = PackFile::registerOpenExtensionForTypeFactory(vpkpp::EXECUTABLE_EXTENSION0, function); \
247 static inline const OpenFactoryFunction& SOURCEPP_UNIQUE_NAME(packFileOpenExecutable1TypeFactoryFunction) = PackFile::registerOpenExtensionForTypeFactory(vpkpp::EXECUTABLE_EXTENSION1, function); \
248 static inline const OpenFactoryFunction& SOURCEPP_UNIQUE_NAME(packFileOpenExecutable2TypeFactoryFunction) = PackFile::registerOpenExtensionForTypeFactory(vpkpp::EXECUTABLE_EXTENSION2, function)
This class represents the metadata that a file has inside a PackFile.
bool bake(const std::string &outputDir_, BakeOptions options, const EntryCallback &callback) final
If output folder is an empty string, it will overwrite the original.
void addEntryInternal(Entry &entry, const std::string &path, std::vector< std::byte > &buffer, EntryOptions options) final
constexpr bool isReadOnly() const noexcept final
virtual constexpr bool hasEntryChecksums() const
Returns true if the format has a checksum for each entry.
tsl::htrie_map< char, Entry > EntryTrie
std::optional< std::string > readEntryText(const std::string &path) const
Try to read the entry's data to a string.
bool extractAll(const std::string &outputDir, bool createUnderPackFileDir=true) const
Extract the contents of the pack file to disk at the given directory.
virtual ~PackFile()=default
virtual bool hasPackFileSignature() const
Returns true if the file is signed.
EntryCallbackBase< void > EntryCallback
virtual std::size_t removeDirectory(const std::string &dirName_)
Remove a directory.
std::function< std::unique_ptr< PackFile >(const std::string &path, const EntryCallback &callback)> OpenFactoryFunction
static std::unordered_map< std::string, std::vector< OpenFactoryFunction > > & getOpenExtensionRegistry()
virtual bool renameDirectory(const std::string &oldDir_, const std::string &newDir_)
Rename an existing directory.
void mergeUnbakedEntries()
virtual constexpr std::string_view getGUID() const =0
Get the GUID corresponding to the pack file type.
bool isInstanceOf() const
Check if the pack file is an instance of the given pack file class.
std::optional< Entry > findEntry(const std::string &path_, bool includeUnbaked=true) const
Try to find an entry given the file path.
virtual bool verifyPackFileChecksum() const
Verify the checksum of the entire file, returns true on success Will return true if there is no check...
bool extractDirectory(const std::string &dir_, const std::string &outputDir) const
Extract the given directory to disk under the given output directory.
virtual bool verifyPackFileSignature() const
Verify the file signature, returns true on success Will return true if there is no signature ability ...
virtual void addEntryInternal(Entry &entry, const std::string &path, std::vector< std::byte > &buffer, EntryOptions options)=0
virtual bool bake(const std::string &outputDir_, BakeOptions options, const EntryCallback &callback)=0
If output folder is an empty string, it will overwrite the original.
bool extractEntry(const std::string &entryPath, const std::string &filepath) const
Extract the given entry to disk at the given file path.
virtual std::string getTruncatedFilestem() const
/home/user/pak01_dir.vpk -> pak01
virtual std::vector< std::string > verifyEntryChecksums() const
Verify the checksums of each file, if a file fails the check its path will be added to the vector If ...
PackFile & operator=(const PackFile &other)=delete
virtual bool hasPackFileChecksum() const
Returns true if the entire file has a checksum.
std::vector< std::string > verifyEntryChecksumsUsingCRC32() const
virtual constexpr bool isReadOnly() const noexcept
EntryCallbackBase< bool > EntryPredicate
PackFile(PackFile &&other) noexcept=default
virtual constexpr bool isCaseSensitive() const
Does the format support case-sensitive file names?
void runForAllEntriesInternal(const std::function< void(const std::string &, Entry &)> &operation, bool includeUnbaked=true)
static const OpenFactoryFunction & registerOpenExtensionForTypeFactory(std::string_view extension, const OpenFactoryFunction &factory)
std::string getFilestem() const
/home/user/pak01_dir.vpk -> pak01_dir
bool hasEntry(const std::string &path, bool includeUnbaked=true) const
Check if an entry exists given the file path.
virtual bool renameEntry(const std::string &oldPath_, const std::string &newPath_)
Rename an existing entry.
std::string getFilename() const
/home/user/pak01_dir.vpk -> pak01_dir.vpk
std::string getBakeOutputDir(const std::string &outputDir) const
static std::string escapeEntryPathForWrite(const std::string &path)
On Windows, some characters and file names are invalid - this escapes the given entry path.
std::string getTruncatedFilepath() const
/home/user/pak01_dir.vpk -> /home/user/pak01
void runForAllEntries(const EntryCallback &operation, bool includeUnbaked=true) const
Run a callback for each entry in the pack file.
void setFullFilePath(const std::string &outputDir)
void addDirectory(const std::string &entryBaseDir, const std::string &dir, EntryOptions options={})
Adds new entries using the contents of a given directory.
std::function< EntryOptions(const std::string &path)> EntryCreation
void addEntry(const std::string &entryPath, const std::string &filepath, EntryOptions options={})
Add a new entry from a file path - the first parameter is the path in the PackFile,...
std::string cleanEntryPath(const std::string &path) const
virtual Attribute getSupportedEntryAttributes() const
Returns a list of supported entry attributes Mostly for GUI programs that show entries and their meta...
virtual std::optional< std::vector< std::byte > > readEntry(const std::string &path_) const =0
Try to read the entry's data to a bytebuffer.
PackFile(const PackFile &other)=delete
static std::vector< std::string > getOpenableExtensions()
Returns a sorted list of supported extensions for opening, e.g. {".bsp", ".vpk"}.
PackFile & operator=(PackFile &&other) noexcept=default
const EntryTrie & getBakedEntries() const
Get entries saved to disk.
static Entry createNewEntry()
std::string getTruncatedFilename() const
/home/user/pak01_dir.vpk -> pak01.vpk
std::size_t getEntryCount(bool includeUnbaked=true) const
Get the number of entries in the pack file.
virtual bool removeEntry(const std::string &path_)
Remove an entry.
static std::unique_ptr< PackFile > open(const std::string &path, const EntryCallback &callback=nullptr)
Open a generic pack file. The parser is selected based on the file extension.
std::string_view getFilepath() const
/home/user/pak01_dir.vpk
std::function< R(const std::string &path, const Entry &entry)> EntryCallbackBase
Accepts the entry's path and metadata.
const EntryTrie & getUnbakedEntries() const
Get entries that have been added but not yet baked.
static std::optional< std::vector< std::byte > > readUnbakedEntry(const Entry &entry)
constexpr std::string_view EXECUTABLE_EXTENSION1
constexpr std::string_view EXECUTABLE_EXTENSION0
constexpr std::string_view EXECUTABLE_EXTENSION2