wowlib 0.0.0
Read & write World of Warcraft client files — a C++26 core
Loading...
Searching...
No Matches
client_filesystem.hpp
Go to the documentation of this file.
1#pragma once
2
7
8#include <optional>
9#include <span>
10#include <string_view>
11#include <utility>
12
14#include <wowlib/core/error.hpp>
19
20namespace wowlib::fs {
27 template <StorageBackend Backend, ListfileProvider Listfile = NullListfile>
29 public:
34 ClientFileSystem(Backend backend, Listfile listfile = {}, std::optional<ProjectDirectory> project = std::nullopt)
35 : _backend(std::move(backend)), _listfile(std::move(listfile)), _project(std::move(project)) {}
36
42 const FileKey resolved = resolve(key);
43
44 if (_project && resolved.path && _project->exists(*resolved.path)) return _project->read(*resolved.path);
45
46 return _backend.readFile(resolved);
47 }
48
52 bool exists(const FileKey& key) {
53 const FileKey resolved = resolve(key);
54 if (_project && resolved.path && _project->exists(*resolved.path)) return true;
55 return _backend.exists(resolved);
56 }
57
62 FileKey resolve(const FileKey& key) const {
63 FileKey out = key;
64 if (!out.fdid && out.path) out.fdid = _listfile.pathToFdid(*out.path);
65 else if (!out.path && out.fdid) out.path = _listfile.fdidToPath(*out.fdid);
66 return out;
67 }
68
76 Result<FileDataID> addFile(std::string_view path, std::span<const std::byte> content) {
77 if (!_project)
78 return makeError(ErrorCode::NotSupported, "no project directory is set; there is nowhere to add files");
79
80 if (auto written = _project->write(path, content); !written) return std::unexpected(written.error());
81
82 if constexpr (Backend::kind() == StorageKind::Mpq) return FileDataID{0};
83 else {
84 // Overwriting an already-known file keeps its id; only new paths allocate.
85 if (auto existing = _listfile.pathToFdid(path)) return *existing;
86 return _listfile.registerPath(path);
87 }
88 }
89
91 static constexpr StorageKind kind() { return Backend::kind(); }
92
94 Backend& backend() { return _backend; }
95
97 Listfile& listfile() { return _listfile; }
98
100 ProjectDirectory* project() { return _project ? &*_project : nullptr; }
101
102 private:
103 Backend _backend;
104 Listfile _listfile;
105 std::optional<ProjectDirectory> _project;
106 };
107}
The owning byte buffer file contents are read into.
Result< FileDataID > addFile(std::string_view path, std::span< const std::byte > content)
Add (or overwrite) a file in the project directory.
bool exists(const FileKey &key)
Whether a file is reachable in the overlay or the storage.
Result< FileBuffer > readFile(const FileKey &key)
Read a file by key.
ClientFileSystem(Backend backend, Listfile listfile={}, std::optional< ProjectDirectory > project=std::nullopt)
Compose from ready components (backends are open by construction).
static constexpr StorageKind kind()
FileKey resolve(const FileKey &key) const
Fill the missing half of a key (path or FileDataID) from the listfile, best-effort.
A local directory acting as the ultimate patch: files here override every client archive,...
The error-handling vocabulary: ErrorCode, Error and the Result<T> alias every fallible wowlib operati...
File identity types: the strong FileDataID and the FileKey a read request travels as.
The pluggable listfile-provider contract and the no-database provider for clients that need none.
std::expected< T, Error > Result
Every fallible wowlib operation returns Result<T>; bindings translate the error branch into a target-...
Definition error.hpp:100
std::unexpected< Error > makeError(ErrorCode code, std::string message, std::uint32_t nativeError=0)
Shorthand for constructing the error branch of a Result.
Definition error.hpp:107
@ NotSupported
Operation not supported by this backend/provider.
Definition error.hpp:32
@ Mpq
Pre-WoD retail clients (< 6.0), StormLib.
The project-directory overlay: a local directory acting as the ultimate patch over any client storage...
The storage-backend concept ClientFileSystem composes over.
std::optional< FileDataID > fdid
The numeric identifier, if known.
Definition file_key.hpp:28
std::optional< std::string > path
The canonical client-internal path, if known.
Definition file_key.hpp:31