Skip to content

Commit

Permalink
fix(vpkpp): add rename entry/directory methods
Browse files Browse the repository at this point in the history
  • Loading branch information
craftablescience committed Aug 20, 2024
1 parent 8d6aaa1 commit ed5c5cb
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/vpkpp/PackFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ class PackFile {
/// Add a new entry from a buffer
void addEntry(const std::string& path, const std::byte* buffer, uint64_t bufferLen, EntryOptions options_);

/// Rename an existing entry
virtual bool renameEntry(const std::string& oldPath_, const std::string& newPath_); // NOLINT(*-use-nodiscard)

/// Rename an existing directory
virtual bool renameDirectory(const std::string& oldDir_, const std::string& newDir_); // NOLINT(*-use-nodiscard)

/// Remove an entry
virtual bool removeEntry(const std::string& path_);

Expand Down
4 changes: 4 additions & 0 deletions lang/c/include/vpkppc/PackFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ SOURCEPP_API void vpkpp_add_entry_from_mem(vpkpp_pack_file_handle_t handle, cons

SOURCEPP_API void vpkpp_add_entry_from_mem_with_options(vpkpp_pack_file_handle_t handle, const char* path, const unsigned char* buffer, size_t bufferLen, vpkpp_entry_options_t options);

SOURCEPP_API int vpkpp_rename_entry(vpkpp_pack_file_handle_t handle, const char* oldPath, const char* newPath);

SOURCEPP_API int vpkpp_rename_directory(vpkpp_pack_file_handle_t handle, const char* oldDir, const char* newDir);

SOURCEPP_API int vpkpp_remove_entry(vpkpp_pack_file_handle_t handle, const char* path);

SOURCEPP_API int vpkpp_remove_directory(vpkpp_pack_file_handle_t handle, const char* dirName);
Expand Down
16 changes: 16 additions & 0 deletions lang/c/src/vpkppc/PackFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,22 @@ SOURCEPP_API void vpkpp_add_entry_from_mem_with_options(vpkpp_pack_file_handle_t
Convert::packFile(handle)->addEntry(path, reinterpret_cast<const std::byte*>(buffer), bufferLen, Convert::optionsFromC(options));
}

SOURCEPP_API int vpkpp_rename_entry(vpkpp_pack_file_handle_t handle, const char* oldPath, const char* newPath) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
SOURCEPP_EARLY_RETURN_VAL(oldPath, false);
SOURCEPP_EARLY_RETURN_VAL(newPath, false);

return Convert::packFile(handle)->renameEntry(oldPath, newPath);
}

SOURCEPP_API int vpkpp_rename_directory(vpkpp_pack_file_handle_t handle, const char* oldDir, const char* newDir) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
SOURCEPP_EARLY_RETURN_VAL(oldDir, false);
SOURCEPP_EARLY_RETURN_VAL(newDir, false);

return Convert::packFile(handle)->renameEntry(oldDir, newDir);
}

SOURCEPP_API int vpkpp_remove_entry(vpkpp_pack_file_handle_t handle, const char* path) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
SOURCEPP_EARLY_RETURN_VAL(path, false);
Expand Down
22 changes: 22 additions & 0 deletions lang/csharp/src/vpkpp/PackFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ internal static unsafe partial class Extern
[DllImport("vpkppc")]
public static extern void vpkpp_add_entry_from_mem(void* handle, [MarshalAs(UnmanagedType.LPStr)] string path, byte* buffer, ulong bufferLen);

[DllImport("vpkppc")]
public static extern int vpkpp_rename_entry(void* handle, [MarshalAs(UnmanagedType.LPStr)] string oldPath, [MarshalAs(UnmanagedType.LPStr)] string newPath);

[DllImport("vpkppc")]
public static extern int vpkpp_rename_directory(void* handle, [MarshalAs(UnmanagedType.LPStr)] string oldDir, [MarshalAs(UnmanagedType.LPStr)] string newDir);

[DllImport("vpkppc")]
public static extern int vpkpp_remove_entry(void* handle, [MarshalAs(UnmanagedType.LPStr)] string path);

Expand Down Expand Up @@ -329,6 +335,22 @@ public void AddEntry(string path, IEnumerable<byte> buffer)
}
}

public bool RenameEntry(string oldPath, string newPath)
{
unsafe
{
return Convert.ToBoolean(Extern.vpkpp_rename_entry(Handle, oldPath, newPath));
}
}

public bool RenameDirectory(string oldDir, string newDir)
{
unsafe
{
return Convert.ToBoolean(Extern.vpkpp_rename_directory(Handle, oldDir, newDir));
}
}

public bool RemoveEntry(string path)
{
unsafe
Expand Down
48 changes: 48 additions & 0 deletions src/vpkpp/PackFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,54 @@ void PackFile::addEntry(const std::string& path, const std::byte* buffer, uint64
this->addEntry(path, std::move(data), options_);
}

bool PackFile::renameEntry(const std::string& oldPath_, const std::string& newPath_) {
auto oldPath = this->cleanEntryPath(oldPath_);
auto newPath = this->cleanEntryPath(newPath_);
if (this->entries.count(oldPath)) {
// Currently there is no pack file format that relies on file path to access data.
// If there ever is one, we're in trouble! (Well, no, just override the method.)
auto entry = this->entries.at(oldPath);
this->entries.erase(oldPath);
this->entries.emplace(newPath, entry);
return true;
} else if (this->unbakedEntries.count(oldPath)) {
auto entry = this->unbakedEntries.at(oldPath);
this->unbakedEntries.erase(oldPath);
this->unbakedEntries.emplace(newPath, entry);
return true;
}
return false;
}

bool PackFile::renameDirectory(const std::string& oldDir_, const std::string& newDir_) {
auto oldDir = this->cleanEntryPath(oldDir_) + '/';
auto newDir = this->cleanEntryPath(newDir_) + '/';

std::vector<std::string> entryPaths;
std::vector<std::string> unbakedEntryPaths;
this->runForAllEntries([&oldDir, &entryPaths, &unbakedEntryPaths](const std::string& path, const Entry& entry) {
if (path.starts_with(oldDir)) {
if (entry.unbaked) {
unbakedEntryPaths.push_back(path);
} else {
entryPaths.push_back(path);
}
}
});

for (const auto& entryPath : entryPaths) {
auto entry = this->entries.at(entryPath);
this->entries.erase(entryPath);
this->entries.emplace(newDir + entryPath.substr(oldDir.length()), entry);
}
for (const auto& entryPath : unbakedEntryPaths) {
auto entry = this->unbakedEntries.at(entryPath);
this->unbakedEntries.erase(entryPath);
this->unbakedEntries.emplace(newDir + entryPath.substr(oldDir.length()), entry);
}
return !entryPaths.empty() || !unbakedEntryPaths.empty();
}

bool PackFile::removeEntry(const std::string& path_) {
if (this->isReadOnly()) {
return false;
Expand Down

0 comments on commit ed5c5cb

Please sign in to comment.