SourcePP
Several modern C++20 libraries for sanely parsing Valve's formats.
Loading...
Searching...
No Matches
ORE.cpp
Go to the documentation of this file.
1#include <vpkpp/format/ORE.h>
2
3#include <filesystem>
4
5#include <FileStream.h>
6
7using namespace sourcepp;
8using namespace vpkpp;
9
10std::unique_ptr<PackFile> ORE::create(const std::string& path) {
11 {
12 FileStream stream{path, FileStream::OPT_TRUNCATE | FileStream::OPT_CREATE_IF_NONEXISTENT};
13 stream
14 .write<uint32_t>(sizeof(uint32_t) * 3)
15 .write<uint32_t>(0)
16 .write<uint32_t>(0);
17 }
18 return ORE::open(path);
19}
20
21std::unique_ptr<PackFile> ORE::open(const std::string& path, const EntryCallback& callback) {
22 if (!std::filesystem::exists(path)) {
23 // File does not exist
24 return nullptr;
25 }
26
27 auto* ore = new ORE{path};
28 auto packFile = std::unique_ptr<PackFile>(ore);
29
30 FileStream reader{ore->fullFilePath};
31 reader.seek_in(0);
32
33 auto headerSize = reader.read<uint32_t>();
34 auto dirCount = reader.read<uint32_t>();
35 std::vector<std::pair<std::string, uint32_t>> dirInfos;
36 for (uint32_t i = 0; i < dirCount; i++) {
37 std::pair<std::string, uint32_t> dirInfo;
38 dirInfo.first = reader.read_string();
39 dirInfo.second = reader.read<uint32_t>();
40 dirInfos.push_back(dirInfo);
41 }
42 if (reader.tell_in() != headerSize) {
43 return nullptr;
44 }
45
46 auto looseFileCount = reader.read<uint32_t>();
47 const auto addOreFiles = [&callback, ore, &reader](const std::string& dirName, uint32_t dirOffset, uint32_t fileCount) {
48 for (uint32_t i = 0; i < fileCount; i++) {
49 Entry entry = createNewEntry();
50
51 auto entryPath = ore->cleanEntryPath(dirName + (dirName.empty() ? "" : "/") + reader.read_string());
52
53 entry.offset = reader.read<uint32_t>() + dirOffset;
54 entry.length = reader.read<uint32_t>();
55
56 ore->entries.emplace(entryPath, entry);
57
58 if (callback) {
59 callback(entryPath, entry);
60 }
61 }
62 };
63 addOreFiles("", headerSize, looseFileCount);
64
65 for (const auto& [dirName, dirOffset] : dirInfos) {
66 reader.seek_in(dirOffset);
67 if (reader.read<uint64_t>() != 8) {
68 return nullptr;
69 }
70 addOreFiles(dirName, dirOffset + sizeof(uint64_t), reader.read<uint32_t>());
71 }
72
73 return packFile;
74}
75
76std::optional<std::vector<std::byte>> ORE::readEntry(const std::string& path_) const {
77 auto path = this->cleanEntryPath(path_);
78 auto entry = this->findEntry(path);
79 if (!entry) {
80 return std::nullopt;
81 }
82 if (entry->unbaked) {
83 return readUnbakedEntry(*entry);
84 }
85
86 // It's baked into the file on disk
87 FileStream stream{this->fullFilePath};
88 if (!stream) {
89 return std::nullopt;
90 }
91 stream.seek_in_u(entry->offset);
92 return stream.read_bytes(entry->length);
93}
94
96 using enum Attribute;
97 return LENGTH;
98}
This class represents the metadata that a file has inside a PackFile.
Definition: Entry.h:14
uint64_t offset
Offset, format-specific meaning - 0 if unused, or if the offset genuinely is 0.
Definition: Entry.h:33
uint64_t length
Length in bytes (in formats with compression, this is the uncompressed length)
Definition: Entry.h:26
Definition: ORE.h:9
std::optional< std::vector< std::byte > > readEntry(const std::string &path_) const override
Try to read the entry's data to a bytebuffer.
Definition: ORE.cpp:76
static std::unique_ptr< PackFile > create(const std::string &path)
Create an ORE file.
Definition: ORE.cpp:10
Attribute getSupportedEntryAttributes() const override
Returns a list of supported entry attributes Mostly for GUI programs that show entries and their meta...
Definition: ORE.cpp:95
static std::unique_ptr< PackFile > open(const std::string &path, const EntryCallback &callback=nullptr)
Open an ORE file.
Definition: ORE.cpp:21
EntryCallbackBase< void > EntryCallback
Definition: PackFile.h:30
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 fullFilePath
Definition: PackFile.h:219
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
Attribute
Definition: Attribute.h:7