12std::unique_ptr<PackFile>
GRP::create(
const std::string& path) {
14 FileStream stream{path, FileStream::OPT_TRUNCATE | FileStream::OPT_CREATE_IF_NONEXISTENT};
23 if (!std::filesystem::exists(path)) {
28 auto* grp =
new GRP{path};
29 auto packFile = std::unique_ptr<PackFile>(grp);
31 FileStream reader{grp->fullFilePath};
39 const auto entryCount = reader.read<uint32_t>();
42 uint32_t currentOffset = dirSize;
43 for (
int i = 0; i < entryCount; i++) {
48 entry.
length = reader.read<uint32_t>();
50 entry.
offset = currentOffset;
51 currentOffset += entry.
length;
53 grp->entries.emplace(entryPath, entry);
56 callback(entryPath, entry);
63std::optional<std::vector<std::byte>>
GRP::readEntry(
const std::string& path_)
const {
78 stream.seek_in_u(entry->offset);
79 return stream.read_bytes(entry->length);
83 entry.
length = buffer.size();
92 const std::string outputPath = outputDir +
'/' + this->
getFilename();
95 std::vector<std::pair<std::string, Entry*>> entriesToBake;
97 entriesToBake.emplace_back(path, &entry);
102 std::vector<std::byte> fileData;
103 for (
auto& [path, entry] : entriesToBake) {
104 if (
auto binData = this->
readEntry(path)) {
105 entry->
offset = fileData.size() + dirSize;
107 fileData.insert(fileData.end(), binData->begin(), binData->end());
115 FileStream stream{outputPath, FileStream::OPT_TRUNCATE | FileStream::OPT_CREATE_IF_NONEXISTENT};
121 .write<uint32_t>(entriesToBake.size());
124 for (
const auto& [path, entry] : entriesToBake) {
127 .write<uint32_t>(entry->
length);
130 callback(path, *entry);
135 stream.write(fileData);
This class represents the metadata that a file has inside a PackFile.
uint64_t offset
Offset, format-specific meaning - 0 if unused, or if the offset genuinely is 0.
uint64_t length
Length in bytes (in formats with compression, this is the uncompressed length).
static std::unique_ptr< PackFile > open(const std::string &path, const EntryCallback &callback=nullptr)
Open a GRP file.
static std::unique_ptr< PackFile > create(const std::string &path)
Create a GRP file.
std::optional< std::vector< std::byte > > readEntry(const std::string &path_) const override
Try to read the entry's data to a bytebuffer.
Attribute getSupportedEntryAttributes() const override
Returns a list of supported entry attributes Mostly for GUI programs that show entries and their meta...
void addEntryInternal(Entry &entry, const std::string &path, std::vector< std::byte > &buffer, EntryOptions options) override
EntryCallbackBase< void > EntryCallback
void mergeUnbakedEntries()
std::optional< Entry > findEntry(const std::string &path_, bool includeUnbaked=true) const
Try to find an entry given the file path.
void runForAllEntriesInternal(const std::function< void(const std::string &, Entry &)> &operation, bool includeUnbaked=true)
bool bake()
If output folder is an empty string, it will overwrite the original.
std::string getFilename() const
/home/user/pak01_dir.vpk -> pak01_dir.vpk
std::string getBakeOutputDir(const std::string &outputDir) const
void setFullFilePath(const std::string &outputDir)
std::string cleanEntryPath(const std::string &path) const
static Entry createNewEntry()
static std::optional< std::vector< std::byte > > readUnbakedEntry(const Entry &entry)
constexpr std::string_view GRP_SIGNATURE
constexpr int8_t GRP_FILENAME_MAX_SIZE