Skip to content

Commit 9afdf3d

Browse files
feat(vpkpp): add an iterator over entries in a particular directory
1 parent dac4a1c commit 9afdf3d

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

include/vpkpp/PackFile.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ class PackFile {
154154
/// Run a callback for each entry in the pack file
155155
void runForAllEntries(const EntryCallback& operation, bool includeUnbaked = true) const;
156156

157+
/// Run a callback for each entry in the pack file under the parent directory
158+
void runForAllEntries(const std::string& parentDir, const EntryCallback& operation, bool recursive = true, bool includeUnbaked = true) const;
159+
157160
/// /home/user/pak01_dir.vpk
158161
[[nodiscard]] std::string_view getFilepath() const;
159162

@@ -186,6 +189,8 @@ class PackFile {
186189

187190
void runForAllEntriesInternal(const std::function<void(const std::string&, Entry&)>& operation, bool includeUnbaked = true);
188191

192+
void runForAllEntriesInternal(const std::string& parentDir, const std::function<void(const std::string&, Entry&)>& operation, bool recursive = true, bool includeUnbaked = true);
193+
189194
[[nodiscard]] std::vector<std::string> verifyEntryChecksumsUsingCRC32() const;
190195

191196
virtual void addEntryInternal(Entry& entry, const std::string& path, std::vector<std::byte>& buffer, EntryOptions options) = 0;

src/vpkpp/PackFile.cpp

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ bool PackFile::extractAll(const std::string& outputDir, bool createUnderPackFile
413413
}
414414
bool noneFailed = true;
415415
this->runForAllEntries([this, &outputDirPath, &noneFailed](const std::string& path, const Entry& entry) {
416-
std::string entryPath = path;
416+
std::string entryPath = path; // NOLINT(*-unnecessary-copy-initialization)
417417
#ifdef _WIN32
418418
::fixFilePathForWindows(entryPath);
419419
#endif
@@ -520,6 +520,34 @@ void PackFile::runForAllEntries(const EntryCallback& operation, bool includeUnba
520520
}
521521
}
522522

523+
void PackFile::runForAllEntries(const std::string& parentDir, const EntryCallback& operation, bool recursive, bool includeUnbaked) const {
524+
auto dir = this->cleanEntryPath(parentDir) + '/';
525+
526+
std::string key;
527+
for (auto [entry, end] = this->entries.equal_prefix_range(dir); entry != end; ++entry) {
528+
entry.key(key);
529+
if (!recursive) {
530+
auto keyView = std::string_view{key}.substr(dir.length());
531+
if (std::find(keyView.begin(), keyView.end(), '/') != keyView.end()) {
532+
continue;
533+
}
534+
}
535+
operation(key, entry.value());
536+
}
537+
if (includeUnbaked) {
538+
for (auto [entry, end] = this->unbakedEntries.equal_prefix_range(dir); entry != end; ++entry) {
539+
entry.key(key);
540+
if (!recursive) {
541+
auto keyView = std::string_view{key}.substr(dir.length());
542+
if (std::find(keyView.begin(), keyView.end(), '/') != keyView.end()) {
543+
continue;
544+
}
545+
}
546+
operation(key, entry.value());
547+
}
548+
}
549+
}
550+
523551
void PackFile::runForAllEntriesInternal(const std::function<void(const std::string&, Entry&)>& operation, bool includeUnbaked) {
524552
std::string key;
525553
for (auto entry = this->entries.begin(); entry != this->entries.end(); ++entry) {
@@ -534,6 +562,34 @@ void PackFile::runForAllEntriesInternal(const std::function<void(const std::stri
534562
}
535563
}
536564

565+
void PackFile::runForAllEntriesInternal(const std::string& parentDir, const std::function<void(const std::string&, Entry&)>& operation, bool recursive, bool includeUnbaked) {
566+
auto dir = this->cleanEntryPath(parentDir) + '/';
567+
568+
std::string key;
569+
for (auto [entry, end] = this->entries.equal_prefix_range(dir); entry != end; ++entry) {
570+
entry.key(key);
571+
if (!recursive) {
572+
auto keyView = std::string_view{key}.substr(dir.length());
573+
if (std::find(keyView.begin(), keyView.end(), '/') != keyView.end()) {
574+
continue;
575+
}
576+
}
577+
operation(key, entry.value());
578+
}
579+
if (includeUnbaked) {
580+
for (auto [entry, end] = this->unbakedEntries.equal_prefix_range(dir); entry != end; ++entry) {
581+
entry.key(key);
582+
if (!recursive) {
583+
auto keyView = std::string_view{key}.substr(dir.length());
584+
if (std::find(keyView.begin(), keyView.end(), '/') != keyView.end()) {
585+
continue;
586+
}
587+
}
588+
operation(key, entry.value());
589+
}
590+
}
591+
}
592+
537593
std::string_view PackFile::getFilepath() const {
538594
return this->fullFilePath;
539595
}

0 commit comments

Comments
 (0)