SourcePP
Several modern C++20 libraries for sanely parsing Valve's formats.
Loading...
Searching...
No Matches
ExamplePackFileImpl.cpp
Go to the documentation of this file.
2
3#include <filesystem>
4#include <tuple>
5
6#include <sourcepp/fs/FS.h>
7
8using namespace sourcepp;
9using namespace vpkpp;
10
11std::unique_ptr<PackFile> EXAMPLE::open(const std::string& path, const EntryCallback& callback) {
12 // Check if the file exists
13 if (!std::filesystem::exists(path)) {
14 // File does not exist
15 return nullptr;
16 }
17
18 // Create the pack file
19 auto* example = new EXAMPLE{path};
20 auto packFile = std::unique_ptr<PackFile>(example);
21
22 // Here is where you add entries to the entries member variable
23 // It's a map between a directory and a vector of entries
24 // Every time an entry is added, the callback should be called if the callback exists
25 std::vector<std::string> samplePaths{
26 {"a/b/c/skibidi_toilet.png"},
27 {"d/c/boykisser.mdl"},
28 {"megamind.txt"},
29 };
30 for (const auto& entryPath_ : samplePaths) {
31 // The path needs to be normalized, and respect case sensitivity
32 auto entryPath = example->cleanEntryPath(entryPath_);
33
34 // Use the createNewEntry function to avoid Entry having to friend every single damn class
35 Entry entry = createNewEntry();
36
37 // The length should be the full uncompressed length of the file data in bytes
38 entry.length = 42;
39
40 // This is the CRC32 of the file - a helper function to compute it is in <sourcepp/crypto/CRC32.h>
41 // This can also be omitted if unused, 0 is the default
42 entry.crc32 = 0;
43
44 // Add the entry to the entries trie
45 example->entries.emplace(entryPath, entry);
46
47 // Call the callback
48 if (callback) {
49 callback(entryPath, entry);
50 }
51 }
52
53 return packFile;
54}
55
56std::optional<std::vector<std::byte>> EXAMPLE::readEntry(const std::string& path_) const {
57 // Include this code verbatim
58 auto path = this->cleanEntryPath(path_);
59 auto entry = this->findEntry(path);
60 if (!entry) {
61 return std::nullopt;
62 }
63 if (entry->unbaked) {
64 return readUnbakedEntry(*entry);
65 }
66
67 // Use the contents of the entry to access the file data and return it
68 // Return std::nullopt if there was an error during any step of this process - not an empty buffer!
69 return std::nullopt;
70}
71
72void EXAMPLE::addEntryInternal(Entry& entry, const std::string& path, std::vector<std::byte>& buffer, EntryOptions options) {
73 // Initialize the entry - set the entry properties just like in EXAMPLE::open
74 entry.length = 0;
75 // ...
76}
77
78bool EXAMPLE::bake(const std::string& outputDir_, BakeOptions options, const EntryCallback& callback) {
79 // Get the proper file output folder (include this verbatim)
80 std::string outputDir = this->getBakeOutputDir(outputDir_);
81 std::string outputPath = outputDir + '/' + this->getFilename();
82
83 // Loop over all entries and save them
84 this->runForAllEntries([&callback](const std::string& path, const Entry& entry) {
85 auto binData = this->readEntry(path);
86 if (!binData) {
87 return;
88 }
89
90 // Write data here
91 // ...
92
93 // Call the callback
94 if (callback) {
95 callback(path, entry);
96 }
97 });
98
99 // Call this when all the entries have been written to disk
100 this->mergeUnbakedEntries();
101
102 // Include this verbatim at the end of the function
103 PackFile::setFullFilePath(outputDir);
104 // Return false before this if it encounters an error
105 return true;
106}
void addEntryInternal(Entry &entry, const std::string &path, std::vector< std::byte > &buffer, EntryOptions options) override
std::optional< std::vector< std::byte > > readEntry(const std::string &path_) const override
Try to read the entry's data to a bytebuffer.
bool bake(const std::string &outputDir_, BakeOptions options, const EntryCallback &callback) override
If output folder is an empty string, it will overwrite the original.
static std::unique_ptr< PackFile > open(const std::string &path, const EntryCallback &callback=nullptr)
This class represents the metadata that a file has inside a PackFile.
Definition: Entry.h:14
uint32_t crc32
CRC32 checksum - 0 if unused.
Definition: Entry.h:40
uint64_t length
Length in bytes (in formats with compression, this is the uncompressed length)
Definition: Entry.h:26
EntryCallbackBase< void > EntryCallback
Definition: PackFile.h:30
void mergeUnbakedEntries()
Definition: PackFile.cpp:656
std::optional< Entry > findEntry(const std::string &path_, bool includeUnbaked=true) const
Try to find an entry given the file path.
Definition: PackFile.cpp:163
std::string getFilename() const
/home/user/pak01_dir.vpk -> pak01_dir.vpk
Definition: PackFile.cpp:591
std::string getBakeOutputDir(const std::string &outputDir) const
Definition: PackFile.cpp:640
void runForAllEntries(const EntryCallback &operation, bool includeUnbaked=true) const
Run a callback for each entry in the pack file.
Definition: PackFile.cpp:499
void setFullFilePath(const std::string &outputDir)
Definition: PackFile.cpp:672
std::string cleanEntryPath(const std::string &path) const
Definition: PackFile.cpp:677
static Entry createNewEntry()
Definition: PackFile.cpp:686
static std::optional< std::vector< std::byte > > readUnbakedEntry(const Entry &entry)
Definition: PackFile.cpp:690
Definition: LZMA.h:11
Definition: Attribute.h:5