diff --git a/.gitmodules b/.gitmodules
index b5170937d..1ec7d94fc 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -13,3 +13,6 @@
[submodule "ext/minizip-ng"]
path = ext/minizip-ng
url = https://github.com/zlib-ng/minizip-ng
+[submodule "ext/hat-trie"]
+ path = ext/hat-trie
+ url = https://github.com/Tessil/hat-trie
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9f81fd546..1506e0dcf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -87,16 +87,16 @@ endif()
# Add libraries
-add_sourcepp_library(bsppp NO_TEST)
-add_sourcepp_library(dmxpp)
-add_sourcepp_library(fgdpp)
-add_sourcepp_library(gamepp)
-add_sourcepp_library(kvpp)
-add_sourcepp_library(mdlpp)
-add_sourcepp_library(steampp C)
-add_sourcepp_library(vicepp C CSHARP)
-add_sourcepp_library(vpkpp C CSHARP NO_TEST)
-add_sourcepp_library(vtfpp)
+add_sourcepp_library(bsppp NO_TEST) # sourcepp::bsppp
+add_sourcepp_library(dmxpp) # sourcepp::dmxpp
+add_sourcepp_library(fgdpp) # sourcepp::fgdpp
+add_sourcepp_library(gamepp) # sourcepp::gamepp
+add_sourcepp_library(kvpp) # sourcepp::kvpp
+add_sourcepp_library(mdlpp) # sourcepp::mdlpp
+add_sourcepp_library(steampp C) # sourcepp::steampp
+add_sourcepp_library(vicepp C CSHARP) # sourcepp::vicepp
+add_sourcepp_library(vpkpp C CSHARP NO_TEST) # sourcepp::vpkpp
+add_sourcepp_library(vtfpp) # sourcepp::vtfpp
# Tests, part 2
diff --git a/README.md b/README.md
index 7c436942c..df643bc54 100644
--- a/README.md
+++ b/README.md
@@ -123,7 +123,6 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
FPX v10 (Tactical Intervention)
GCF v6
GMA v1-3 (Garry's Mod)
- GRP (Build Engine)
PAK (Quake, WON Half-Life)
PCK v1-2 (Godot Engine)
VPK v1-2
diff --git a/cmake/AddPrettyParser.cmake b/cmake/AddPrettyParser.cmake
index 2ff7ade9a..d8a081f6e 100644
--- a/cmake/AddPrettyParser.cmake
+++ b/cmake/AddPrettyParser.cmake
@@ -1,21 +1,24 @@
# Add a new parser library
function(add_pretty_parser TARGET)
- cmake_parse_arguments(PARSE_ARGV 1 OPTIONS "C" "" "DEPS;PRECOMPILED_HEADERS;SOURCES")
+ cmake_parse_arguments(PARSE_ARGV 1 OPTIONS "C" "" "DEPS;DEPS_INTERFACE;PRECOMPILED_HEADERS;SOURCES")
if(OPTIONS_C)
add_library(${TARGET}c SHARED ${${PROJECT_NAME}c_SOURCES} ${OPTIONS_PRECOMPILED_HEADERS} ${OPTIONS_SOURCES})
+ add_library(sourcepp::${TARGET}c ALIAS ${TARGET}c)
set_target_properties(${TARGET}c PROPERTIES PREFIX "")
target_link_libraries(${TARGET}c PRIVATE ${TARGET})
target_include_directories(${TARGET}c PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include")
set(TARGET "${TARGET}c")
else()
add_library(${TARGET} STATIC ${OPTIONS_PRECOMPILED_HEADERS} ${OPTIONS_SOURCES})
+ add_library(sourcepp::${TARGET} ALIAS ${TARGET})
endif()
if(NOT ("PRECOMPILED_HEADERS" IN_LIST OPTIONS_UNPARSED_ARGUMENTS))
target_precompile_headers(${TARGET} PUBLIC ${OPTIONS_HEADERS})
endif()
target_link_libraries(${TARGET} PUBLIC ${PROJECT_NAME})
target_link_libraries(${TARGET} PRIVATE ${OPTIONS_DEPS})
+ target_link_libraries(${TARGET} INTERFACE ${OPTIONS_DEPS_INTERFACE})
# Define DEBUG macro
target_compile_definitions(${TARGET} PRIVATE "$<$:DEBUG>")
diff --git a/ext/_ext.cmake b/ext/_ext.cmake
index 91cd9d746..22f41da34 100644
--- a/ext/_ext.cmake
+++ b/ext/_ext.cmake
@@ -21,6 +21,12 @@ if(NOT TARGET cryptopp::cryptopp)
endif()
+# hat-trie
+if(NOT TARGET tsl::hat_trie)
+ add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/hat-trie")
+endif()
+
+
# ice
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/ice")
diff --git a/ext/hat-trie b/ext/hat-trie
new file mode 160000
index 000000000..906e6abd1
--- /dev/null
+++ b/ext/hat-trie
@@ -0,0 +1 @@
+Subproject commit 906e6abd1e7063f1dacd3a6b270aa654b525eb0a
diff --git a/ext/miniz b/ext/miniz
index 8573fd7cd..1ff82be7d 160000
--- a/ext/miniz
+++ b/ext/miniz
@@ -1 +1 @@
-Subproject commit 8573fd7cd6f49b262a0ccc447f3c6acfc415e556
+Subproject commit 1ff82be7d67f5c2f8b5497f538eea247861e0717
diff --git a/include/sourcepp/BitwiseEnumClass.h b/include/sourcepp/BitwiseEnumClass.h
new file mode 100644
index 000000000..e11eadc56
--- /dev/null
+++ b/include/sourcepp/BitwiseEnumClass.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include
+
+#define SOURCEPP_SETUP_BITWISE_ENUM_CLASS(Enum) \
+ inline constexpr Enum operator|(Enum lhs, Enum rhs) { \
+ return static_cast( \
+ static_cast>(lhs) | \
+ static_cast>(rhs)); \
+ } \
+ inline constexpr Enum operator&(Enum lhs, Enum rhs) { \
+ return static_cast( \
+ static_cast>(lhs) & \
+ static_cast>(rhs)); \
+ } \
+ inline constexpr Enum operator^(Enum lhs, Enum rhs) { \
+ return static_cast( \
+ static_cast>(lhs) ^ \
+ static_cast>(rhs)); \
+ } \
+ inline constexpr Enum operator~(Enum e) { \
+ return static_cast( \
+ ~static_cast>(e)); \
+ } \
+ inline Enum& operator|=(Enum& lhs, Enum rhs) { \
+ return lhs = static_cast( \
+ static_cast>(lhs) | \
+ static_cast>(rhs)); \
+ } \
+ inline Enum& operator&=(Enum& lhs, Enum rhs) { \
+ return lhs = static_cast( \
+ static_cast>(lhs) & \
+ static_cast>(rhs)); \
+ } \
+ inline Enum& operator^=(Enum& lhs, Enum rhs) { \
+ return lhs = static_cast( \
+ static_cast>(lhs) ^ \
+ static_cast>(rhs)); \
+ }
diff --git a/include/sourcepp/String.h b/include/sourcepp/String.h
index a9fc5f93c..edf7b570b 100644
--- a/include/sourcepp/String.h
+++ b/include/sourcepp/String.h
@@ -52,7 +52,7 @@ void toUpper(std::string& input);
[[nodiscard]] std::string generateUUIDv4();
-[[nodiscard]] std::string padNumber(int number, int width, char pad = '0');
+[[nodiscard]] std::string padNumber(int64_t number, int width, char pad = '0');
void normalizeSlashes(std::string& path, bool stripSlashPrefix = false, bool stripSlashSuffix = true);
diff --git a/include/vpkpp/Attribute.h b/include/vpkpp/Attribute.h
index 255a1ba15..09579bb6e 100644
--- a/include/vpkpp/Attribute.h
+++ b/include/vpkpp/Attribute.h
@@ -1,15 +1,17 @@
#pragma once
+#include
+
namespace vpkpp {
-enum class Attribute : int {
- //PATH, // Not included because its implied
- LENGTH = 0,
- VPK_PRELOADED_DATA_LENGTH,
- ARCHIVE_INDEX,
- CRC32,
- PCK_MD5,
- ATTRIBUTE_COUNT,
+enum class Attribute {
+ NONE = 0,
+ ARCHIVE_INDEX = 1 << 0,
+ LENGTH = 1 << 1,
+ CRC32 = 1 << 2,
+ PCK_MD5 = 1 << 3,
+ VPK_PRELOADED_DATA = 1 << 4,
};
+SOURCEPP_SETUP_BITWISE_ENUM_CLASS(Attribute)
} // namespace vpkpp
diff --git a/include/vpkpp/Entry.h b/include/vpkpp/Entry.h
index e7bb24be1..cc0190eb7 100644
--- a/include/vpkpp/Entry.h
+++ b/include/vpkpp/Entry.h
@@ -1,6 +1,5 @@
#pragma once
-#include
#include
#include
#include
@@ -16,44 +15,33 @@ class Entry {
friend class PackFile;
public:
- /// Path to this entry (e.g. "materials/cable.vmt")
- std::string path;
/// Format-specific flags (PCK: File flags, VPK: Internal parser state)
uint32_t flags = 0;
+
+ /// Which external archive this entry is in.
+ /// If this file format does not support external archives, this will always be 0
+ uint32_t archiveIndex = 0;
+
/// Length in bytes (in formats with compression, this is the uncompressed length)
uint64_t length = 0;
- /// Offset, format-specific meaning - may be unused
- uint64_t offset = 0;
- /// If the format supports compression, this is the compressed length
+
+ /// If the format supports compression, this is the compressed length.
/// If compression is not supported or unused, this will remain 0
uint64_t compressedLength = 0;
- /// Which external archive this entry is in
- /// If this file format does not support external archives, this will always be 0
- uint16_t archiveIndex = 0;
+
+ /// Offset, format-specific meaning - 0 if unused, or if the offset genuinely is 0
+ uint64_t offset = 0;
+
+ /// Format-specific (PCK: MD5 hash, VPK: Preloaded data)
+ std::vector extraData;
+
/// CRC32 checksum - 0 if unused.
/// Note that for GCF, this is actually an index into a checksum array and NOT a checksum
uint32_t crc32 = 0;
+
/// Used to check if entry is saved to disk
bool unbaked = false;
- /// PCK - Each file has a 16-byte MD5 hash
- std::array pck_md5{};
-
- /// VPK - Preloaded data
- std::vector vpk_preloadedData;
-
- /// Returns the parent directory's path (e.g. "materials/cable.vmt" -> "materials")
- [[nodiscard]] std::string getParentPath() const;
-
- /// Returns the filename (e.g. "materials/cable.vmt" -> "cable.vmt")
- [[nodiscard]] std::string getFilename() const;
-
- /// Returns the file stem (e.g. "materials/cable.vmt" -> "cable")
- [[nodiscard]] std::string getStem() const;
-
- /// Returns the file extension without a period (e.g. "materials/cable.vmt" -> "vmt")
- [[nodiscard]] std::string getExtension() const;
-
private:
/// The data attached to the unbaked entry, or the path to the file containing the unbaked entry's data
std::variant> unbakedData;
diff --git a/include/vpkpp/PackFile.h b/include/vpkpp/PackFile.h
index 688843e7d..f0857cfc7 100644
--- a/include/vpkpp/PackFile.h
+++ b/include/vpkpp/PackFile.h
@@ -10,6 +10,7 @@
#include
#include
+#include
#include "Attribute.h"
#include "Entry.h"
@@ -21,24 +22,28 @@ namespace vpkpp {
// Executable extensions - mostly just for Godot exports
constexpr std::string_view EXECUTABLE_EXTENSION0 = ".exe"; // - Windows
constexpr std::string_view EXECUTABLE_EXTENSION1 = ".bin"; // - Linux + Godot 3 and below (and Generic)
-constexpr std::string_view EXECUTABLE_EXTENSION2 = ".x86"; // | Godot 4 (32-bit)
-constexpr std::string_view EXECUTABLE_EXTENSION3 = ".x86_32"; // | Godot 4 (32-bit)
-constexpr std::string_view EXECUTABLE_EXTENSION4 = ".x86_64"; // | Godot 4 (64-bit)
+constexpr std::string_view EXECUTABLE_EXTENSION2 = ".x86_64"; // | Godot 4 (64-bit)
class PackFile {
public:
+ /// Accepts the entry's path and metadata
+ using EntryCallback = std::function;
+
+ /// Accepts the entry's path and metadata
+ using EntryPredicate = std::function;
+
+ using EntryTrie = tsl::htrie_map;
+
PackFile(const PackFile& other) = delete;
PackFile& operator=(const PackFile& other) = delete;
+
PackFile(PackFile&& other) noexcept = default;
PackFile& operator=(PackFile&& other) noexcept = default;
virtual ~PackFile() = default;
- // Accepts the entry parent directory and the entry metadata
- using Callback = std::function;
-
/// Open a generic pack file. The parser is selected based on the file extension
- [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
/// Get the file type of the pack file
[[nodiscard]] PackFileType getType() const;
@@ -51,7 +56,7 @@ class PackFile {
return false;
}
- /// Verify the checksums of each file, if a file fails the check its filename will be added to the vector
+ /// Verify the checksums of each file, if a file fails the check its path will be added to the vector
/// If there is no checksum ability in the format, it will return an empty vector
[[nodiscard]] virtual std::vector verifyEntryChecksums() const;
@@ -75,57 +80,69 @@ class PackFile {
}
/// Check if an entry exists given the file path
- [[nodiscard]] bool hasEntry(const std::string& filename_, bool includeUnbaked = true) const;
+ [[nodiscard]] bool hasEntry(const std::string& path, bool includeUnbaked = true) const;
/// Try to find an entry given the file path
- [[nodiscard]] std::optional findEntry(const std::string& filename_, bool includeUnbaked = true) const;
+ [[nodiscard]] std::optional findEntry(const std::string& path_, bool includeUnbaked = true) const;
/// Try to read the entry's data to a bytebuffer
- [[nodiscard]] virtual std::optional> readEntry(const Entry& entry) const = 0;
+ [[nodiscard]] virtual std::optional> readEntry(const std::string& path_) const = 0;
/// Try to read the entry's data to a string
- [[nodiscard]] std::optional readEntryText(const Entry& entry) const;
+ [[nodiscard]] std::optional readEntryText(const std::string& path) const;
[[nodiscard]] virtual constexpr bool isReadOnly() const noexcept {
return false;
}
/// Add a new entry from a file path - the first parameter is the path in the PackFile, the second is the path on disk
- void addEntry(const std::string& filename_, const std::string& pathToFile, EntryOptions options_);
+ void addEntry(const std::string& entryPath, const std::string& filepath, EntryOptions options_);
/// Add a new entry from a buffer
- void addEntry(const std::string& filename_, std::vector&& buffer, EntryOptions options_);
+ void addEntry(const std::string& path, std::vector&& buffer, EntryOptions options_);
/// Add a new entry from a buffer
- void addEntry(const std::string& filename_, const std::byte* buffer, uint64_t bufferLen, EntryOptions options_);
+ 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& filename_);
+ virtual bool removeEntry(const std::string& path_);
+
+ /// Remove a directory
+ virtual std::size_t removeDirectory(const std::string& dirName_);
/// If output folder is unspecified, it will overwrite the original
- virtual bool bake(const std::string& outputDir_ /*= ""*/, const Callback& callback /*= nullptr*/) = 0;
+ virtual bool bake(const std::string& outputDir_ /*= ""*/, const EntryCallback& callback /*= nullptr*/) = 0;
/// Extract the given entry to disk at the given file path
- bool extractEntry(const Entry& entry, const std::string& filePath) const; // NOLINT(*-use-nodiscard)
+ bool extractEntry(const std::string& entryPath, const std::string& filepath) const; // NOLINT(*-use-nodiscard)
/// Extract the given directory to disk under the given output directory
- bool extractDirectory(const std::string& dir, const std::string& outputDir) const; // NOLINT(*-use-nodiscard)
+ bool extractDirectory(const std::string& dir_, const std::string& outputDir) const; // NOLINT(*-use-nodiscard)
/// Extract the contents of the pack file to disk at the given directory
bool extractAll(const std::string& outputDir, bool createUnderPackFileDir = true) const; // NOLINT(*-use-nodiscard)
/// Extract the contents of the pack file to disk at the given directory - only entries which match the predicate are extracted
- bool extractAll(const std::string& outputDir, const std::function& predicate) const; // NOLINT(*-use-nodiscard)
+ bool extractAll(const std::string& outputDir, const EntryPredicate& predicate, bool stripSharedDirs = true) const; // NOLINT(*-use-nodiscard)
/// Get entries saved to disk
- [[nodiscard]] const std::unordered_map>& getBakedEntries() const;
+ [[nodiscard]] const EntryTrie& getBakedEntries() const;
/// Get entries that have been added but not yet baked
- [[nodiscard]] const std::unordered_map>& getUnbakedEntries() const;
+ [[nodiscard]] const EntryTrie& getUnbakedEntries() const;
/// Get the number of entries in the pack file
[[nodiscard]] std::size_t getEntryCount(bool includeUnbaked = true) const;
+ /// Run a callback for each entry in the pack file
+ void runForAllEntries(const EntryCallback& operation, bool includeUnbaked = true) const;
+
/// /home/user/pak01_dir.vpk
[[nodiscard]] std::string_view getFilepath() const;
@@ -146,12 +163,12 @@ class PackFile {
/// Returns a list of supported entry attributes
/// Mostly for GUI programs that show entries and their metadata in a table ;)
- [[nodiscard]] virtual std::vector getSupportedEntryAttributes() const;
+ [[nodiscard]] virtual Attribute getSupportedEntryAttributes() const;
[[nodiscard]] virtual explicit operator std::string() const;
/// On Windows, some characters and file names are invalid - this escapes the given entry path
- [[nodiscard]] static std::string escapeEntryPath(const std::string& path);
+ [[nodiscard]] static std::string escapeEntryPathForWrite(const std::string& path);
/// Returns a list of supported extensions, e.g. {".vpk", ".bsp"}
[[nodiscard]] static std::vector getSupportedFileTypes();
@@ -159,9 +176,11 @@ class PackFile {
protected:
PackFile(std::string fullFilePath_, PackFileOptions options_);
+ void runForAllEntries(const std::function& operation, bool includeUnbaked = true);
+
[[nodiscard]] std::vector verifyEntryChecksumsUsingCRC32() const;
- virtual Entry& addEntryInternal(Entry& entry, const std::string& filename_, std::vector& buffer, EntryOptions options_) = 0;
+ virtual void addEntryInternal(Entry& entry, const std::string& path, std::vector& buffer, EntryOptions options_) = 0;
[[nodiscard]] std::string getBakeOutputDir(const std::string& outputDir) const;
@@ -169,25 +188,21 @@ class PackFile {
void setFullFilePath(const std::string& outputDir);
- [[nodiscard]] static std::pair splitFilenameAndParentDir(const std::string& filename);
+ [[nodiscard]] std::string cleanEntryPath(const std::string& path) const;
[[nodiscard]] static Entry createNewEntry();
- [[nodiscard]] static const std::variant>& getEntryUnbakedData(const Entry& entry);
-
- [[nodiscard]] static bool isEntryUnbakedUsingByteBuffer(const Entry& entry);
-
- [[nodiscard]] std::optional> readUnbakedEntry(const Entry& entry) const;
+ [[nodiscard]] static std::optional> readUnbakedEntry(const Entry& entry);
std::string fullFilePath;
PackFileType type = PackFileType::UNKNOWN;
PackFileOptions options;
- std::unordered_map> entries;
- std::unordered_map> unbakedEntries;
+ EntryTrie entries;
+ EntryTrie unbakedEntries;
- using FactoryFunction = std::function(const std::string& path, PackFileOptions options, const Callback& callback)>;
+ using FactoryFunction = std::function(const std::string& path, PackFileOptions options, const EntryCallback& callback)>;
static std::unordered_map>& getOpenExtensionRegistry();
@@ -203,11 +218,11 @@ class PackFileReadOnly : public PackFile {
[[nodiscard]] explicit operator std::string() const override;
protected:
- PackFileReadOnly(std::string fullFilePath_, PackFileOptions options_);
+ PackFileReadOnly([[maybe_unused]] [[maybe_unused]] std::string fullFilePath_, PackFileOptions options_);
- Entry& addEntryInternal(Entry& entry, const std::string& filename_, std::vector& buffer, EntryOptions options_) final;
+ void addEntryInternal(Entry& entry, const std::string& path, std::vector& buffer, EntryOptions options_) final;
- bool bake(const std::string& outputDir_ /*= ""*/, const Callback& callback /*= nullptr*/) final;
+ bool bake(const std::string& outputDir_ /*= ""*/, const EntryCallback& callback /*= nullptr*/) final;
};
} // namespace vpkpp
@@ -222,6 +237,4 @@ class PackFileReadOnly : public PackFile {
#define VPKPP_REGISTER_PACKFILE_OPEN_EXECUTABLE(function) \
static inline const FactoryFunction& VPKPP_HELPER_UNIQUE_NAME(packFileOpenExecutable0TypeFactoryFunction) = PackFile::registerOpenExtensionForTypeFactory(vpkpp::EXECUTABLE_EXTENSION0, function); \
static inline const FactoryFunction& VPKPP_HELPER_UNIQUE_NAME(packFileOpenExecutable1TypeFactoryFunction) = PackFile::registerOpenExtensionForTypeFactory(vpkpp::EXECUTABLE_EXTENSION1, function); \
- static inline const FactoryFunction& VPKPP_HELPER_UNIQUE_NAME(packFileOpenExecutable2TypeFactoryFunction) = PackFile::registerOpenExtensionForTypeFactory(vpkpp::EXECUTABLE_EXTENSION2, function); \
- static inline const FactoryFunction& VPKPP_HELPER_UNIQUE_NAME(packFileOpenExecutable3TypeFactoryFunction) = PackFile::registerOpenExtensionForTypeFactory(vpkpp::EXECUTABLE_EXTENSION3, function); \
- static inline const FactoryFunction& VPKPP_HELPER_UNIQUE_NAME(packFileOpenExecutable4TypeFactoryFunction) = PackFile::registerOpenExtensionForTypeFactory(vpkpp::EXECUTABLE_EXTENSION4, function);
+ static inline const FactoryFunction& VPKPP_HELPER_UNIQUE_NAME(packFileOpenExecutable2TypeFactoryFunction) = PackFile::registerOpenExtensionForTypeFactory(vpkpp::EXECUTABLE_EXTENSION2, function)
diff --git a/include/vpkpp/PackFileType.h b/include/vpkpp/PackFileType.h
index 9037e92b0..2d9454926 100644
--- a/include/vpkpp/PackFileType.h
+++ b/include/vpkpp/PackFileType.h
@@ -8,7 +8,6 @@ enum class PackFileType {
FPX,
GCF,
GMA,
- GRP,
PAK,
PCK,
VPK,
diff --git a/include/vpkpp/format/BSP.h b/include/vpkpp/format/BSP.h
index 90d8f1802..2781c7694 100644
--- a/include/vpkpp/format/BSP.h
+++ b/include/vpkpp/format/BSP.h
@@ -14,13 +14,13 @@ constexpr std::string_view BSP_EXTENSION = ".bsp";
class BSP : public ZIP, private bsppp::BSP {
public:
/// Open a BSP file
- [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
[[nodiscard]] constexpr bool isCaseSensitive() const noexcept override {
return false;
}
- bool bake(const std::string& outputDir_ /*= ""*/, const Callback& callback /*= nullptr*/) override;
+ bool bake(const std::string& outputDir_ /*= ""*/, const EntryCallback& callback /*= nullptr*/) override;
[[nodiscard]] explicit operator std::string() const override;
diff --git a/include/vpkpp/format/FPX.h b/include/vpkpp/format/FPX.h
index 8f611b7be..6a639de2a 100644
--- a/include/vpkpp/format/FPX.h
+++ b/include/vpkpp/format/FPX.h
@@ -11,12 +11,12 @@ constexpr std::string_view FPX_EXTENSION = ".fpx";
class FPX : public VPK {
public:
/// Open a directory VPK file
- [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
protected:
FPX(const std::string& fullFilePath_, PackFileOptions options_);
- [[nodiscard]] static std::unique_ptr openInternal(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr openInternal(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
private:
using VPK::generateKeyPairFiles;
diff --git a/include/vpkpp/format/GCF.h b/include/vpkpp/format/GCF.h
index 4874d43ed..666bb41d5 100644
--- a/include/vpkpp/format/GCF.h
+++ b/include/vpkpp/format/GCF.h
@@ -110,7 +110,7 @@ class GCF : public PackFileReadOnly {
#pragma pack(pop)
public:
- [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
[[nodiscard]] constexpr bool hasEntryChecksums() const override {
return true;
@@ -118,9 +118,9 @@ class GCF : public PackFileReadOnly {
[[nodiscard]] std::vector verifyEntryChecksums() const override;
- [[nodiscard]] std::optional> readEntry(const Entry& entry) const override;
+ [[nodiscard]] std::optional> readEntry(const std::string& path_) const override;
- [[nodiscard]] std::vector getSupportedEntryAttributes() const override;
+ [[nodiscard]] Attribute getSupportedEntryAttributes() const override;
[[nodiscard]] explicit operator std::string() const override;
diff --git a/include/vpkpp/format/GMA.h b/include/vpkpp/format/GMA.h
index c8719bc75..41d0f39d3 100644
--- a/include/vpkpp/format/GMA.h
+++ b/include/vpkpp/format/GMA.h
@@ -25,7 +25,7 @@ class GMA : public PackFile {
public:
/// Open a GMA file
- [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
[[nodiscard]] constexpr bool hasEntryChecksums() const override {
return true;
@@ -37,18 +37,18 @@ class GMA : public PackFile {
[[nodiscard]] bool verifyPackFileChecksum() const override;
- [[nodiscard]] std::optional> readEntry(const Entry& entry) const override;
+ [[nodiscard]] std::optional> readEntry(const std::string& path_) const override;
- bool bake(const std::string& outputDir_ /*= ""*/, const Callback& callback /*= nullptr*/) override;
+ bool bake(const std::string& outputDir_ /*= ""*/, const EntryCallback& callback /*= nullptr*/) override;
- [[nodiscard]] std::vector getSupportedEntryAttributes() const override;
+ [[nodiscard]] Attribute getSupportedEntryAttributes() const override;
[[nodiscard]] explicit operator std::string() const override;
protected:
GMA(const std::string& fullFilePath_, PackFileOptions options_);
- Entry& addEntryInternal(Entry& entry, const std::string& filename_, std::vector& buffer, EntryOptions options_) override;
+ void addEntryInternal(Entry& entry, const std::string& path, std::vector& buffer, EntryOptions options_) override;
Header header{};
diff --git a/include/vpkpp/format/GRP.h b/include/vpkpp/format/GRP.h
deleted file mode 100644
index d68f15f52..000000000
--- a/include/vpkpp/format/GRP.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-
-#include "../PackFile.h"
-
-namespace vpkpp {
-
-constexpr int8_t GRP_FILENAME_MAX_SIZE = 12;
-constexpr std::string_view GRP_SIGNATURE = "KenSilverman";
-constexpr std::string_view GRP_EXTENSION = ".grp";
-
-class GRP : public PackFile {
-public:
- /// Open a GRP file
- [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
-
- [[nodiscard]] std::optional> readEntry(const Entry& entry) const override;
-
- bool bake(const std::string& outputDir_ /*= ""*/, const Callback& callback /*= nullptr*/) override;
-
- [[nodiscard]] std::vector getSupportedEntryAttributes() const override;
-
-protected:
- GRP(const std::string& fullFilePath_, PackFileOptions options_);
-
- Entry& addEntryInternal(Entry& entry, const std::string& filename_, std::vector& buffer, EntryOptions options_) override;
-
-private:
- VPKPP_REGISTER_PACKFILE_OPEN(GRP_EXTENSION, &GRP::open);
-};
-
-} // namespace vpkpp
diff --git a/include/vpkpp/format/PAK.h b/include/vpkpp/format/PAK.h
index ecc306fc5..d7df0b5ce 100644
--- a/include/vpkpp/format/PAK.h
+++ b/include/vpkpp/format/PAK.h
@@ -13,18 +13,18 @@ constexpr std::string_view PAK_EXTENSION = ".pak";
class PAK : public PackFile {
public:
/// Open a PAK file
- [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
- [[nodiscard]] std::optional> readEntry(const Entry& entry) const override;
+ [[nodiscard]] std::optional> readEntry(const std::string& path_) const override;
- bool bake(const std::string& outputDir_ /*= ""*/, const Callback& callback /*= nullptr*/) override;
+ bool bake(const std::string& outputDir_ /*= ""*/, const EntryCallback& callback /*= nullptr*/) override;
- [[nodiscard]] std::vector getSupportedEntryAttributes() const override;
+ [[nodiscard]] Attribute getSupportedEntryAttributes() const override;
protected:
PAK(const std::string& fullFilePath_, PackFileOptions options_);
- Entry& addEntryInternal(Entry& entry, const std::string& filename_, std::vector& buffer, EntryOptions options_) override;
+ void addEntryInternal(Entry& entry, const std::string& path, std::vector& buffer, EntryOptions options_) override;
private:
VPKPP_REGISTER_PACKFILE_OPEN(PAK_EXTENSION, &PAK::open);
diff --git a/include/vpkpp/format/PCK.h b/include/vpkpp/format/PCK.h
index 780abdf9f..c6956f2a9 100644
--- a/include/vpkpp/format/PCK.h
+++ b/include/vpkpp/format/PCK.h
@@ -28,24 +28,24 @@ class PCK : public PackFile {
public:
/// Open a PCK file (potentially embedded in an executable)
- [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
[[nodiscard]] constexpr bool isCaseSensitive() const noexcept override {
return true;
}
- [[nodiscard]] std::optional> readEntry(const Entry& entry) const override;
+ [[nodiscard]] std::optional> readEntry(const std::string& path_) const override;
- bool bake(const std::string& outputDir_ /*= ""*/, const Callback& callback /*= nullptr*/) override;
+ bool bake(const std::string& outputDir_ /*= ""*/, const EntryCallback& callback /*= nullptr*/) override;
- [[nodiscard]] std::vector getSupportedEntryAttributes() const override;
+ [[nodiscard]] Attribute getSupportedEntryAttributes() const override;
[[nodiscard]] explicit operator std::string() const override;
protected:
PCK(const std::string& fullFilePath_, PackFileOptions options_);
- Entry& addEntryInternal(Entry& entry, const std::string& filename_, std::vector& buffer, EntryOptions options_) override;
+ void addEntryInternal(Entry& entry, const std::string& path, std::vector& buffer, EntryOptions options_) override;
Header header{};
diff --git a/include/vpkpp/format/VPK.h b/include/vpkpp/format/VPK.h
index 719eac416..9a8ecf8f2 100644
--- a/include/vpkpp/format/VPK.h
+++ b/include/vpkpp/format/VPK.h
@@ -55,24 +55,24 @@ class VPK : public PackFile {
struct FreedChunk {
uint64_t offset;
uint64_t length;
- uint16_t archiveIndex;
+ uint32_t archiveIndex;
};
public:
// Accepts the full entry path (parent directory + filename), returns saveToDir and preloadBytes
- using EntryCreationCallback = std::function(const std::string& fullEntryPath)>;
+ using EntryCreationCallback = std::function(const std::string& path)>;
/// Create a new directory VPK file - must end in "_dir.vpk"! This is not enforced but STRONGLY recommended
static std::unique_ptr createEmpty(const std::string& path, PackFileOptions options = {});
/// Create a new directory VPK file from a directory, the contents of the directory will be present in the root VPK directory. (See above comment)
- static std::unique_ptr createFromDirectory(const std::string& vpkPath, const std::string& contentPath, bool saveToDir = false, PackFileOptions options = {}, const Callback& bakeCallback = nullptr);
+ static std::unique_ptr createFromDirectory(const std::string& vpkPath, const std::string& contentPath, bool saveToDir = false, PackFileOptions options = {}, const EntryCallback& bakeCallback = nullptr);
/// Create a new directory VPK file from a directory, the contents of the directory will be present in the root VPK directory. Each entry's properties is determined by a callback. (See above comment)
- static std::unique_ptr createFromDirectoryProcedural(const std::string& vpkPath, const std::string& contentPath, const EntryCreationCallback& creationCallback, PackFileOptions options = {}, const Callback& bakeCallback = nullptr);
+ static std::unique_ptr createFromDirectoryProcedural(const std::string& vpkPath, const std::string& contentPath, const EntryCreationCallback& creationCallback, PackFileOptions options = {}, const EntryCallback& bakeCallback = nullptr);
/// Open a directory VPK file
- [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
[[nodiscard]] constexpr bool hasEntryChecksums() const override {
return true;
@@ -88,15 +88,17 @@ class VPK : public PackFile {
[[nodiscard]] bool verifyPackFileSignature() const override;
- [[nodiscard]] std::optional> readEntry(const Entry& entry) const override;
+ [[nodiscard]] std::optional> readEntry(const std::string& path_) const override;
bool removeEntry(const std::string& filename_) override;
- bool bake(const std::string& outputDir_ /*= ""*/, const Callback& callback /*= nullptr*/) override;
+ std::size_t removeDirectory(const std::string& dirName_) override;
+
+ bool bake(const std::string& outputDir_ /*= ""*/, const EntryCallback& callback /*= nullptr*/) override;
[[nodiscard]] std::string getTruncatedFilestem() const override;
- [[nodiscard]] std::vector getSupportedEntryAttributes() const override;
+ [[nodiscard]] Attribute getSupportedEntryAttributes() const override;
[[nodiscard]] explicit operator std::string() const override;
@@ -120,13 +122,13 @@ class VPK : public PackFile {
protected:
VPK(const std::string& fullFilePath_, PackFileOptions options_);
- [[nodiscard]] static std::unique_ptr openInternal(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr openInternal(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
- Entry& addEntryInternal(Entry& entry, const std::string& filename_, std::vector& buffer, EntryOptions options_) override;
+ void addEntryInternal(Entry& entry, const std::string& path, std::vector& buffer, EntryOptions options_) override;
[[nodiscard]] uint32_t getHeaderLength() const;
- int numArchives = -1;
+ uint32_t numArchives = -1;
uint32_t currentlyFilledChunkSize = 0;
std::vector freedChunks;
diff --git a/include/vpkpp/format/VPK_VTMB.h b/include/vpkpp/format/VPK_VTMB.h
index a50806596..2af76ea80 100644
--- a/include/vpkpp/format/VPK_VTMB.h
+++ b/include/vpkpp/format/VPK_VTMB.h
@@ -12,25 +12,25 @@ constexpr std::string_view VPK_VTMB_EXTENSION = ".vpk";
class VPK_VTMB : public PackFile {
public:
/// Open Vampire: The Masquerade - Bloodlines VPK files
- [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
- [[nodiscard]] std::optional> readEntry(const Entry& entry) const override;
+ [[nodiscard]] std::optional> readEntry(const std::string& path_) const override;
- bool bake(const std::string& outputDir_ /*= ""*/, const Callback& callback /*= nullptr*/) override;
+ bool bake(const std::string& outputDir_ /*= ""*/, const EntryCallback& callback /*= nullptr*/) override;
[[nodiscard]] std::string getTruncatedFilestem() const override;
- [[nodiscard]] std::vector getSupportedEntryAttributes() const override;
+ [[nodiscard]] Attribute getSupportedEntryAttributes() const override;
protected:
VPK_VTMB(const std::string& fullFilePath_, PackFileOptions options_);
- void openNumbered(uint16_t archiveIndex, const std::string& path, const Callback& callback);
+ void openNumbered(uint32_t archiveIndex, const std::string& path, const EntryCallback& callback);
- Entry& addEntryInternal(Entry& entry, const std::string& filename_, std::vector& buffer, EntryOptions options_) override;
+ void addEntryInternal(Entry& entry, const std::string& path, std::vector& buffer, EntryOptions options_) override;
- std::vector knownArchives;
- uint16_t currentArchive = 0;
+ std::vector knownArchives;
+ uint32_t currentArchive = 0;
private:
VPKPP_REGISTER_PACKFILE_OPEN(VPK_VTMB_EXTENSION, &VPK_VTMB::open);
diff --git a/include/vpkpp/format/ZIP.h b/include/vpkpp/format/ZIP.h
index a0eafb11d..fb52c45c8 100644
--- a/include/vpkpp/format/ZIP.h
+++ b/include/vpkpp/format/ZIP.h
@@ -12,7 +12,7 @@ class ZIP : public PackFile {
~ZIP() override;
/// Open a ZIP file
- [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const Callback& callback = nullptr);
+ [[nodiscard]] static std::unique_ptr open(const std::string& path, PackFileOptions options = {}, const EntryCallback& callback = nullptr);
[[nodiscard]] constexpr bool hasEntryChecksums() const override {
return true;
@@ -24,11 +24,11 @@ class ZIP : public PackFile {
return true;
}
- [[nodiscard]] std::optional> readEntry(const Entry& entry) const override;
+ [[nodiscard]] std::optional> readEntry(const std::string& path_) const override;
- bool bake(const std::string& outputDir_ /*= ""*/, const Callback& callback /*= nullptr*/) override;
+ bool bake(const std::string& outputDir_ /*= ""*/, const EntryCallback& callback /*= nullptr*/) override;
- [[nodiscard]] std::vector getSupportedEntryAttributes() const override;
+ [[nodiscard]] Attribute getSupportedEntryAttributes() const override;
#ifdef VPKPP_ZIP_COMPRESSION
[[nodiscard]] uint16_t getCompressionMethod() const;
@@ -39,9 +39,9 @@ class ZIP : public PackFile {
protected:
ZIP(const std::string& fullFilePath_, PackFileOptions options_);
- Entry& addEntryInternal(Entry& entry, const std::string& filename_, std::vector& buffer, EntryOptions options_) override;
+ void addEntryInternal(Entry& entry, const std::string& path, std::vector& buffer, EntryOptions options_) override;
- bool bakeTempZip(const std::string& writeZipPath, const Callback& callback);
+ bool bakeTempZip(const std::string& writeZipPath, const EntryCallback& callback);
bool openZIP(std::string_view path);
diff --git a/lang/c/include/vpkppc/Attribute.h b/lang/c/include/vpkppc/Attribute.h
index 01dada6b7..2d3a7aac2 100644
--- a/lang/c/include/vpkppc/Attribute.h
+++ b/lang/c/include/vpkppc/Attribute.h
@@ -5,13 +5,12 @@ extern "C" {
#endif
typedef enum {
- VPKPP_ATTRIBUTE_NONE = -1,
- VPKPP_ATTRIBUTE_LENGTH = 0,
- VPKPP_ATTRIBUTE_VPK_PRELOADED_DATA_LENGTH,
- VPKPP_ATTRIBUTE_ARCHIVE_INDEX,
- VPKPP_ATTRIBUTE_CRC32,
- VPKPP_ATTRIBUTE_PCK_MD5,
- VPKPP_ATTRIBUTE_COUNT,
+ VPKPP_ATTRIBUTE_NONE = 0,
+ VPKPP_ATTRIBUTE_ARCHIVE_INDEX = 1 << 0,
+ VPKPP_ATTRIBUTE_LENGTH = 1 << 1,
+ VPKPP_ATTRIBUTE_CRC32 = 1 << 2,
+ VPKPP_ATTRIBUTE_PCK_MD5 = 1 << 3,
+ VPKPP_ATTRIBUTE_VPK_PRELOADED_DATA = 1 << 4,
} vpkpp_attribute_e;
#ifdef __cplusplus
diff --git a/lang/c/include/vpkppc/Convert.hpp b/lang/c/include/vpkppc/Convert.hpp
index 4d06f345c..a4bb57cf8 100644
--- a/lang/c/include/vpkppc/Convert.hpp
+++ b/lang/c/include/vpkppc/Convert.hpp
@@ -28,6 +28,10 @@ vpkpp::Entry* entry(vpkpp_entry_handle_t handle);
vpkpp::PackFileOptions optionsFromC(vpkpp_pack_file_options_t options);
+vpkpp::EntryOptions optionsFromC(vpkpp_entry_options_t options);
+
vpkpp_pack_file_options_t optionsToC(vpkpp::PackFileOptions options);
+vpkpp_entry_options_t optionsToC(vpkpp::EntryOptions options);
+
} // namespace Convert
diff --git a/lang/c/include/vpkppc/Entry.h b/lang/c/include/vpkppc/Entry.h
index 6a4385784..d86faf422 100644
--- a/lang/c/include/vpkppc/Entry.h
+++ b/lang/c/include/vpkppc/Entry.h
@@ -1,6 +1,7 @@
#pragma once
#include
+#include
#ifdef __cplusplus
extern "C" {
@@ -8,27 +9,24 @@ extern "C" {
typedef void* vpkpp_entry_handle_t;
-typedef struct {
- int64_t size;
- vpkpp_entry_handle_t* data;
-} vpkpp_entry_handle_array_t;
-
-#define VPKPP_ENTRY_HANDLE_ARRAY_INVALID (vpkpp_entry_handle_array_t{.size = -1, .data = NULL})
-
#ifdef __cplusplus
} // extern "C"
#endif
-SOURCEPP_API size_t vpkpp_entry_get_path(vpkpp_entry_handle_t handle, char* buffer, size_t bufferLen);
+SOURCEPP_API uint32_t vpkpp_entry_get_flags(vpkpp_entry_handle_t handle);
-SOURCEPP_API size_t vpkpp_entry_get_parent_path(vpkpp_entry_handle_t handle, char* buffer, size_t bufferLen);
+SOURCEPP_API uint32_t vpkpp_entry_get_archive_index(vpkpp_entry_handle_t handle);
-SOURCEPP_API size_t vpkpp_entry_get_filename(vpkpp_entry_handle_t handle, char* buffer, size_t bufferLen);
+SOURCEPP_API uint64_t vpkpp_entry_get_length(vpkpp_entry_handle_t handle);
-SOURCEPP_API size_t vpkpp_entry_get_stem(vpkpp_entry_handle_t handle, char* buffer, size_t bufferLen);
+SOURCEPP_API uint64_t vpkpp_entry_get_compressed_length(vpkpp_entry_handle_t handle);
-SOURCEPP_API size_t vpkpp_entry_get_extension(vpkpp_entry_handle_t handle, char* buffer, size_t bufferLen);
+SOURCEPP_API uint64_t vpkpp_entry_get_offset(vpkpp_entry_handle_t handle);
-SOURCEPP_API void vpkpp_entry_free(vpkpp_entry_handle_t* handle);
+SOURCEPP_API sourcepp_buffer_t vpkpp_entry_get_extra_data(vpkpp_entry_handle_t handle);
-SOURCEPP_API void vpkpp_entry_array_free(vpkpp_entry_handle_array_t* array);
+SOURCEPP_API uint32_t vpkpp_entry_get_crc32(vpkpp_entry_handle_t handle);
+
+SOURCEPP_API int vpkpp_entry_is_unbaked(vpkpp_entry_handle_t handle);
+
+SOURCEPP_API void vpkpp_entry_free(vpkpp_entry_handle_t* handle);
diff --git a/lang/c/include/vpkppc/Options.h b/lang/c/include/vpkppc/Options.h
index 95e52e651..4ff7a7321 100644
--- a/lang/c/include/vpkppc/Options.h
+++ b/lang/c/include/vpkppc/Options.h
@@ -7,13 +7,18 @@ extern "C" {
#endif
typedef struct {
- bool gma_writeCRCs;
+ int gma_writeCRCs;
uint32_t vpk_version;
uint32_t vpk_preferredChunkSize;
- bool vpk_generateMD5Entries;
+ int vpk_generateMD5Entries;
uint16_t zip_compressionMethod;
} vpkpp_pack_file_options_t;
+typedef struct {
+ int vpk_saveToDirectory;
+ uint32_t vpk_preloadBytes;
+} vpkpp_entry_options_t;
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/lang/c/include/vpkppc/PackFile.h b/lang/c/include/vpkppc/PackFile.h
index 72972309a..777ae5ccf 100644
--- a/lang/c/include/vpkppc/PackFile.h
+++ b/lang/c/include/vpkppc/PackFile.h
@@ -14,6 +14,10 @@ extern "C" {
typedef void* vpkpp_pack_file_handle_t;
+typedef void(*EntryCallback)(const char* path, vpkpp_entry_handle_t entry);
+
+typedef int(*EntryPredicate)(const char* path, vpkpp_entry_handle_t entry);
+
#ifdef __cplusplus
} // extern "C"
#endif
@@ -21,85 +25,106 @@ typedef void* vpkpp_pack_file_handle_t;
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_open(const char* path);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_open_with_callback(const char* path, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_open_with_options(const char* path, vpkpp_pack_file_options_t options);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback);
+
SOURCEPP_API vpkpp_pack_file_type_e vpkpp_get_type(vpkpp_pack_file_handle_t handle);
SOURCEPP_API vpkpp_pack_file_options_t vpkpp_get_options(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API bool vpkpp_has_entry_checksums(vpkpp_pack_file_handle_t handle);
+SOURCEPP_API int vpkpp_has_entry_checksums(vpkpp_pack_file_handle_t handle);
// REQUIRES MANUAL FREE: sourcepp_string_array_free
SOURCEPP_API sourcepp_string_array_t vpkpp_verify_entry_checksums(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API bool vpkpp_has_pack_file_checksum(vpkpp_pack_file_handle_t handle);
+SOURCEPP_API int vpkpp_has_pack_file_checksum(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API bool vpkpp_verify_pack_file_checksum(vpkpp_pack_file_handle_t handle);
+SOURCEPP_API int vpkpp_verify_pack_file_checksum(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API bool vpkpp_has_pack_file_signature(vpkpp_pack_file_handle_t handle);
+SOURCEPP_API int vpkpp_has_pack_file_signature(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API bool vpkpp_verify_pack_file_signature(vpkpp_pack_file_handle_t handle);
+SOURCEPP_API int vpkpp_verify_pack_file_signature(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API bool vpkpp_is_case_sensitive(vpkpp_pack_file_handle_t handle);
+SOURCEPP_API int vpkpp_is_case_sensitive(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API bool vpkpp_has_entry(vpkpp_pack_file_handle_t handle, const char* filename, bool includeUnbaked);
+SOURCEPP_API int vpkpp_has_entry(vpkpp_pack_file_handle_t handle, const char* path, int includeUnbaked);
// REQUIRES MANUAL FREE: vpkpp_entry_free
-SOURCEPP_API vpkpp_entry_handle_t vpkpp_find_entry(vpkpp_pack_file_handle_t handle, const char* filename, bool includeUnbaked);
+SOURCEPP_API vpkpp_entry_handle_t vpkpp_find_entry(vpkpp_pack_file_handle_t handle, const char* path, int includeUnbaked);
// REQUIRES MANUAL FREE: sourcepp_buffer_free
-SOURCEPP_API sourcepp_buffer_t vpkpp_read_entry(vpkpp_pack_file_handle_t handle, vpkpp_entry_handle_t entry);
+SOURCEPP_API sourcepp_buffer_t vpkpp_read_entry(vpkpp_pack_file_handle_t handle, const char* path);
// REQUIRES MANUAL FREE: sourcepp_string_free
-SOURCEPP_API sourcepp_string_t vpkpp_read_entry_text(vpkpp_pack_file_handle_t handle, vpkpp_entry_handle_t entry);
+SOURCEPP_API sourcepp_string_t vpkpp_read_entry_text(vpkpp_pack_file_handle_t handle, const char* path);
+
+SOURCEPP_API int vpkpp_is_read_only(vpkpp_pack_file_handle_t handle);
+
+SOURCEPP_API void vpkpp_add_entry_from_file(vpkpp_pack_file_handle_t handle, const char* entryPath, const char* filepath);
+
+SOURCEPP_API void vpkpp_add_entry_from_file_with_options(vpkpp_pack_file_handle_t handle, const char* entryPath, const char* filepath, vpkpp_entry_options_t options);
-SOURCEPP_API bool vpkpp_is_read_only(vpkpp_pack_file_handle_t handle);
+SOURCEPP_API void vpkpp_add_entry_from_mem(vpkpp_pack_file_handle_t handle, const char* path, const unsigned char* buffer, size_t bufferLen);
-SOURCEPP_API void vpkpp_add_entry_from_file(vpkpp_pack_file_handle_t handle, const char* filename, const char* pathToFile);
+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 void vpkpp_add_entry_from_mem(vpkpp_pack_file_handle_t handle, const char* filename, const unsigned char* buffer, size_t bufferLen);
+SOURCEPP_API int vpkpp_rename_entry(vpkpp_pack_file_handle_t handle, const char* oldPath, const char* newPath);
-SOURCEPP_API bool vpkpp_remove_entry(vpkpp_pack_file_handle_t handle, const char* filename);
+SOURCEPP_API int vpkpp_rename_directory(vpkpp_pack_file_handle_t handle, const char* oldDir, const char* newDir);
-SOURCEPP_API bool vpkpp_bake(vpkpp_pack_file_handle_t handle, const char* outputDir);
+SOURCEPP_API int vpkpp_remove_entry(vpkpp_pack_file_handle_t handle, const char* path);
-SOURCEPP_API bool vpkpp_extract_entry(vpkpp_pack_file_handle_t handle, vpkpp_entry_handle_t entry, const char* filePath);
+SOURCEPP_API int vpkpp_remove_directory(vpkpp_pack_file_handle_t handle, const char* dirName);
-SOURCEPP_API bool vpkpp_extract_directory(vpkpp_pack_file_handle_t handle, const char* dir, const char* outputDir);
+SOURCEPP_API int vpkpp_bake(vpkpp_pack_file_handle_t handle, const char* outputDir);
-SOURCEPP_API bool vpkpp_extract_all(vpkpp_pack_file_handle_t handle, const char* outputDir, bool createUnderPackFileDir);
+SOURCEPP_API int vpkpp_bake_with_callback(vpkpp_pack_file_handle_t handle, const char* outputDir, EntryCallback callback);
-SOURCEPP_API bool vpkpp_extract_all_if(vpkpp_pack_file_handle_t handle, const char* outputDir, bool(*predicate)(vpkpp_entry_handle_t));
+SOURCEPP_API int vpkpp_extract_entry(vpkpp_pack_file_handle_t handle, const char* entryPath, const char* filepath);
-// REQUIRES MANUAL FREE: vpkpp_entry_array_free
-SOURCEPP_API vpkpp_entry_handle_array_t vpkpp_get_baked_entries(vpkpp_pack_file_handle_t handle);
+SOURCEPP_API int vpkpp_extract_directory(vpkpp_pack_file_handle_t handle, const char* dir, const char* outputDir);
-// REQUIRES MANUAL FREE: vpkpp_entry_array_free
-SOURCEPP_API vpkpp_entry_handle_array_t vpkpp_get_unbaked_entries(vpkpp_pack_file_handle_t handle);
+SOURCEPP_API int vpkpp_extract_all(vpkpp_pack_file_handle_t handle, const char* outputDir, int createUnderPackFileDir);
-SOURCEPP_API size_t vpkpp_get_entry_count(vpkpp_pack_file_handle_t handle, bool includeUnbaked);
+SOURCEPP_API int vpkpp_extract_all_if(vpkpp_pack_file_handle_t handle, const char* outputDir, EntryPredicate predicate, int stripSharedDirs);
-SOURCEPP_API size_t vpkpp_get_filepath(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen);
+SOURCEPP_API size_t vpkpp_get_entry_count(vpkpp_pack_file_handle_t handle, int includeUnbaked);
-SOURCEPP_API size_t vpkpp_get_truncated_filepath(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen);
+SOURCEPP_API void vpkpp_run_for_all_entries(vpkpp_pack_file_handle_t handle, EntryCallback operation, int includeUnbaked);
-SOURCEPP_API size_t vpkpp_get_filename(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen);
+// REQUIRES MANUAL FREE: sourcepp_string_free
+SOURCEPP_API sourcepp_string_t vpkpp_get_filepath(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API size_t vpkpp_get_truncated_filename(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen);
+// REQUIRES MANUAL FREE: sourcepp_string_free
+SOURCEPP_API sourcepp_string_t vpkpp_get_truncated_filepath(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API size_t vpkpp_get_filestem(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen);
+// REQUIRES MANUAL FREE: sourcepp_string_free
+SOURCEPP_API sourcepp_string_t vpkpp_get_filename(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API size_t vpkpp_get_truncated_filestem(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen);
+// REQUIRES MANUAL FREE: sourcepp_string_free
+SOURCEPP_API sourcepp_string_t vpkpp_get_truncated_filename(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API size_t vpkpp_get_supported_entry_attributes(vpkpp_pack_file_handle_t handle, vpkpp_attribute_e* buffer, size_t bufferLen);
+// REQUIRES MANUAL FREE: sourcepp_string_free
+SOURCEPP_API sourcepp_string_t vpkpp_get_filestem(vpkpp_pack_file_handle_t handle);
-SOURCEPP_API size_t vpkpp_to_string(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen);
+// REQUIRES MANUAL FREE: sourcepp_string_free
+SOURCEPP_API sourcepp_string_t vpkpp_get_truncated_filestem(vpkpp_pack_file_handle_t handle);
+
+SOURCEPP_API vpkpp_attribute_e vpkpp_get_supported_entry_attributes(vpkpp_pack_file_handle_t handle);
+
+// REQUIRES MANUAL FREE: sourcepp_string_free
+SOURCEPP_API sourcepp_string_t vpkpp_to_string(vpkpp_pack_file_handle_t handle);
SOURCEPP_API void vpkpp_close(vpkpp_pack_file_handle_t* handle);
// REQUIRES MANUAL FREE: sourcepp_string_free
-SOURCEPP_API sourcepp_string_t vpkpp_escape_entry_path(const char* path);
+SOURCEPP_API sourcepp_string_t vpkpp_escape_entry_path_for_write(const char* path);
// REQUIRES MANUAL FREE: sourcepp_string_array_free
SOURCEPP_API sourcepp_string_array_t vpkpp_get_supported_file_types();
diff --git a/lang/c/include/vpkppc/PackFileType.h b/lang/c/include/vpkppc/PackFileType.h
index fe7baa1ff..914f30ae9 100644
--- a/lang/c/include/vpkppc/PackFileType.h
+++ b/lang/c/include/vpkppc/PackFileType.h
@@ -10,7 +10,6 @@ typedef enum {
VPKPP_PACK_FILE_TYPE_FPX,
VPKPP_PACK_FILE_TYPE_GCF,
VPKPP_PACK_FILE_TYPE_GMA,
- VPKPP_PACK_FILE_TYPE_GRP,
VPKPP_PACK_FILE_TYPE_PAK,
VPKPP_PACK_FILE_TYPE_PCK,
VPKPP_PACK_FILE_TYPE_VPK,
diff --git a/lang/c/include/vpkppc/format/BSP.h b/lang/c/include/vpkppc/format/BSP.h
index 820003ff2..c01444686 100644
--- a/lang/c/include/vpkppc/format/BSP.h
+++ b/lang/c/include/vpkppc/format/BSP.h
@@ -5,5 +5,11 @@
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_bsp_open(const char* path);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_bsp_open_with_callback(const char* path, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_bsp_open_with_options(const char* path, vpkpp_pack_file_options_t options);
+
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_bsp_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback);
diff --git a/lang/c/include/vpkppc/format/FPX.h b/lang/c/include/vpkppc/format/FPX.h
index 93b7f13c1..cf6426c90 100644
--- a/lang/c/include/vpkppc/format/FPX.h
+++ b/lang/c/include/vpkppc/format/FPX.h
@@ -5,5 +5,11 @@
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_fpx_open(const char* path);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_fpx_open_with_callback(const char* path, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_fpx_open_with_options(const char* path, vpkpp_pack_file_options_t options);
+
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_fpx_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback);
diff --git a/lang/c/include/vpkppc/format/GCF.h b/lang/c/include/vpkppc/format/GCF.h
index 45725972c..18e5edb5a 100644
--- a/lang/c/include/vpkppc/format/GCF.h
+++ b/lang/c/include/vpkppc/format/GCF.h
@@ -5,5 +5,11 @@
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gcf_open(const char* path);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gcf_open_with_callback(const char* path, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gcf_open_with_options(const char* path, vpkpp_pack_file_options_t options);
+
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gcf_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback);
diff --git a/lang/c/include/vpkppc/format/GMA.h b/lang/c/include/vpkppc/format/GMA.h
index a8b43cc5d..488017003 100644
--- a/lang/c/include/vpkppc/format/GMA.h
+++ b/lang/c/include/vpkppc/format/GMA.h
@@ -5,5 +5,11 @@
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gma_open(const char* path);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gma_open_with_callback(const char* path, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gma_open_with_options(const char* path, vpkpp_pack_file_options_t options);
+
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gma_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback);
diff --git a/lang/c/include/vpkppc/format/GRP.h b/lang/c/include/vpkppc/format/GRP.h
deleted file mode 100644
index 44be3fc04..000000000
--- a/lang/c/include/vpkppc/format/GRP.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#include "../PackFile.h"
-
-// REQUIRES MANUAL FREE: vpkpp_close
-SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_grp_open(const char* path);
-
-// REQUIRES MANUAL FREE: vpkpp_close
-SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_grp_open_with_options(const char* path, vpkpp_pack_file_options_t options);
diff --git a/lang/c/include/vpkppc/format/PAK.h b/lang/c/include/vpkppc/format/PAK.h
index 1bdb75333..ee7151c02 100644
--- a/lang/c/include/vpkppc/format/PAK.h
+++ b/lang/c/include/vpkppc/format/PAK.h
@@ -5,5 +5,11 @@
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pak_open(const char* path);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pak_open_with_callback(const char* path, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pak_open_with_options(const char* path, vpkpp_pack_file_options_t options);
+
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pak_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback);
diff --git a/lang/c/include/vpkppc/format/PCK.h b/lang/c/include/vpkppc/format/PCK.h
index 0a89f60bd..144d9a1a2 100644
--- a/lang/c/include/vpkppc/format/PCK.h
+++ b/lang/c/include/vpkppc/format/PCK.h
@@ -5,5 +5,11 @@
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pck_open(const char* path);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pck_open_with_callback(const char* path, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pck_open_with_options(const char* path, vpkpp_pack_file_options_t options);
+
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pck_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback);
diff --git a/lang/c/include/vpkppc/format/VPK.h b/lang/c/include/vpkppc/format/VPK.h
index 91a5934c5..f2cc3a139 100644
--- a/lang/c/include/vpkppc/format/VPK.h
+++ b/lang/c/include/vpkppc/format/VPK.h
@@ -11,15 +11,27 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_empty_with_options(const
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_from_directory(const char* vpkPath, const char* contentPath, bool saveToDir);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_from_directory_with_callback(const char* vpkPath, const char* contentPath, bool saveToDir, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_from_directory_with_options(const char* vpkPath, const char* contentPath, bool saveToDir, vpkpp_pack_file_options_t options);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_from_directory_with_options_and_callback(const char* vpkPath, const char* contentPath, bool saveToDir, vpkpp_pack_file_options_t options, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_open(const char* path);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_open_with_callback(const char* path, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_open_with_options(const char* path, vpkpp_pack_file_options_t options);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback);
+
SOURCEPP_API bool vpkpp_vpk_generate_keypair_files(const char* path);
SOURCEPP_API bool vpkpp_vpk_sign_from_file(vpkpp_pack_file_handle_t handle, const char* filename);
diff --git a/lang/c/include/vpkppc/format/VPK_VTMB.h b/lang/c/include/vpkppc/format/VPK_VTMB.h
index 504c69ab9..bc07c08a4 100644
--- a/lang/c/include/vpkppc/format/VPK_VTMB.h
+++ b/lang/c/include/vpkppc/format/VPK_VTMB.h
@@ -5,5 +5,11 @@
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_vtmb_open(const char* path);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_vtmb_open_with_callback(const char* path, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_vtmb_open_with_options(const char* path, vpkpp_pack_file_options_t options);
+
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_vtmb_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback);
diff --git a/lang/c/include/vpkppc/format/ZIP.h b/lang/c/include/vpkppc/format/ZIP.h
index f472c05ea..6245d01cc 100644
--- a/lang/c/include/vpkppc/format/ZIP.h
+++ b/lang/c/include/vpkppc/format/ZIP.h
@@ -5,5 +5,11 @@
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_zip_open(const char* path);
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_zip_open_with_callback(const char* path, EntryCallback callback);
+
// REQUIRES MANUAL FREE: vpkpp_close
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_zip_open_with_options(const char* path, vpkpp_pack_file_options_t options);
+
+// REQUIRES MANUAL FREE: vpkpp_close
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_zip_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback);
diff --git a/lang/c/src/vpkppc/Convert.cpp b/lang/c/src/vpkppc/Convert.cpp
index 2f467bf5f..111fc22ec 100644
--- a/lang/c/src/vpkppc/Convert.cpp
+++ b/lang/c/src/vpkppc/Convert.cpp
@@ -14,14 +14,21 @@ Entry* Convert::entry(vpkpp_entry_handle_t handle) {
PackFileOptions Convert::optionsFromC(vpkpp_pack_file_options_t options) {
return {
- .gma_writeCRCs = options.gma_writeCRCs,
+ .gma_writeCRCs = static_cast(options.gma_writeCRCs),
.vpk_version = options.vpk_version,
.vpk_preferredChunkSize = options.vpk_preferredChunkSize,
- .vpk_generateMD5Entries = options.vpk_generateMD5Entries,
+ .vpk_generateMD5Entries = static_cast(options.vpk_generateMD5Entries),
.zip_compressionMethod = options.zip_compressionMethod,
};
}
+EntryOptions Convert::optionsFromC(vpkpp_entry_options_t options) {
+ return {
+ .vpk_saveToDirectory = static_cast(options.vpk_saveToDirectory),
+ .vpk_preloadBytes = options.vpk_preloadBytes,
+ };
+}
+
vpkpp_pack_file_options_t Convert::optionsToC(PackFileOptions options) {
return {
.gma_writeCRCs = options.gma_writeCRCs,
@@ -31,3 +38,10 @@ vpkpp_pack_file_options_t Convert::optionsToC(PackFileOptions options) {
.zip_compressionMethod = options.zip_compressionMethod,
};
}
+
+vpkpp_entry_options_t Convert::optionsToC(EntryOptions options) {
+ return {
+ .vpk_saveToDirectory = options.vpk_saveToDirectory,
+ .vpk_preloadBytes = options.vpk_preloadBytes,
+ };
+}
diff --git a/lang/c/src/vpkppc/Entry.cpp b/lang/c/src/vpkppc/Entry.cpp
index 449e79c69..efad90c5f 100644
--- a/lang/c/src/vpkppc/Entry.cpp
+++ b/lang/c/src/vpkppc/Entry.cpp
@@ -8,44 +8,52 @@
using namespace vpkpp;
-SOURCEPP_API size_t vpkpp_entry_get_path(vpkpp_entry_handle_t handle, char* buffer, size_t bufferLen) {
+SOURCEPP_API uint32_t vpkpp_entry_get_flags(vpkpp_entry_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
- return Convert::writeStringToMem(Convert::entry(handle)->path, buffer, bufferLen);
+ return Convert::entry(handle)->flags;
}
-SOURCEPP_API size_t vpkpp_entry_get_parent_path(vpkpp_entry_handle_t handle, char* buffer, size_t bufferLen) {
+SOURCEPP_API uint32_t vpkpp_entry_get_archive_index(vpkpp_entry_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
- return Convert::writeStringToMem(Convert::entry(handle)->getParentPath(), buffer, bufferLen);
+ return Convert::entry(handle)->archiveIndex;
}
-SOURCEPP_API size_t vpkpp_entry_get_filename(vpkpp_entry_handle_t handle, char* buffer, size_t bufferLen) {
+SOURCEPP_API uint64_t vpkpp_entry_get_length(vpkpp_entry_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
- return Convert::writeStringToMem(Convert::entry(handle)->getFilename(), buffer, bufferLen);
+ return Convert::entry(handle)->length;
}
-SOURCEPP_API size_t vpkpp_entry_get_stem(vpkpp_entry_handle_t handle, char* buffer, size_t bufferLen) {
+SOURCEPP_API uint64_t vpkpp_entry_get_compressed_length(vpkpp_entry_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
- return Convert::writeStringToMem(Convert::entry(handle)->getStem(), buffer, bufferLen);
+ return Convert::entry(handle)->compressedLength;
}
-SOURCEPP_API size_t vpkpp_entry_get_extension(vpkpp_entry_handle_t handle, char* buffer, size_t bufferLen) {
+SOURCEPP_API uint64_t vpkpp_entry_get_offset(vpkpp_entry_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
- return Convert::writeStringToMem(Convert::entry(handle)->getExtension(), buffer, bufferLen);
+ return Convert::entry(handle)->offset;
+}
+
+SOURCEPP_API sourcepp_buffer_t vpkpp_entry_get_extra_data(vpkpp_entry_handle_t handle) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID);
+
+ return Convert::toBuffer(Convert::entry(handle)->extraData);
+}
+
+SOURCEPP_API uint32_t vpkpp_entry_get_crc32(vpkpp_entry_handle_t handle) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, 0);
+
+ return Convert::entry(handle)->crc32;
+}
+
+SOURCEPP_API int vpkpp_entry_is_unbaked(vpkpp_entry_handle_t handle) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, false);
+
+ return Convert::entry(handle)->unbaked;
}
SOURCEPP_API void vpkpp_entry_free(vpkpp_entry_handle_t* handle) {
@@ -54,18 +62,3 @@ SOURCEPP_API void vpkpp_entry_free(vpkpp_entry_handle_t* handle) {
delete Convert::entry(*handle);
*handle = nullptr;
}
-
-SOURCEPP_API void vpkpp_entry_array_free(vpkpp_entry_handle_array_t* array) {
- SOURCEPP_EARLY_RETURN(array);
-
- if (array->data) {
- for (size_t i = 0; i < array->size; i++) {
- if (auto*& entry = array->data[i]) {
- vpkpp_entry_free(&entry);
- }
- }
- std::free(array->data);
- array->data = nullptr;
- }
- array->size = 0;
-}
diff --git a/lang/c/src/vpkppc/PackFile.cpp b/lang/c/src/vpkppc/PackFile.cpp
index d347f09ac..db6ff8460 100644
--- a/lang/c/src/vpkppc/PackFile.cpp
+++ b/lang/c/src/vpkppc/PackFile.cpp
@@ -23,6 +23,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_open(const char* path) {
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_open_with_callback(const char* path, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = PackFile::open(path, {}, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_open_with_options(const char* path, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
@@ -33,6 +46,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_open_with_options(const char* path,
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = PackFile::open(path, Convert::optionsFromC(options), [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_type_e vpkpp_get_type(vpkpp_pack_file_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, VPKPP_PACK_FILE_TYPE_UNKNOWN);
@@ -43,7 +69,7 @@ SOURCEPP_API vpkpp_pack_file_options_t vpkpp_get_options(vpkpp_pack_file_handle_
return Convert::optionsToC(Convert::packFile(handle)->getOptions());
}
-SOURCEPP_API bool vpkpp_has_entry_checksums(vpkpp_pack_file_handle_t handle) {
+SOURCEPP_API int vpkpp_has_entry_checksums(vpkpp_pack_file_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
return Convert::packFile(handle)->hasEntryChecksums();
@@ -55,256 +81,253 @@ SOURCEPP_API sourcepp_string_array_t vpkpp_verify_entry_checksums(vpkpp_pack_fil
return Convert::toStringArray(Convert::packFile(handle)->verifyEntryChecksums());
}
-SOURCEPP_API bool vpkpp_has_pack_file_checksum(vpkpp_pack_file_handle_t handle) {
+SOURCEPP_API int vpkpp_has_pack_file_checksum(vpkpp_pack_file_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
return Convert::packFile(handle)->hasPackFileChecksum();
}
-SOURCEPP_API bool vpkpp_verify_pack_file_checksum(vpkpp_pack_file_handle_t handle) {
+SOURCEPP_API int vpkpp_verify_pack_file_checksum(vpkpp_pack_file_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
return Convert::packFile(handle)->verifyPackFileChecksum();
}
-SOURCEPP_API bool vpkpp_has_pack_file_signature(vpkpp_pack_file_handle_t handle) {
+SOURCEPP_API int vpkpp_has_pack_file_signature(vpkpp_pack_file_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
return Convert::packFile(handle)->hasPackFileSignature();
}
-SOURCEPP_API bool vpkpp_verify_pack_file_signature(vpkpp_pack_file_handle_t handle) {
+SOURCEPP_API int vpkpp_verify_pack_file_signature(vpkpp_pack_file_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
return Convert::packFile(handle)->verifyPackFileSignature();
}
-SOURCEPP_API bool vpkpp_is_case_sensitive(vpkpp_pack_file_handle_t handle) {
+SOURCEPP_API int vpkpp_is_case_sensitive(vpkpp_pack_file_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
return Convert::packFile(handle)->isCaseSensitive();
}
-SOURCEPP_API bool vpkpp_has_entry(vpkpp_pack_file_handle_t handle, const char* filename, bool includeUnbaked) {
+SOURCEPP_API int vpkpp_has_entry(vpkpp_pack_file_handle_t handle, const char* path, int includeUnbaked) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
- SOURCEPP_EARLY_RETURN_VAL(filename, false);
+ SOURCEPP_EARLY_RETURN_VAL(path, false);
- return Convert::packFile(handle)->hasEntry(filename, includeUnbaked);
+ return Convert::packFile(handle)->hasEntry(path, includeUnbaked);
}
-SOURCEPP_API vpkpp_entry_handle_t vpkpp_find_entry(vpkpp_pack_file_handle_t handle, const char* filename, bool includeUnbaked) {
+SOURCEPP_API vpkpp_entry_handle_t vpkpp_find_entry(vpkpp_pack_file_handle_t handle, const char* path, int includeUnbaked) {
SOURCEPP_EARLY_RETURN_VAL(handle, nullptr);
- SOURCEPP_EARLY_RETURN_VAL(filename, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
- auto entry = Convert::packFile(handle)->findEntry(filename, includeUnbaked);
+ auto entry = Convert::packFile(handle)->findEntry(path, includeUnbaked);
if (!entry) {
return nullptr;
}
return new Entry(std::move(*entry));
}
-SOURCEPP_API sourcepp_buffer_t vpkpp_read_entry(vpkpp_pack_file_handle_t handle, vpkpp_entry_handle_t entry) {
+SOURCEPP_API sourcepp_buffer_t vpkpp_read_entry(vpkpp_pack_file_handle_t handle, const char* path) {
SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID);
- SOURCEPP_EARLY_RETURN_VAL(entry, SOURCEPP_BUFFER_INVALID);
+ SOURCEPP_EARLY_RETURN_VAL(path, SOURCEPP_BUFFER_INVALID);
- if (auto binary = Convert::packFile(handle)->readEntry(*Convert::entry(entry))) {
+ if (auto binary = Convert::packFile(handle)->readEntry(path)) {
return Convert::toBuffer(*binary);
}
return SOURCEPP_BUFFER_INVALID;
}
-SOURCEPP_API sourcepp_string_t vpkpp_read_entry_text(vpkpp_pack_file_handle_t handle, vpkpp_entry_handle_t entry) {
+SOURCEPP_API sourcepp_string_t vpkpp_read_entry_text(vpkpp_pack_file_handle_t handle, const char* path) {
SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID);
- SOURCEPP_EARLY_RETURN_VAL(entry, SOURCEPP_STRING_INVALID);
+ SOURCEPP_EARLY_RETURN_VAL(path, SOURCEPP_STRING_INVALID);
- if (auto text = Convert::packFile(handle)->readEntryText(*Convert::entry(entry))) {
+ if (auto text = Convert::packFile(handle)->readEntryText(path)) {
return Convert::toString(*text);
}
return SOURCEPP_STRING_INVALID;
}
-SOURCEPP_API bool vpkpp_is_read_only(vpkpp_pack_file_handle_t handle) {
+SOURCEPP_API int vpkpp_is_read_only(vpkpp_pack_file_handle_t handle) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
return Convert::packFile(handle)->isReadOnly();
}
-SOURCEPP_API void vpkpp_add_entry_from_file(vpkpp_pack_file_handle_t handle, const char* filename, const char* pathToFile) {
+SOURCEPP_API void vpkpp_add_entry_from_file(vpkpp_pack_file_handle_t handle, const char* entryPath, const char* filepath) {
SOURCEPP_EARLY_RETURN(handle);
- SOURCEPP_EARLY_RETURN(filename);
- SOURCEPP_EARLY_RETURN(pathToFile);
+ SOURCEPP_EARLY_RETURN(entryPath);
+ SOURCEPP_EARLY_RETURN(filepath);
- Convert::packFile(handle)->addEntry(filename, pathToFile, {});
+ Convert::packFile(handle)->addEntry(entryPath, filepath, {});
}
-SOURCEPP_API void vpkpp_add_entry_from_mem(vpkpp_pack_file_handle_t handle, const char* filename, const unsigned char* buffer, size_t bufferLen) {
+SOURCEPP_API void vpkpp_add_entry_from_file_with_options(vpkpp_pack_file_handle_t handle, const char* entryPath, const char* filepath, vpkpp_entry_options_t options) {
SOURCEPP_EARLY_RETURN(handle);
- SOURCEPP_EARLY_RETURN(filename);
+ SOURCEPP_EARLY_RETURN(entryPath);
+ SOURCEPP_EARLY_RETURN(filepath);
- Convert::packFile(handle)->addEntry(filename, reinterpret_cast(buffer), bufferLen, {});
+ Convert::packFile(handle)->addEntry(entryPath, filepath, Convert::optionsFromC(options));
}
-SOURCEPP_API bool vpkpp_remove_entry(vpkpp_pack_file_handle_t handle, const char* filename) {
+SOURCEPP_API void vpkpp_add_entry_from_mem(vpkpp_pack_file_handle_t handle, const char* path, const unsigned char* buffer, size_t bufferLen) {
+ SOURCEPP_EARLY_RETURN(handle);
+ SOURCEPP_EARLY_RETURN(path);
+ SOURCEPP_EARLY_RETURN(buffer);
+ SOURCEPP_EARLY_RETURN(bufferLen);
+
+ Convert::packFile(handle)->addEntry(path, reinterpret_cast(buffer), bufferLen, {});
+}
+
+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_EARLY_RETURN(handle);
+ SOURCEPP_EARLY_RETURN(path);
+ SOURCEPP_EARLY_RETURN(buffer);
+ SOURCEPP_EARLY_RETURN(bufferLen);
+
+ Convert::packFile(handle)->addEntry(path, reinterpret_cast(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(filename, false);
+ SOURCEPP_EARLY_RETURN_VAL(oldPath, false);
+ SOURCEPP_EARLY_RETURN_VAL(newPath, false);
- return Convert::packFile(handle)->removeEntry(filename);
+ return Convert::packFile(handle)->renameEntry(oldPath, newPath);
}
-SOURCEPP_API bool vpkpp_bake(vpkpp_pack_file_handle_t handle, const char* outputDir) {
+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(outputDir, false);
+ SOURCEPP_EARLY_RETURN_VAL(oldDir, false);
+ SOURCEPP_EARLY_RETURN_VAL(newDir, false);
- return Convert::packFile(handle)->bake(outputDir, nullptr);
+ return Convert::packFile(handle)->renameEntry(oldDir, newDir);
}
-SOURCEPP_API bool vpkpp_extract_entry(vpkpp_pack_file_handle_t handle, vpkpp_entry_handle_t entry, const char* filePath) {
+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(entry, false);
- SOURCEPP_EARLY_RETURN_VAL(filePath, false);
+ SOURCEPP_EARLY_RETURN_VAL(path, false);
- return Convert::packFile(handle)->extractEntry(*Convert::entry(entry), filePath);
+ return Convert::packFile(handle)->removeEntry(path);
}
-SOURCEPP_API bool vpkpp_extract_directory(vpkpp_pack_file_handle_t handle, const char* dir, const char* outputDir) {
+SOURCEPP_API int vpkpp_remove_directory(vpkpp_pack_file_handle_t handle, const char* dirName) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
- SOURCEPP_EARLY_RETURN_VAL(dir, false);
- SOURCEPP_EARLY_RETURN_VAL(outputDir, false);
+ SOURCEPP_EARLY_RETURN_VAL(dirName, false);
- return Convert::packFile(handle)->extractDirectory(dir, outputDir);
+ return Convert::packFile(handle)->removeEntry(dirName);
}
-SOURCEPP_API bool vpkpp_extract_all(vpkpp_pack_file_handle_t handle, const char* outputDir, bool createUnderPackFileDir) {
+SOURCEPP_API int vpkpp_bake(vpkpp_pack_file_handle_t handle, const char* outputDir) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
SOURCEPP_EARLY_RETURN_VAL(outputDir, false);
- return Convert::packFile(handle)->extractAll(outputDir, createUnderPackFileDir);
+ return Convert::packFile(handle)->bake(outputDir, nullptr);
}
-SOURCEPP_API bool vpkpp_extract_all_if(vpkpp_pack_file_handle_t handle, const char* outputDir, bool(*predicate)(vpkpp_entry_handle_t)) {
+SOURCEPP_API int vpkpp_bake_with_callback(vpkpp_pack_file_handle_t handle, const char* outputDir, EntryCallback callback) {
SOURCEPP_EARLY_RETURN_VAL(handle, false);
SOURCEPP_EARLY_RETURN_VAL(outputDir, false);
- SOURCEPP_EARLY_RETURN_VAL(predicate, false);
+ SOURCEPP_EARLY_RETURN_VAL(callback, false);
- return Convert::packFile(handle)->extractAll(outputDir, [predicate](const Entry& entry) {
- return predicate(reinterpret_cast(const_cast(&entry)));
+ return Convert::packFile(handle)->bake(outputDir, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
});
}
-SOURCEPP_API vpkpp_entry_handle_array_t vpkpp_get_baked_entries(vpkpp_pack_file_handle_t handle) {
- SOURCEPP_EARLY_RETURN_VAL(handle, VPKPP_ENTRY_HANDLE_ARRAY_INVALID);
+SOURCEPP_API int vpkpp_extract_entry(vpkpp_pack_file_handle_t handle, const char* entryPath, const char* filePath) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, false);
+ SOURCEPP_EARLY_RETURN_VAL(entryPath, false);
+ SOURCEPP_EARLY_RETURN_VAL(filePath, false);
- std::vector heapEntries;
- for (const auto& [dir, entries] : Convert::packFile(handle)->getBakedEntries()) {
- for (const auto& entry : entries) {
- heapEntries.push_back(new Entry{entry});
- }
- }
+ return Convert::packFile(handle)->extractEntry(entryPath, filePath);
+}
- vpkpp_entry_handle_array_t array;
- array.size = static_cast(heapEntries.size());
- array.data = static_cast(std::malloc(sizeof(vpkpp_entry_handle_t) * array.size));
+SOURCEPP_API int vpkpp_extract_directory(vpkpp_pack_file_handle_t handle, const char* dir, const char* outputDir) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, false);
+ SOURCEPP_EARLY_RETURN_VAL(dir, false);
+ SOURCEPP_EARLY_RETURN_VAL(outputDir, false);
- for (size_t i = 0; i < array.size; i++) {
- array.data[i] = heapEntries[i];
- }
- return array;
+ return Convert::packFile(handle)->extractDirectory(dir, outputDir);
}
-SOURCEPP_API vpkpp_entry_handle_array_t vpkpp_get_unbaked_entries(vpkpp_pack_file_handle_t handle) {
- SOURCEPP_EARLY_RETURN_VAL(handle, VPKPP_ENTRY_HANDLE_ARRAY_INVALID);
+SOURCEPP_API int vpkpp_extract_all(vpkpp_pack_file_handle_t handle, const char* outputDir, int createUnderPackFileDir) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, false);
+ SOURCEPP_EARLY_RETURN_VAL(outputDir, false);
- std::vector heapEntries;
- for (const auto& [dir, entries] : Convert::packFile(handle)->getUnbakedEntries()) {
- for (const auto& entry : entries) {
- heapEntries.push_back(new Entry{entry});
- }
- }
+ return Convert::packFile(handle)->extractAll(outputDir, createUnderPackFileDir);
+}
- vpkpp_entry_handle_array_t array;
- array.size = static_cast(heapEntries.size());
- array.data = static_cast(std::malloc(sizeof(vpkpp_entry_handle_t) * array.size));
+SOURCEPP_API int vpkpp_extract_all_if(vpkpp_pack_file_handle_t handle, const char* outputDir, EntryPredicate predicate, int stripSharedDirs) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, false);
+ SOURCEPP_EARLY_RETURN_VAL(outputDir, false);
+ SOURCEPP_EARLY_RETURN_VAL(predicate, false);
- for (size_t i = 0; i < array.size; i++) {
- array.data[i] = heapEntries[i];
- }
- return array;
+ return Convert::packFile(handle)->extractAll(outputDir, [predicate](const std::string& path, const Entry& entry) {
+ return predicate(path.c_str(), const_cast(&entry));
+ }, stripSharedDirs);
}
-SOURCEPP_API size_t vpkpp_get_entry_count(vpkpp_pack_file_handle_t handle, bool includeUnbaked) {
+SOURCEPP_API size_t vpkpp_get_entry_count(vpkpp_pack_file_handle_t handle, int includeUnbaked) {
return Convert::packFile(handle)->getEntryCount(includeUnbaked);
}
-SOURCEPP_API size_t vpkpp_get_filepath(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen) {
- SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
+SOURCEPP_API void vpkpp_run_for_all_entries(vpkpp_pack_file_handle_t handle, EntryCallback operation, int includeUnbaked) {
+ SOURCEPP_EARLY_RETURN(handle);
+ SOURCEPP_EARLY_RETURN(operation);
+
+ return const_cast(Convert::packFile(handle))->runForAllEntries([operation](const std::string& path, const Entry& entry) {
+ return operation(path.c_str(), const_cast(&entry));
+ }, includeUnbaked);
+}
+
+SOURCEPP_API sourcepp_string_t vpkpp_get_filepath(vpkpp_pack_file_handle_t handle) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID);
- return Convert::writeStringToMem(Convert::packFile(handle)->getFilepath(), buffer, bufferLen);
+ return Convert::toString(Convert::packFile(handle)->getFilepath());
}
-SOURCEPP_API size_t vpkpp_get_truncated_filepath(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen) {
- SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
+SOURCEPP_API sourcepp_string_t vpkpp_get_truncated_filepath(vpkpp_pack_file_handle_t handle) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID);
- return Convert::writeStringToMem(Convert::packFile(handle)->getTruncatedFilepath(), buffer, bufferLen);
+ return Convert::toString(Convert::packFile(handle)->getTruncatedFilepath());
}
-SOURCEPP_API size_t vpkpp_get_filename(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen) {
- SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
+SOURCEPP_API sourcepp_string_t vpkpp_get_filename(vpkpp_pack_file_handle_t handle) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID);
- return Convert::writeStringToMem(Convert::packFile(handle)->getFilename(), buffer, bufferLen);
+ return Convert::toString(Convert::packFile(handle)->getFilename());
}
-SOURCEPP_API size_t vpkpp_get_truncated_filename(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen) {
- SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
+SOURCEPP_API sourcepp_string_t vpkpp_get_truncated_filename(vpkpp_pack_file_handle_t handle) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID);
- return Convert::writeStringToMem(Convert::packFile(handle)->getTruncatedFilename(), buffer, bufferLen);
+ return Convert::toString(Convert::packFile(handle)->getTruncatedFilename());
}
-SOURCEPP_API size_t vpkpp_get_filestem(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen) {
- SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
+SOURCEPP_API sourcepp_string_t vpkpp_get_filestem(vpkpp_pack_file_handle_t handle) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID);
- return Convert::writeStringToMem(Convert::packFile(handle)->getFilestem(), buffer, bufferLen);
+ return Convert::toString(Convert::packFile(handle)->getFilestem());
}
-SOURCEPP_API size_t vpkpp_get_truncated_filestem(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen) {
- SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
+SOURCEPP_API sourcepp_string_t vpkpp_get_truncated_filestem(vpkpp_pack_file_handle_t handle) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID);
- return Convert::writeStringToMem(Convert::packFile(handle)->getTruncatedFilestem(), buffer, bufferLen);
+ return Convert::toString(Convert::packFile(handle)->getTruncatedFilestem());
}
-SOURCEPP_API size_t vpkpp_get_supported_entry_attributes(vpkpp_pack_file_handle_t handle, vpkpp_attribute_e* buffer, size_t bufferLen) {
- SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
+SOURCEPP_API vpkpp_attribute_e vpkpp_get_supported_entry_attributes(vpkpp_pack_file_handle_t handle) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, VPKPP_ATTRIBUTE_NONE);
- auto attrs = Convert::packFile(handle)->getSupportedEntryAttributes();
- for (size_t i = 0; i < bufferLen; i++) {
- if (i < attrs.size()) {
- buffer[i] = static_cast(attrs[i]);
- } else {
- buffer[i] = VPKPP_ATTRIBUTE_NONE;
- }
- }
- return std::min(attrs.size(), bufferLen);
+ return static_cast(Convert::packFile(handle)->getSupportedEntryAttributes());
}
-SOURCEPP_API size_t vpkpp_to_string(vpkpp_pack_file_handle_t handle, char* buffer, size_t bufferLen) {
- SOURCEPP_EARLY_RETURN_VAL(handle, 0);
- SOURCEPP_EARLY_RETURN_VAL(buffer, 0);
- SOURCEPP_EARLY_RETURN_VAL(bufferLen, 0);
+SOURCEPP_API sourcepp_string_t vpkpp_to_string(vpkpp_pack_file_handle_t handle) {
+ SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID);
- return Convert::writeStringToMem(std::string{*Convert::packFile(handle)}, buffer, bufferLen);
+ return Convert::toString(std::string{*Convert::packFile(handle)});
}
SOURCEPP_API void vpkpp_close(vpkpp_pack_file_handle_t* handle) {
@@ -314,10 +337,10 @@ SOURCEPP_API void vpkpp_close(vpkpp_pack_file_handle_t* handle) {
*handle = nullptr;
}
-SOURCEPP_API sourcepp_string_t vpkpp_escape_entry_path(const char* path) {
+SOURCEPP_API sourcepp_string_t vpkpp_escape_entry_path_for_write(const char* path) {
SOURCEPP_EARLY_RETURN_VAL(path, SOURCEPP_STRING_INVALID);
- return Convert::toString(PackFile::escapeEntryPath(path));
+ return Convert::toString(PackFile::escapeEntryPathForWrite(path));
}
SOURCEPP_API sourcepp_string_array_t vpkpp_get_supported_file_types() {
diff --git a/lang/c/src/vpkppc/_vpkppc.cmake b/lang/c/src/vpkppc/_vpkppc.cmake
index 04fb5855c..0f115eb58 100644
--- a/lang/c/src/vpkppc/_vpkppc.cmake
+++ b/lang/c/src/vpkppc/_vpkppc.cmake
@@ -4,7 +4,6 @@ add_pretty_parser(vpkpp C
"${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/FPX.h"
"${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/GCF.h"
"${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/GMA.h"
- "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/GRP.h"
"${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/PAK.h"
"${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/PCK.h"
"${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/VPK.h"
@@ -22,7 +21,6 @@ add_pretty_parser(vpkpp C
"${CMAKE_CURRENT_LIST_DIR}/format/FPX.cpp"
"${CMAKE_CURRENT_LIST_DIR}/format/GCF.cpp"
"${CMAKE_CURRENT_LIST_DIR}/format/GMA.cpp"
- "${CMAKE_CURRENT_LIST_DIR}/format/GRP.cpp"
"${CMAKE_CURRENT_LIST_DIR}/format/PAK.cpp"
"${CMAKE_CURRENT_LIST_DIR}/format/PCK.cpp"
"${CMAKE_CURRENT_LIST_DIR}/format/VPK.cpp"
diff --git a/lang/c/src/vpkppc/format/BSP.cpp b/lang/c/src/vpkppc/format/BSP.cpp
index 86786450c..e0f422e0f 100644
--- a/lang/c/src/vpkppc/format/BSP.cpp
+++ b/lang/c/src/vpkppc/format/BSP.cpp
@@ -17,6 +17,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_bsp_open(const char* path) {
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_bsp_open_with_callback(const char* path, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = BSP::open(path, {}, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_bsp_open_with_options(const char* path, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
@@ -26,3 +39,16 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_bsp_open_with_options(const char* pa
}
return packFile.release();
}
+
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_bsp_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = BSP::open(path, Convert::optionsFromC(options), [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
diff --git a/lang/c/src/vpkppc/format/FPX.cpp b/lang/c/src/vpkppc/format/FPX.cpp
index 16e5181cd..34edb8fcf 100644
--- a/lang/c/src/vpkppc/format/FPX.cpp
+++ b/lang/c/src/vpkppc/format/FPX.cpp
@@ -17,6 +17,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_fpx_open(const char* path) {
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_fpx_open_with_callback(const char* path, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = FPX::open(path, {}, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_fpx_open_with_options(const char* path, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
@@ -26,3 +39,16 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_fpx_open_with_options(const char* pa
}
return packFile.release();
}
+
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_fpx_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = FPX::open(path, Convert::optionsFromC(options), [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
diff --git a/lang/c/src/vpkppc/format/GCF.cpp b/lang/c/src/vpkppc/format/GCF.cpp
index 499e9bace..abdd58879 100644
--- a/lang/c/src/vpkppc/format/GCF.cpp
+++ b/lang/c/src/vpkppc/format/GCF.cpp
@@ -17,6 +17,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gcf_open(const char* path) {
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gcf_open_with_callback(const char* path, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = GCF::open(path, {}, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gcf_open_with_options(const char* path, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
@@ -26,3 +39,16 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gcf_open_with_options(const char* pa
}
return packFile.release();
}
+
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gcf_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = GCF::open(path, Convert::optionsFromC(options), [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
diff --git a/lang/c/src/vpkppc/format/GMA.cpp b/lang/c/src/vpkppc/format/GMA.cpp
index 4315a6336..cb72c801f 100644
--- a/lang/c/src/vpkppc/format/GMA.cpp
+++ b/lang/c/src/vpkppc/format/GMA.cpp
@@ -17,6 +17,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gma_open(const char* path) {
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gma_open_with_callback(const char* path, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = GMA::open(path, {}, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gma_open_with_options(const char* path, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
@@ -26,3 +39,16 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gma_open_with_options(const char* pa
}
return packFile.release();
}
+
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_gma_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = GMA::open(path, Convert::optionsFromC(options), [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
diff --git a/lang/c/src/vpkppc/format/GRP.cpp b/lang/c/src/vpkppc/format/GRP.cpp
deleted file mode 100644
index 580e9140b..000000000
--- a/lang/c/src/vpkppc/format/GRP.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include
-
-#include
-
-#include
-#include
-
-using namespace vpkpp;
-
-SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_grp_open(const char* path) {
- SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
-
- auto packFile = GRP::open(path);
- if (!packFile) {
- return nullptr;
- }
- return packFile.release();
-}
-
-SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_grp_open_with_options(const char* path, vpkpp_pack_file_options_t options) {
- SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
-
- auto packFile = GRP::open(path, Convert::optionsFromC(options));
- if (!packFile) {
- return nullptr;
- }
- return packFile.release();
-}
diff --git a/lang/c/src/vpkppc/format/PAK.cpp b/lang/c/src/vpkppc/format/PAK.cpp
index 9547de352..e5b3f48fa 100644
--- a/lang/c/src/vpkppc/format/PAK.cpp
+++ b/lang/c/src/vpkppc/format/PAK.cpp
@@ -17,6 +17,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pak_open(const char* path) {
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pak_open_with_callback(const char* path, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = PAK::open(path, {}, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pak_open_with_options(const char* path, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
@@ -26,3 +39,16 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pak_open_with_options(const char* pa
}
return packFile.release();
}
+
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pak_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = PAK::open(path, Convert::optionsFromC(options), [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
diff --git a/lang/c/src/vpkppc/format/PCK.cpp b/lang/c/src/vpkppc/format/PCK.cpp
index 6bfebeb58..d221d40b4 100644
--- a/lang/c/src/vpkppc/format/PCK.cpp
+++ b/lang/c/src/vpkppc/format/PCK.cpp
@@ -17,6 +17,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pck_open(const char* path) {
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pck_open_with_callback(const char* path, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = PCK::open(path, {}, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pck_open_with_options(const char* path, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
@@ -26,3 +39,16 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pck_open_with_options(const char* pa
}
return packFile.release();
}
+
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_pck_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = PCK::open(path, Convert::optionsFromC(options), [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
diff --git a/lang/c/src/vpkppc/format/VPK.cpp b/lang/c/src/vpkppc/format/VPK.cpp
index 24b41da88..822ad4395 100644
--- a/lang/c/src/vpkppc/format/VPK.cpp
+++ b/lang/c/src/vpkppc/format/VPK.cpp
@@ -20,7 +20,7 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_empty(const char* path) {
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_empty_with_options(const char* path, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
- auto packFile = PackFile::open(path, Convert::optionsFromC(options));
+ auto packFile = VPK::createEmpty(path, Convert::optionsFromC(options));
if (!packFile) {
return nullptr;
}
@@ -38,6 +38,20 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_from_directory(const char
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_from_directory_with_callback(const char* vpkPath, const char* contentPath, bool saveToDir, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(vpkPath, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(contentPath, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = VPK::createFromDirectory(vpkPath, contentPath, saveToDir, {}, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_from_directory_with_options(const char* vpkPath, const char* contentPath, bool saveToDir, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(vpkPath, nullptr);
SOURCEPP_EARLY_RETURN_VAL(contentPath, nullptr);
@@ -49,6 +63,20 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_from_directory_with_optio
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_create_from_directory_with_options_and_callback(const char* vpkPath, const char* contentPath, bool saveToDir, vpkpp_pack_file_options_t options, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(vpkPath, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(contentPath, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = VPK::createFromDirectory(vpkPath, contentPath, saveToDir, Convert::optionsFromC(options), [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_open(const char* path) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
@@ -59,6 +87,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_open(const char* path) {
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_open_with_callback(const char* path, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = VPK::open(path, {}, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_open_with_options(const char* path, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
@@ -69,6 +110,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_open_with_options(const char* pa
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = VPK::open(path, Convert::optionsFromC(options), [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API bool vpkpp_vpk_generate_keypair_files(const char* path) {
SOURCEPP_EARLY_RETURN_VAL(path, false);
diff --git a/lang/c/src/vpkppc/format/VPK_VTMB.cpp b/lang/c/src/vpkppc/format/VPK_VTMB.cpp
index e5bba5b79..22d83edbb 100644
--- a/lang/c/src/vpkppc/format/VPK_VTMB.cpp
+++ b/lang/c/src/vpkppc/format/VPK_VTMB.cpp
@@ -17,6 +17,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_vtmb_open(const char* path) {
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_vtmb_open_with_callback(const char* path, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = VPK_VTMB::open(path, {}, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_vtmb_open_with_options(const char* path, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
@@ -26,3 +39,16 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_vtmb_open_with_options(const cha
}
return packFile.release();
}
+
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpk_vtmb_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = VPK_VTMB::open(path, Convert::optionsFromC(options), [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
diff --git a/lang/c/src/vpkppc/format/ZIP.cpp b/lang/c/src/vpkppc/format/ZIP.cpp
index 28235a3f1..9c066f378 100644
--- a/lang/c/src/vpkppc/format/ZIP.cpp
+++ b/lang/c/src/vpkppc/format/ZIP.cpp
@@ -17,6 +17,19 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_zip_open(const char* path) {
return packFile.release();
}
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_zip_open_with_callback(const char* path, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = ZIP::open(path, {}, [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
+
SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_zip_open_with_options(const char* path, vpkpp_pack_file_options_t options) {
SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
@@ -26,3 +39,16 @@ SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_zip_open_with_options(const char* pa
}
return packFile.release();
}
+
+SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_zip_open_with_options_and_callback(const char* path, vpkpp_pack_file_options_t options, EntryCallback callback) {
+ SOURCEPP_EARLY_RETURN_VAL(path, nullptr);
+ SOURCEPP_EARLY_RETURN_VAL(callback, nullptr);
+
+ auto packFile = ZIP::open(path, Convert::optionsFromC(options), [callback](const std::string& path, const Entry& entry) {
+ callback(path.c_str(), const_cast(&entry));
+ });
+ if (!packFile) {
+ return nullptr;
+ }
+ return packFile.release();
+}
diff --git a/lang/csharp/src/vpkpp/Attribute.cs b/lang/csharp/src/vpkpp/Attribute.cs
index e3fc26437..a4a0e12a9 100644
--- a/lang/csharp/src/vpkpp/Attribute.cs
+++ b/lang/csharp/src/vpkpp/Attribute.cs
@@ -2,12 +2,11 @@ namespace vpkpp
{
public enum Attribute
{
- NONE = -1,
- LENGTH = 0,
- VPK_PRELOADED_DATA_LENGTH,
- ARCHIVE_INDEX,
- CRC32,
- PCK_MD5,
- COUNT,
+ NONE = 0,
+ ARCHIVE_INDEX = 1 << 0,
+ LENGTH = 1 << 1,
+ CRC32 = 1 << 2,
+ PCK_MD5 = 1 << 3,
+ VPK_PRELOADED_DATA = 1 << 4,
}
}
diff --git a/lang/csharp/src/vpkpp/Constants.cs b/lang/csharp/src/vpkpp/Constants.cs
deleted file mode 100644
index f2f9b8690..000000000
--- a/lang/csharp/src/vpkpp/Constants.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace vpkpp
-{
- internal static class Constants
- {
- public const int MaxPath = 4096; // This seems reasonable
-
- public const int MaxFilename = 1024; // Again, seems reasonable
-
- public const int MaxPackFileString = 256; // Definitely works
- }
-}
diff --git a/lang/csharp/src/vpkpp/Entry.cs b/lang/csharp/src/vpkpp/Entry.cs
index 3fd2d6672..624c55ba3 100644
--- a/lang/csharp/src/vpkpp/Entry.cs
+++ b/lang/csharp/src/vpkpp/Entry.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections;
-using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace vpkpp
@@ -8,45 +6,44 @@ namespace vpkpp
internal static unsafe partial class Extern
{
[DllImport("vpkppc")]
- public static extern ulong vpkpp_entry_get_path(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern uint vpkpp_entry_get_flags(void* handle);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_entry_get_parent_path(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern uint vpkpp_entry_get_archive_index(void* handle);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_entry_get_filename(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern ulong vpkpp_entry_get_length(void* handle);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_entry_get_stem(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern ulong vpkpp_entry_get_compressed_length(void* handle);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_entry_get_extension(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern ulong vpkpp_entry_get_offset(void* handle);
[DllImport("vpkppc")]
- public static extern void vpkpp_entry_free(void** handle);
+ public static extern Buffer vpkpp_entry_get_extra_data(void* handle);
[DllImport("vpkppc")]
- public static extern void vpkpp_entry_array_free(EntryHandleArray* array);
- }
+ public static extern uint vpkpp_entry_get_crc32(void* handle);
- [StructLayout(LayoutKind.Sequential)]
- internal unsafe struct EntryHandleArray
- {
- internal long size;
- internal void** data;
+ [DllImport("vpkppc")]
+ public static extern int vpkpp_entry_is_unbaked(void* handle);
+
+ [DllImport("vpkppc")]
+ public static extern void vpkpp_entry_free(void** handle);
}
public class Entry
{
- internal unsafe Entry(void* handle, bool inArray)
+ internal unsafe Entry(void* handle, bool managed)
{
Handle = handle;
- _inArray = inArray;
+ _managed = managed;
}
~Entry()
{
- if (!_inArray)
+ if (!_managed)
{
unsafe
{
@@ -58,135 +55,97 @@ internal unsafe Entry(void* handle, bool inArray)
}
}
- public string Path
+ public uint Flags
{
get
{
- Span stringArray = new sbyte[Constants.MaxPath];
unsafe
{
- fixed (sbyte* stringPtr = stringArray)
- {
- Extern.vpkpp_entry_get_path(Handle, stringPtr, Convert.ToUInt64(stringArray.Length));
- return new string(stringPtr);
- }
+ return Extern.vpkpp_entry_get_flags(Handle);
}
}
}
- public string ParentPath
+ public uint ArchiveIndex
{
get
{
- Span stringArray = new sbyte[Constants.MaxPath];
unsafe
{
- fixed (sbyte* stringPtr = stringArray)
- {
- Extern.vpkpp_entry_get_parent_path(Handle, stringPtr, Convert.ToUInt64(stringArray.Length));
- return new string(stringPtr);
- }
+ return Extern.vpkpp_entry_get_archive_index(Handle);
}
}
}
- public string FileName
+ public ulong Length
{
get
{
- Span stringArray = new sbyte[Constants.MaxFilename];
unsafe
{
- fixed (sbyte* stringPtr = stringArray)
- {
- Extern.vpkpp_entry_get_filename(Handle, stringPtr, Convert.ToUInt64(stringArray.Length));
- return new string(stringPtr);
- }
+ return Extern.vpkpp_entry_get_length(Handle);
}
}
}
- public string Stem
+ public ulong CompressedLength
{
get
{
- Span stringArray = new sbyte[Constants.MaxFilename];
unsafe
{
- fixed (sbyte* stringPtr = stringArray)
- {
- Extern.vpkpp_entry_get_stem(Handle, stringPtr, Convert.ToUInt64(stringArray.Length));
- return new string(stringPtr);
- }
+ return Extern.vpkpp_entry_get_compressed_length(Handle);
}
}
}
- public string Extension
+ public ulong Offset
{
get
{
- Span stringArray = new sbyte[Constants.MaxFilename];
unsafe
{
- fixed (sbyte* stringPtr = stringArray)
- {
- Extern.vpkpp_entry_get_extension(Handle, stringPtr, Convert.ToUInt64(stringArray.Length));
- return new string(stringPtr);
- }
+ return Extern.vpkpp_entry_get_offset(Handle);
}
}
}
- internal unsafe void* Handle;
-
- private readonly bool _inArray;
- }
-
- public class EntryEnumerable : IEnumerable
- {
- internal EntryEnumerable(EntryHandleArray array)
+ public byte[] ExtraData
{
- _array = array;
- }
-
- ~EntryEnumerable()
- {
- unsafe
+ get
{
- fixed (EntryHandleArray* arrayPtr = &_array)
+ unsafe
{
- Extern.vpkpp_entry_array_free(arrayPtr);
+ var buffer = Extern.vpkpp_entry_get_extra_data(Handle);
+ return BufferUtils.ConvertToArrayAndDelete(ref buffer);
}
}
}
- private Entry GetEntryAtPosition(ulong pos)
+ public uint CRC32
{
- unsafe
+ get
{
- return new Entry(_array.data[pos], true);
+ unsafe
+ {
+ return Extern.vpkpp_entry_get_crc32(Handle);
+ }
}
}
- private IEnumerator GetEnumerator()
+ public bool Unbaked
{
- for (long i = 0; i < _array.size; i++)
+ get
{
- yield return GetEntryAtPosition((ulong) i);
+ unsafe
+ {
+ return Convert.ToBoolean(Extern.vpkpp_entry_is_unbaked(Handle));
+ }
}
}
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
+ internal unsafe void* Handle;
- private EntryHandleArray _array;
+ private readonly bool _managed;
}
}
diff --git a/lang/csharp/src/vpkpp/Format/BSP.cs b/lang/csharp/src/vpkpp/Format/BSP.cs
index 1557affa1..cd7574a4f 100644
--- a/lang/csharp/src/vpkpp/Format/BSP.cs
+++ b/lang/csharp/src/vpkpp/Format/BSP.cs
@@ -1,14 +1,23 @@
+using System;
using System.Runtime.InteropServices;
namespace vpkpp.Format
{
+ using EntryCallback = Action;
+
internal static unsafe partial class Extern
{
[DllImport("vpkppc")]
public static extern void* vpkpp_bsp_open([MarshalAs(UnmanagedType.LPStr)] string path);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_bsp_open_with_callback([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern void* vpkpp_bsp_open_with_options([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options);
+
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_bsp_open_with_options_and_callback([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options, IntPtr callback);
}
public class BSP : PackFile
@@ -24,6 +33,19 @@ private protected unsafe BSP(void* handle) : base(handle) {}
}
}
+ public new static BSP? Open(string path, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_bsp_open_with_callback(path, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new BSP(handle);
+ }
+ }
+
public new static BSP? Open(string path, PackFileOptions options)
{
unsafe
@@ -32,5 +54,18 @@ private protected unsafe BSP(void* handle) : base(handle) {}
return handle == null ? null : new BSP(handle);
}
}
+
+ public new static BSP? Open(string path, PackFileOptions options, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_bsp_open_with_options_and_callback(path, options, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new BSP(handle);
+ }
+ }
}
}
diff --git a/lang/csharp/src/vpkpp/Format/FPX.cs b/lang/csharp/src/vpkpp/Format/FPX.cs
index a9e351b92..c7d3771d2 100644
--- a/lang/csharp/src/vpkpp/Format/FPX.cs
+++ b/lang/csharp/src/vpkpp/Format/FPX.cs
@@ -1,14 +1,23 @@
-using System.Runtime.InteropServices;
+using System;
+using System.Runtime.InteropServices;
namespace vpkpp.Format
{
+ using EntryCallback = Action;
+
internal static unsafe partial class Extern
{
[DllImport("vpkppc")]
public static extern void* vpkpp_fpx_open([MarshalAs(UnmanagedType.LPStr)] string path);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_fpx_open_with_callback([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern void* vpkpp_fpx_open_with_options([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options);
+
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_fpx_open_with_options_and_callback([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options, IntPtr callback);
}
public class FPX : PackFile
@@ -24,6 +33,19 @@ private protected unsafe FPX(void* handle) : base(handle) {}
}
}
+ public new static FPX? Open(string path, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_fpx_open_with_callback(path, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new FPX(handle);
+ }
+ }
+
public new static FPX? Open(string path, PackFileOptions options)
{
unsafe
@@ -32,5 +54,18 @@ private protected unsafe FPX(void* handle) : base(handle) {}
return handle == null ? null : new FPX(handle);
}
}
+
+ public new static FPX? Open(string path, PackFileOptions options, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_fpx_open_with_options_and_callback(path, options, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new FPX(handle);
+ }
+ }
}
}
diff --git a/lang/csharp/src/vpkpp/Format/GCF.cs b/lang/csharp/src/vpkpp/Format/GCF.cs
index 68a253380..30ebeb6c1 100644
--- a/lang/csharp/src/vpkpp/Format/GCF.cs
+++ b/lang/csharp/src/vpkpp/Format/GCF.cs
@@ -1,14 +1,23 @@
+using System;
using System.Runtime.InteropServices;
namespace vpkpp.Format
{
+ using EntryCallback = Action;
+
internal static unsafe partial class Extern
{
[DllImport("vpkppc")]
public static extern void* vpkpp_gcf_open([MarshalAs(UnmanagedType.LPStr)] string path);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_gcf_open_with_callback([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern void* vpkpp_gcf_open_with_options([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options);
+
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_gcf_open_with_options_and_callback([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options, IntPtr callback);
}
public class GCF : PackFile
@@ -24,6 +33,19 @@ private protected unsafe GCF(void* handle) : base(handle) {}
}
}
+ public new static GCF? Open(string path, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_gcf_open_with_callback(path, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new GCF(handle);
+ }
+ }
+
public new static GCF? Open(string path, PackFileOptions options)
{
unsafe
@@ -32,5 +54,18 @@ private protected unsafe GCF(void* handle) : base(handle) {}
return handle == null ? null : new GCF(handle);
}
}
+
+ public new static GCF? Open(string path, PackFileOptions options, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_gcf_open_with_options_and_callback(path, options, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new GCF(handle);
+ }
+ }
}
}
diff --git a/lang/csharp/src/vpkpp/Format/GMA.cs b/lang/csharp/src/vpkpp/Format/GMA.cs
index a450141a8..d4a6e401f 100644
--- a/lang/csharp/src/vpkpp/Format/GMA.cs
+++ b/lang/csharp/src/vpkpp/Format/GMA.cs
@@ -1,14 +1,23 @@
+using System;
using System.Runtime.InteropServices;
namespace vpkpp.Format
{
+ using EntryCallback = Action;
+
internal static unsafe partial class Extern
{
[DllImport("vpkppc")]
public static extern void* vpkpp_gma_open([MarshalAs(UnmanagedType.LPStr)] string path);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_gma_open_with_callback([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern void* vpkpp_gma_open_with_options([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options);
+
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_gma_open_with_options_and_callback([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options, IntPtr callback);
}
public class GMA : PackFile
@@ -24,6 +33,19 @@ private protected unsafe GMA(void* handle) : base(handle) {}
}
}
+ public new static GMA? Open(string path, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_gma_open_with_callback(path, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new GMA(handle);
+ }
+ }
+
public new static GMA? Open(string path, PackFileOptions options)
{
unsafe
@@ -32,5 +54,18 @@ private protected unsafe GMA(void* handle) : base(handle) {}
return handle == null ? null : new GMA(handle);
}
}
+
+ public new static GMA? Open(string path, PackFileOptions options, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_gma_open_with_options_and_callback(path, options, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new GMA(handle);
+ }
+ }
}
}
diff --git a/lang/csharp/src/vpkpp/Format/GRP.cs b/lang/csharp/src/vpkpp/Format/GRP.cs
deleted file mode 100644
index 3cda91a7c..000000000
--- a/lang/csharp/src/vpkpp/Format/GRP.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace vpkpp.Format
-{
- internal static unsafe partial class Extern
- {
- [DllImport("vpkppc")]
- public static extern void* vpkpp_grp_open([MarshalAs(UnmanagedType.LPStr)] string path);
-
- [DllImport("vpkppc")]
- public static extern void* vpkpp_grp_open_with_options([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options);
- }
-
- public class GRP : PackFile
- {
- private protected unsafe GRP(void* handle) : base(handle) {}
-
- public new static GRP? Open(string path)
- {
- unsafe
- {
- var handle = Extern.vpkpp_grp_open(path);
- return handle == null ? null : new GRP(handle);
- }
- }
-
- public new static GRP? Open(string path, PackFileOptions options)
- {
- unsafe
- {
- var handle = Extern.vpkpp_grp_open_with_options(path, options);
- return handle == null ? null : new GRP(handle);
- }
- }
- }
-}
diff --git a/lang/csharp/src/vpkpp/Format/PAK.cs b/lang/csharp/src/vpkpp/Format/PAK.cs
index 676650aa8..21d86a7c2 100644
--- a/lang/csharp/src/vpkpp/Format/PAK.cs
+++ b/lang/csharp/src/vpkpp/Format/PAK.cs
@@ -1,14 +1,23 @@
+using System;
using System.Runtime.InteropServices;
namespace vpkpp.Format
{
+ using EntryCallback = Action;
+
internal static unsafe partial class Extern
{
[DllImport("vpkppc")]
public static extern void* vpkpp_pak_open([MarshalAs(UnmanagedType.LPStr)] string path);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_pak_open_with_callback([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern void* vpkpp_pak_open_with_options([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options);
+
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_pak_open_with_options_and_callback([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options, IntPtr callback);
}
public class PAK : PackFile
@@ -24,6 +33,19 @@ private protected unsafe PAK(void* handle) : base(handle) {}
}
}
+ public new static PAK? Open(string path, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_pak_open_with_callback(path, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new PAK(handle);
+ }
+ }
+
public new static PAK? Open(string path, PackFileOptions options)
{
unsafe
@@ -32,5 +54,18 @@ private protected unsafe PAK(void* handle) : base(handle) {}
return handle == null ? null : new PAK(handle);
}
}
+
+ public new static PAK? Open(string path, PackFileOptions options, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_pak_open_with_options_and_callback(path, options, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new PAK(handle);
+ }
+ }
}
}
diff --git a/lang/csharp/src/vpkpp/Format/PCK.cs b/lang/csharp/src/vpkpp/Format/PCK.cs
index 8caa7d5fa..61b1c328f 100644
--- a/lang/csharp/src/vpkpp/Format/PCK.cs
+++ b/lang/csharp/src/vpkpp/Format/PCK.cs
@@ -1,14 +1,23 @@
+using System;
using System.Runtime.InteropServices;
namespace vpkpp.Format
{
+ using EntryCallback = Action;
+
internal static unsafe partial class Extern
{
[DllImport("vpkppc")]
public static extern void* vpkpp_pck_open([MarshalAs(UnmanagedType.LPStr)] string path);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_pck_open_with_callback([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern void* vpkpp_pck_open_with_options([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options);
+
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_pck_open_with_options_and_callback([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options, IntPtr callback);
}
public class PCK : PackFile
@@ -24,6 +33,19 @@ private protected unsafe PCK(void* handle) : base(handle) {}
}
}
+ public new static PCK? Open(string path, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_pck_open_with_callback(path, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new PCK(handle);
+ }
+ }
+
public new static PCK? Open(string path, PackFileOptions options)
{
unsafe
@@ -32,5 +54,18 @@ private protected unsafe PCK(void* handle) : base(handle) {}
return handle == null ? null : new PCK(handle);
}
}
+
+ public new static PCK? Open(string path, PackFileOptions options, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_pck_open_with_options_and_callback(path, options, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new PCK(handle);
+ }
+ }
}
}
diff --git a/lang/csharp/src/vpkpp/Format/VPK.cs b/lang/csharp/src/vpkpp/Format/VPK.cs
index 788a07fcc..e9f522e0f 100644
--- a/lang/csharp/src/vpkpp/Format/VPK.cs
+++ b/lang/csharp/src/vpkpp/Format/VPK.cs
@@ -5,6 +5,8 @@
namespace vpkpp.Format
{
+ using EntryCallback = Action;
+
internal static unsafe partial class Extern
{
[DllImport("vpkppc")]
@@ -22,9 +24,15 @@ internal static unsafe partial class Extern
[DllImport("vpkppc")]
public static extern void* vpkpp_vpk_open([MarshalAs(UnmanagedType.LPStr)] string path);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_vpk_open_with_callback([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern void* vpkpp_vpk_open_with_options([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_vpk_open_with_options_and_callback([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern byte vpkpp_vpk_generate_keypair_files([MarshalAs(UnmanagedType.LPStr)] string path);
@@ -90,6 +98,19 @@ private unsafe VPK(void* handle) : base(handle) {}
}
}
+ public new static VPK? Open(string path, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_vpk_open_with_callback(path, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new VPK(handle);
+ }
+ }
+
public new static VPK? Open(string path, PackFileOptions options)
{
unsafe
@@ -99,6 +120,19 @@ private unsafe VPK(void* handle) : base(handle) {}
}
}
+ public new static VPK? Open(string path, PackFileOptions options, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_vpk_open_with_options_and_callback(path, options, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new VPK(handle);
+ }
+ }
+
public static bool GenerateKeyPairFiles(string path)
{
unsafe
diff --git a/lang/csharp/src/vpkpp/Format/VPK_VTMB.cs b/lang/csharp/src/vpkpp/Format/VPK_VTMB.cs
index 45be95d14..c0df55b70 100644
--- a/lang/csharp/src/vpkpp/Format/VPK_VTMB.cs
+++ b/lang/csharp/src/vpkpp/Format/VPK_VTMB.cs
@@ -1,14 +1,23 @@
+using System;
using System.Runtime.InteropServices;
namespace vpkpp.Format
{
+ using EntryCallback = Action;
+
internal static unsafe partial class Extern
{
[DllImport("vpkppc")]
public static extern void* vpkpp_vpk_vtmb_open([MarshalAs(UnmanagedType.LPStr)] string path);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_vpk_vtmb_open_with_callback([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern void* vpkpp_vpk_vtmb_open_with_options([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options);
+
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_vpk_vtmb_open_with_options_and_callback([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options, IntPtr callback);
}
public class VPK_VTMB : PackFile
@@ -24,6 +33,19 @@ private protected unsafe VPK_VTMB(void* handle) : base(handle) {}
}
}
+ public new static VPK_VTMB? Open(string path, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_vpk_vtmb_open_with_callback(path, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new VPK_VTMB(handle);
+ }
+ }
+
public new static VPK_VTMB? Open(string path, PackFileOptions options)
{
unsafe
@@ -32,5 +54,18 @@ private protected unsafe VPK_VTMB(void* handle) : base(handle) {}
return handle == null ? null : new VPK_VTMB(handle);
}
}
+
+ public new static VPK_VTMB? Open(string path, PackFileOptions options, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_vpk_vtmb_open_with_options_and_callback(path, options, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new VPK_VTMB(handle);
+ }
+ }
}
}
diff --git a/lang/csharp/src/vpkpp/Format/ZIP.cs b/lang/csharp/src/vpkpp/Format/ZIP.cs
index 0a9d4ead1..d1d8192a4 100644
--- a/lang/csharp/src/vpkpp/Format/ZIP.cs
+++ b/lang/csharp/src/vpkpp/Format/ZIP.cs
@@ -1,14 +1,23 @@
+using System;
using System.Runtime.InteropServices;
namespace vpkpp.Format
{
+ using EntryCallback = Action;
+
internal static unsafe partial class Extern
{
[DllImport("vpkppc")]
public static extern void* vpkpp_zip_open([MarshalAs(UnmanagedType.LPStr)] string path);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_zip_open_with_callback([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern void* vpkpp_zip_open_with_options([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options);
+
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_zip_open_with_options_and_callback([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options, IntPtr callback);
}
public class ZIP : PackFile
@@ -24,6 +33,19 @@ private protected unsafe ZIP(void* handle) : base(handle) {}
}
}
+ public new static ZIP? Open(string path, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_zip_open_with_callback(path, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new ZIP(handle);
+ }
+ }
+
public new static ZIP? Open(string path, PackFileOptions options)
{
unsafe
@@ -32,5 +54,18 @@ private protected unsafe ZIP(void* handle) : base(handle) {}
return handle == null ? null : new ZIP(handle);
}
}
+
+ public new static ZIP? Open(string path, PackFileOptions options, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_zip_open_with_options_and_callback(path, options, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new ZIP(handle);
+ }
+ }
}
}
diff --git a/lang/csharp/src/vpkpp/PackFile.cs b/lang/csharp/src/vpkpp/PackFile.cs
index e2831967f..ee28dbaae 100644
--- a/lang/csharp/src/vpkpp/PackFile.cs
+++ b/lang/csharp/src/vpkpp/PackFile.cs
@@ -1,18 +1,33 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace vpkpp
{
+ using EntryCallback = Action;
+
+ using EntryPredicate = Func;
+
+ internal unsafe delegate void EntryCallbackNative(string path, void* entry);
+
+ internal unsafe delegate int EntryPredicateNative(string path, void* entry);
+
internal static unsafe partial class Extern
{
[DllImport("vpkppc")]
public static extern void* vpkpp_open([MarshalAs(UnmanagedType.LPStr)] string path);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_open_with_callback([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern void* vpkpp_open_with_options([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options);
+ [DllImport("vpkppc")]
+ public static extern void* vpkpp_open_with_options_and_callback([MarshalAs(UnmanagedType.LPStr)] string path, PackFileOptions options, IntPtr callback);
+
[DllImport("vpkppc")]
public static extern PackFileType vpkpp_get_type(void* handle);
@@ -20,103 +35,112 @@ internal static unsafe partial class Extern
public static extern PackFileOptions vpkpp_get_options(void* handle);
[DllImport("vpkppc")]
- public static extern byte vpkpp_has_entry_checksums(void* handle);
+ public static extern int vpkpp_has_entry_checksums(void* handle);
[DllImport("vpkppc")]
public static extern StringArray vpkpp_verify_entry_checksums(void* handle);
[DllImport("vpkppc")]
- public static extern byte vpkpp_has_pack_file_checksum(void* handle);
+ public static extern int vpkpp_has_pack_file_checksum(void* handle);
[DllImport("vpkppc")]
- public static extern byte vpkpp_verify_pack_file_checksum(void* handle);
+ public static extern int vpkpp_verify_pack_file_checksum(void* handle);
[DllImport("vpkppc")]
- public static extern byte vpkpp_has_pack_file_signature(void* handle);
+ public static extern int vpkpp_has_pack_file_signature(void* handle);
[DllImport("vpkppc")]
- public static extern byte vpkpp_verify_pack_file_signature(void* handle);
+ public static extern int vpkpp_verify_pack_file_signature(void* handle);
[DllImport("vpkppc")]
- public static extern byte vpkpp_is_case_sensitive(void* handle);
+ public static extern int vpkpp_is_case_sensitive(void* handle);
[DllImport("vpkppc")]
- public static extern byte vpkpp_has_entry(void* handle, [MarshalAs(UnmanagedType.LPStr)] string filename, byte includeUnbaked);
+ public static extern int vpkpp_has_entry(void* handle, [MarshalAs(UnmanagedType.LPStr)] string path, int includeUnbaked);
[DllImport("vpkppc")]
- public static extern void* vpkpp_find_entry(void* handle, [MarshalAs(UnmanagedType.LPStr)] string filename, byte includeUnbaked);
+ public static extern void* vpkpp_find_entry(void* handle, [MarshalAs(UnmanagedType.LPStr)] string path, int includeUnbaked);
[DllImport("vpkppc")]
- public static extern Buffer vpkpp_read_entry(void* handle, void* entry);
+ public static extern Buffer vpkpp_read_entry(void* handle, [MarshalAs(UnmanagedType.LPStr)] string path);
[DllImport("vpkppc")]
- public static extern String vpkpp_read_entry_text(void* handle, void* entry);
+ public static extern String vpkpp_read_entry_text(void* handle, [MarshalAs(UnmanagedType.LPStr)] string path);
[DllImport("vpkppc")]
- public static extern byte vpkpp_is_read_only(void* handle);
+ public static extern int vpkpp_is_read_only(void* handle);
[DllImport("vpkppc")]
- public static extern void vpkpp_add_entry_from_file(void* handle, [MarshalAs(UnmanagedType.LPStr)] string filename, [MarshalAs(UnmanagedType.LPStr)] string pathToFile);
+ public static extern void vpkpp_add_entry_from_file(void* handle, [MarshalAs(UnmanagedType.LPStr)] string entryPath, [MarshalAs(UnmanagedType.LPStr)] string filepath);
[DllImport("vpkppc")]
- public static extern void vpkpp_add_entry_from_mem(void* handle, [MarshalAs(UnmanagedType.LPStr)] string filename, byte* buffer, ulong bufferLen);
+ 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 byte vpkpp_remove_entry(void* handle, [MarshalAs(UnmanagedType.LPStr)] string filename);
+ public static extern int vpkpp_rename_entry(void* handle, [MarshalAs(UnmanagedType.LPStr)] string oldPath, [MarshalAs(UnmanagedType.LPStr)] string newPath);
[DllImport("vpkppc")]
- public static extern byte vpkpp_bake(void* handle, [MarshalAs(UnmanagedType.LPStr)] string outputDir);
+ public static extern int vpkpp_rename_directory(void* handle, [MarshalAs(UnmanagedType.LPStr)] string oldDir, [MarshalAs(UnmanagedType.LPStr)] string newDir);
[DllImport("vpkppc")]
- public static extern byte vpkpp_extract_entry(void* handle, void* entry, [MarshalAs(UnmanagedType.LPStr)] string filePath);
+ public static extern int vpkpp_remove_entry(void* handle, [MarshalAs(UnmanagedType.LPStr)] string path);
[DllImport("vpkppc")]
- public static extern byte vpkpp_extract_directory(void* handle, [MarshalAs(UnmanagedType.LPStr)] string dir, [MarshalAs(UnmanagedType.LPStr)] string outputDir);
+ public static extern ulong vpkpp_remove_directory(void* handle, [MarshalAs(UnmanagedType.LPStr)] string dirName);
[DllImport("vpkppc")]
- public static extern byte vpkpp_extract_all(void* handle, [MarshalAs(UnmanagedType.LPStr)] string outputDir, byte createUnderPackFileDir);
+ public static extern int vpkpp_bake(void* handle, [MarshalAs(UnmanagedType.LPStr)] string outputDir);
[DllImport("vpkppc")]
- public static extern byte vpkpp_extract_all_if(void* handle, [MarshalAs(UnmanagedType.LPStr)] string outputDir, IntPtr predicate);
+ public static extern int vpkpp_bake_with_callback(void* handle, [MarshalAs(UnmanagedType.LPStr)] string outputDir, IntPtr callback);
[DllImport("vpkppc")]
- public static extern EntryHandleArray vpkpp_get_baked_entries(void* handle);
+ public static extern int vpkpp_extract_entry(void* handle, [MarshalAs(UnmanagedType.LPStr)] string entryPath, [MarshalAs(UnmanagedType.LPStr)] string filepath);
[DllImport("vpkppc")]
- public static extern EntryHandleArray vpkpp_get_unbaked_entries(void* handle);
+ public static extern int vpkpp_extract_directory(void* handle, [MarshalAs(UnmanagedType.LPStr)] string dir, [MarshalAs(UnmanagedType.LPStr)] string outputDir);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_get_entry_count(void* handle, byte includeUnbaked);
+ public static extern int vpkpp_extract_all(void* handle, [MarshalAs(UnmanagedType.LPStr)] string outputDir, int createUnderPackFileDir);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_get_filepath(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern int vpkpp_extract_all_if(void* handle, [MarshalAs(UnmanagedType.LPStr)] string outputDir, IntPtr predicate, int stripSharedDirs);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_get_truncated_filepath(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern ulong vpkpp_get_entry_count(void* handle, int includeUnbaked);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_get_filename(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern void vpkpp_run_for_all_entries(void* handle, IntPtr operation, int includeUnbaked);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_get_truncated_filename(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern String vpkpp_get_filepath(void* handle);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_get_filestem(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern String vpkpp_get_truncated_filepath(void* handle);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_get_truncated_filestem(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern String vpkpp_get_filename(void* handle);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_get_supported_entry_attributes(void* handle, Attribute* buffer, ulong bufferLen);
+ public static extern String vpkpp_get_truncated_filename(void* handle);
[DllImport("vpkppc")]
- public static extern ulong vpkpp_to_string(void* handle, sbyte* buffer, ulong bufferLen);
+ public static extern String vpkpp_get_filestem(void* handle);
+
+ [DllImport("vpkppc")]
+ public static extern String vpkpp_get_truncated_filestem(void* handle);
+
+ [DllImport("vpkppc")]
+ public static extern Attribute vpkpp_get_supported_entry_attributes(void* handle);
+
+ [DllImport("vpkppc")]
+ public static extern String vpkpp_to_string(void* handle);
[DllImport("vpkppc")]
public static extern void vpkpp_close(void** handle);
[DllImport("vpkppc")]
- public static extern String vpkpp_escape_entry_path([MarshalAs(UnmanagedType.LPStr)] string path);
+ public static extern String vpkpp_escape_entry_path_for_write([MarshalAs(UnmanagedType.LPStr)] string path);
[DllImport("vpkppc")]
public static extern StringArray vpkpp_get_supported_file_types();
@@ -149,6 +173,19 @@ private protected unsafe PackFile(void* handle)
}
}
+ public static PackFile? Open(string path, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_open_with_callback(path, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new PackFile(handle);
+ }
+ }
+
public static PackFile? Open(string path, PackFileOptions options)
{
unsafe
@@ -158,9 +195,22 @@ private protected unsafe PackFile(void* handle)
}
}
- public static string EscapeEntryPath(string path)
+ public static PackFile? Open(string path, PackFileOptions options, EntryCallback callback)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ callback(path, new Entry(entry, true));
+ };
+ var handle = Extern.vpkpp_open_with_options_and_callback(path, options, Marshal.GetFunctionPointerForDelegate(callbackNative));
+ return handle == null ? null : new PackFile(handle);
+ }
+ }
+
+ public static string EscapeEntryPathForWrite(string path)
{
- var str = Extern.vpkpp_escape_entry_path(path);
+ var str = Extern.vpkpp_escape_entry_path_for_write(path);
return StringUtils.ConvertToStringAndDelete(ref str);
}
@@ -219,140 +269,157 @@ public bool VerifyPackFileSignature()
}
}
- public bool HasEntry(string filename, bool includeUnbaked = true)
+ public bool HasEntry(string path, bool includeUnbaked = true)
{
unsafe
{
- return Convert.ToBoolean(Extern.vpkpp_has_entry(Handle, filename, Convert.ToByte(includeUnbaked)));
+ return Convert.ToBoolean(Extern.vpkpp_has_entry(Handle, path, Convert.ToInt32(includeUnbaked)));
}
}
- public Entry? FindEntry(string filename, bool includeUnbaked = true)
+ public Entry? FindEntry(string path, bool includeUnbaked = true)
{
unsafe
{
- var entry = Extern.vpkpp_find_entry(Handle, filename, Convert.ToByte(includeUnbaked));
+ var entry = Extern.vpkpp_find_entry(Handle, path, Convert.ToInt32(includeUnbaked));
return entry == null ? null : new Entry(entry, false);
}
}
- public byte[]? ReadEntry(Entry entry)
+ public byte[]? ReadEntry(string path)
{
unsafe
{
- var buffer = Extern.vpkpp_read_entry(Handle, entry.Handle);
+ var buffer = Extern.vpkpp_read_entry(Handle, path);
return buffer.size < 0 ? null : BufferUtils.ConvertToArrayAndDelete(ref buffer);
}
}
- public string? ReadEntryText(Entry entry)
+ public string? ReadEntryText(string path)
{
unsafe
{
- var str = Extern.vpkpp_read_entry_text(Handle, entry.Handle);
+ var str = Extern.vpkpp_read_entry_text(Handle, path);
return str.size < 0 ? null : StringUtils.ConvertToStringAndDelete(ref str);
}
}
- public void AddEntry(string filename, string pathToFile)
+ public void AddEntry(string entryPath, string filepath)
{
unsafe
{
- Extern.vpkpp_add_entry_from_file(Handle, filename, pathToFile);
+ Extern.vpkpp_add_entry_from_file(Handle, entryPath, filepath);
}
}
- public void AddEntry(string filename, byte[] buffer)
+ public void AddEntry(string path, byte[] buffer)
{
unsafe
{
fixed (byte* bufferPtr = buffer)
{
- Extern.vpkpp_add_entry_from_mem(Handle, filename, bufferPtr, (ulong) buffer.LongLength);
+ Extern.vpkpp_add_entry_from_mem(Handle, path, bufferPtr, (ulong) buffer.LongLength);
}
}
}
- public void AddEntry(string filename, IEnumerable buffer)
+ public void AddEntry(string path, IEnumerable buffer)
{
unsafe
{
var data = buffer.ToArray();
fixed (byte* bufferPtr = data)
{
- Extern.vpkpp_add_entry_from_mem(Handle, filename, bufferPtr, (ulong) data.LongLength);
+ Extern.vpkpp_add_entry_from_mem(Handle, path, bufferPtr, (ulong) data.LongLength);
}
}
}
- public bool RemoveEntry(string filename)
+ public bool RenameEntry(string oldPath, string newPath)
{
unsafe
{
- return Convert.ToBoolean(Extern.vpkpp_remove_entry(Handle, filename));
+ return Convert.ToBoolean(Extern.vpkpp_rename_entry(Handle, oldPath, newPath));
}
}
- public bool Bake(string outputDir)
+ public bool RenameDirectory(string oldDir, string newDir)
{
unsafe
{
- return Convert.ToBoolean(Extern.vpkpp_bake(Handle, outputDir));
+ return Convert.ToBoolean(Extern.vpkpp_rename_directory(Handle, oldDir, newDir));
}
}
- public bool ExtractEntry(Entry entry, string filePath)
+ public bool RemoveEntry(string path)
{
unsafe
{
- return Convert.ToBoolean(Extern.vpkpp_extract_entry(Handle, entry.Handle, filePath));
+ return Convert.ToBoolean(Extern.vpkpp_remove_entry(Handle, path));
}
}
- public bool ExtractDirectory(string dir, string outputDir)
+ public ulong RemoveDirectory(string dirName)
{
unsafe
{
- return Convert.ToBoolean(Extern.vpkpp_extract_directory(Handle, dir, outputDir));
+ return Extern.vpkpp_remove_directory(Handle, dirName);
}
}
- public bool ExtractAll(string outputDir, bool createUnderPackFileDir = true)
+ public bool Bake(string outputDir)
{
unsafe
{
- return Convert.ToBoolean(Extern.vpkpp_extract_all(Handle, outputDir, Convert.ToByte(createUnderPackFileDir)));
+ return Convert.ToBoolean(Extern.vpkpp_bake(Handle, outputDir));
}
}
- private unsafe delegate byte ExtractAllPredicateNative(void* entry);
-
- public bool ExtractAll(string outputDir, Func predicate)
+ public bool Bake(string outputDir, EntryCallback callback)
{
unsafe
{
- ExtractAllPredicateNative predicateWrapper = (entry) =>
+ EntryCallbackNative callbackNative = (path, entry) =>
{
- // HACK: tell the entry its in an array so it doesn't kill itself
- return Convert.ToByte(predicate(new Entry(entry, true)));
+ callback(path, new Entry(entry, true));
};
- return Convert.ToBoolean(Extern.vpkpp_extract_all_if(Handle, outputDir, Marshal.GetFunctionPointerForDelegate(predicateWrapper)));
+ return Convert.ToBoolean(Extern.vpkpp_bake_with_callback(Handle, outputDir, Marshal.GetFunctionPointerForDelegate(callbackNative)));
+ }
+ }
+
+ public bool ExtractEntry(string entryPath, string filepath)
+ {
+ unsafe
+ {
+ return Convert.ToBoolean(Extern.vpkpp_extract_entry(Handle, entryPath, filepath));
+ }
+ }
+
+ public bool ExtractDirectory(string dir, string outputDir)
+ {
+ unsafe
+ {
+ return Convert.ToBoolean(Extern.vpkpp_extract_directory(Handle, dir, outputDir));
}
}
- public EntryEnumerable GetBakedEntries()
+ public bool ExtractAll(string outputDir, bool createUnderPackFileDir = true)
{
unsafe
{
- return new EntryEnumerable(Extern.vpkpp_get_baked_entries(Handle));
+ return Convert.ToBoolean(Extern.vpkpp_extract_all(Handle, outputDir, Convert.ToInt32(createUnderPackFileDir)));
}
}
- public EntryEnumerable GetUnbakedEntries()
+ public bool ExtractAll(string outputDir, EntryPredicate predicate, bool stripSharedDirs = true)
{
unsafe
{
- return new EntryEnumerable(Extern.vpkpp_get_unbaked_entries(Handle));
+ EntryPredicateNative predicateNative = (path, entry) =>
+ {
+ return Convert.ToInt32(predicate(path, new Entry(entry, true)));
+ };
+ return Convert.ToBoolean(Extern.vpkpp_extract_all_if(Handle, outputDir, Marshal.GetFunctionPointerForDelegate(predicateNative), Convert.ToInt32(stripSharedDirs));
}
}
@@ -360,7 +427,19 @@ public ulong GetEntryCount(bool includeUnbaked = true)
{
unsafe
{
- return Extern.vpkpp_get_entry_count(Handle, Convert.ToByte(includeUnbaked));
+ return Extern.vpkpp_get_entry_count(Handle, Convert.ToInt32(includeUnbaked));
+ }
+ }
+
+ public void RunForAllEntries(EntryCallback operation, bool includeUnbaked = true)
+ {
+ unsafe
+ {
+ EntryCallbackNative callbackNative = (path, entry) =>
+ {
+ operation(path, new Entry(entry, true));
+ };
+ Extern.vpkpp_run_for_all_entries(Handle, Marshal.GetFunctionPointerForDelegate(callbackNative), Convert.ToInt32(includeUnbaked));
}
}
@@ -368,9 +447,8 @@ public override string ToString()
{
unsafe
{
- var stringPtr = stackalloc sbyte[Constants.MaxPackFileString];
- Extern.vpkpp_to_string(Handle, stringPtr, Convert.ToUInt64(Constants.MaxPackFileString));
- return new string(stringPtr);
+ var str = Extern.vpkpp_to_string(Handle);
+ return StringUtils.ConvertToStringAndDelete(ref str);
}
}
@@ -422,14 +500,10 @@ public string FilePath
{
get
{
- Span stringArray = new sbyte[Constants.MaxPath];
unsafe
{
- fixed (sbyte* stringPtr = stringArray)
- {
- Extern.vpkpp_get_filepath(Handle, stringPtr, Convert.ToUInt64(stringArray.Length));
- return new string(stringPtr);
- }
+ var str = Extern.vpkpp_get_filepath(Handle);
+ return StringUtils.ConvertToStringAndDelete(ref str);
}
}
}
@@ -438,14 +512,10 @@ public string TruncatedFilePath
{
get
{
- Span stringArray = new sbyte[Constants.MaxPath];
unsafe
{
- fixed (sbyte* stringPtr = stringArray)
- {
- Extern.vpkpp_get_truncated_filepath(Handle, stringPtr, Convert.ToUInt64(stringArray.Length));
- return new string(stringPtr);
- }
+ var str = Extern.vpkpp_get_truncated_filepath(Handle);
+ return StringUtils.ConvertToStringAndDelete(ref str);
}
}
}
@@ -454,14 +524,10 @@ public string FileName
{
get
{
- Span stringArray = new sbyte[Constants.MaxFilename];
unsafe
{
- fixed (sbyte* stringPtr = stringArray)
- {
- Extern.vpkpp_get_filename(Handle, stringPtr, Convert.ToUInt64(stringArray.Length));
- return new string(stringPtr);
- }
+ var str = Extern.vpkpp_get_filename(Handle);
+ return StringUtils.ConvertToStringAndDelete(ref str);
}
}
}
@@ -470,14 +536,10 @@ public string TruncatedFileName
{
get
{
- Span stringArray = new sbyte[Constants.MaxFilename];
unsafe
{
- fixed (sbyte* stringPtr = stringArray)
- {
- Extern.vpkpp_get_truncated_filename(Handle, stringPtr, Convert.ToUInt64(stringArray.Length));
- return new string(stringPtr);
- }
+ var str = Extern.vpkpp_get_truncated_filename(Handle);
+ return StringUtils.ConvertToStringAndDelete(ref str);
}
}
}
@@ -486,14 +548,10 @@ public string FileStem
{
get
{
- Span stringArray = new sbyte[Constants.MaxFilename];
unsafe
{
- fixed (sbyte* stringPtr = stringArray)
- {
- Extern.vpkpp_get_filestem(Handle, stringPtr, Convert.ToUInt64(stringArray.Length));
- return new string(stringPtr);
- }
+ var str = Extern.vpkpp_get_filestem(Handle);
+ return StringUtils.ConvertToStringAndDelete(ref str);
}
}
}
@@ -502,33 +560,21 @@ public string TruncatedFileStem
{
get
{
- Span stringArray = new sbyte[Constants.MaxFilename];
unsafe
{
- fixed (sbyte* stringPtr = stringArray)
- {
- Extern.vpkpp_get_truncated_filestem(Handle, stringPtr, Convert.ToUInt64(stringArray.Length));
- return new string(stringPtr);
- }
+ var str = Extern.vpkpp_get_truncated_filestem(Handle);
+ return StringUtils.ConvertToStringAndDelete(ref str);
}
}
}
- public List SupportedEntryAttributes
+ public Attribute SupportedEntryAttributes
{
get
{
unsafe
{
- var attrArray = stackalloc Attribute[(int) Attribute.COUNT];
- var numAttributes = Extern.vpkpp_get_supported_entry_attributes(Handle, attrArray, (ulong) Attribute.COUNT);
-
- var result = new List();
- for (ulong i = 0; i < numAttributes; i++)
- {
- result.Add(attrArray[i]);
- }
- return result;
+ return Extern.vpkpp_get_supported_entry_attributes(Handle);
}
}
}
diff --git a/lang/csharp/src/vpkpp/PackFileType.cs b/lang/csharp/src/vpkpp/PackFileType.cs
index 8225b07f8..55cb3b212 100644
--- a/lang/csharp/src/vpkpp/PackFileType.cs
+++ b/lang/csharp/src/vpkpp/PackFileType.cs
@@ -7,7 +7,6 @@ public enum PackFileType
FPX,
GCF,
GMA,
- GRP,
PAK,
PCK,
VPK,
diff --git a/lang/csharp/test/vpkpp.test/PackFileTest.cs b/lang/csharp/test/vpkpp.test/PackFileTest.cs
index 271f21226..624a08200 100644
--- a/lang/csharp/test/vpkpp.test/PackFileTest.cs
+++ b/lang/csharp/test/vpkpp.test/PackFileTest.cs
@@ -8,7 +8,10 @@ public class PackFileTest
[TestMethod]
public void Open()
{
- var vpk = PackFile.Open(BasePortalPath + "portal_pak_dir.vpk");
+ var vpk = PackFile.Open(BasePortalPath + "portal_pak_dir.vpk", (path, entry) =>
+ {
+ Console.WriteLine(path);
+ });
Assert.IsNotNull(vpk);
Assert.AreEqual(vpk.Type, PackFileType.VPK);
@@ -16,15 +19,10 @@ public void Open()
var entry = vpk.FindEntry("materials/console/background1.vmt");
Assert.IsNotNull(entry);
- Assert.AreEqual(vpk.ReadEntryText(entry), "\"UnlitGeneric\"\r\n{\r\n\t\"$basetexture\" \"console/background1\"\r\n\t\"$vertexcolor\" 1\r\n\t\"$vertexalpha\" 1\r\n\t\"$ignorez\" 1\r\n\t\"$no_fullbright\" \"1\"\r\n\t\"$nolod\" \"1\"\r\n}");
+ Assert.AreEqual(vpk.ReadEntryText("materials/console/background1.vmt"), "\"UnlitGeneric\"\r\n{\r\n\t\"$basetexture\" \"console/background1\"\r\n\t\"$vertexcolor\" 1\r\n\t\"$vertexalpha\" 1\r\n\t\"$ignorez\" 1\r\n\t\"$no_fullbright\" \"1\"\r\n\t\"$nolod\" \"1\"\r\n}");
Assert.IsFalse(vpk.ReadOnly);
- foreach(var baked in vpk.GetBakedEntries())
- {
- Console.WriteLine(baked.Path);
- }
-
Assert.AreEqual(vpk.GetEntryCount(), 3509u);
Assert.AreEqual(vpk.FilePath, BasePortalPath + "portal_pak_dir.vpk");
@@ -33,13 +31,8 @@ public void Open()
Assert.AreEqual(vpk.TruncatedFileName, "portal_pak.vpk");
Assert.AreEqual(vpk.FileStem, "portal_pak_dir");
Assert.AreEqual(vpk.TruncatedFileStem, "portal_pak");
-
- CollectionAssert.AreEqual(vpk.SupportedEntryAttributes, new List
- {
- Attribute.LENGTH, Attribute.VPK_PRELOADED_DATA_LENGTH, Attribute.VPK_ARCHIVE_INDEX, Attribute.CRC32
- });
-
- Assert.AreEqual(vpk.ToString(), "portal_pak_dir.vpk | Version v2");
+ Assert.AreEqual(vpk.SupportedEntryAttributes, Attribute.LENGTH | Attribute.VPK_PRELOADED_DATA_LENGTH | Attribute.ARCHIVE_INDEX | Attribute.CRC32);
+ Assert.AreEqual(vpk.ToString(), "portal_pak.vpk | Version v2");
}
[TestMethod]
@@ -54,8 +47,7 @@ public void VerifyChecksums()
[TestMethod]
public void GetSupportedFileTypes()
{
- // 15 as of v4.1.2
- Assert.AreEqual(PackFile.GetSupportedFileTypes().Count, 15);
+ Assert.AreEqual(PackFile.GetSupportedFileTypes().Count, 12);
}
[TestMethod]
diff --git a/src/sourcepp/String.cpp b/src/sourcepp/String.cpp
index 31e98597d..c014d7767 100644
--- a/src/sourcepp/String.cpp
+++ b/src/sourcepp/String.cpp
@@ -153,7 +153,7 @@ std::string string::generateUUIDv4() {
return out;
}
-std::string string::padNumber(int number, int width, char pad) {
+std::string string::padNumber(int64_t number, int width, char pad) {
auto numStr = std::to_string(number);
return std::string(width - std::min(width, numStr.length()), pad) + numStr;
}
diff --git a/src/steampp/_steampp.cmake b/src/steampp/_steampp.cmake
index 7001d000c..6c4b89f82 100644
--- a/src/steampp/_steampp.cmake
+++ b/src/steampp/_steampp.cmake
@@ -1,5 +1,5 @@
add_pretty_parser(steampp
- DEPS kvpp
+ DEPS sourcepp::kvpp
SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/include/steampp/steampp.h"
"${CMAKE_CURRENT_LIST_DIR}/steampp.cpp")
diff --git a/src/vpkpp/Entry.cpp b/src/vpkpp/Entry.cpp
deleted file mode 100644
index 254d37888..000000000
--- a/src/vpkpp/Entry.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#include
-
-#include
-
-using namespace vpkpp;
-
-std::string Entry::getParentPath() const {
- return std::filesystem::path{this->path}.parent_path().string();
-}
-
-std::string Entry::getFilename() const {
- return std::filesystem::path{this->path}.filename().string();
-}
-
-std::string Entry::getStem() const {
- return std::filesystem::path{this->path}.stem().string();
-}
-
-std::string Entry::getExtension() const {
- auto ext = std::filesystem::path{this->path}.extension().string();
- if (!ext.empty() && ext.at(0) == '.') {
- ext = ext.substr(1);
- }
- return ext;
-}
diff --git a/src/vpkpp/PackFile.cpp b/src/vpkpp/PackFile.cpp
index fddc465ae..9897527fa 100644
--- a/src/vpkpp/PackFile.cpp
+++ b/src/vpkpp/PackFile.cpp
@@ -16,7 +16,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -74,50 +73,39 @@ void replace(std::string& line, const std::string& oldString, const std::string&
}
}
-void fixFilePathForWindows(std::string& filePath) {
+void fixFilePathForWindows(std::string& path) {
// Remove invalid characters
- ::replace(filePath, "<", "_LT_");
- ::replace(filePath, "<", "_LT_");
- ::replace(filePath, ">", "_GT_");
- ::replace(filePath, ":", "_COLON_");
- ::replace(filePath, "\"", "_QUOT_");
- ::replace(filePath, "|", "_BAR_");
- ::replace(filePath, "?", "_QMARK_");
- ::replace(filePath, "*", "_AST_");
-
- std::filesystem::path path{filePath};
- auto filename = path.filename().string();
- auto extension = path.extension().string();
- auto stem = path.stem().string();
+ ::replace(path, "<", "_");
+ ::replace(path, "<", "_");
+ ::replace(path, ">", "_");
+ ::replace(path, ":", "_");
+ ::replace(path, "\"", "_");
+ ::replace(path, "|", "_");
+ ::replace(path, "?", "_");
+ ::replace(path, "*", "_");
+
+ std::filesystem::path filePath{path};
+ auto filename = filePath.filename().string();
+ auto extension = filePath.extension().string();
+ auto stem = filePath.stem().string();
string::toUpper(stem);
// Replace bad filenames
- if (stem == "CON") {
- filename = "_CON_" + extension;
- } else if (stem == "PRN") {
- filename = "_PRN_" + extension;
- } else if (stem == "AUX") {
- filename = "_AUX_" + extension;
- } else if (stem == "NUL") {
- filename = "_NUL_" + extension;
- } else if (stem.starts_with("COM") && stem.length() == 4 && std::isdigit(stem[3]) && stem[3] != '0') {
- filename = "_COM";
+ if (stem == "CON" || stem == "PRN" || stem == "AUX" || stem == "NUL") {
+ filename = "___" + extension;
+ } else if (stem.length() == 4 && stem[3] != '0' && ((stem.starts_with("COM") || stem.starts_with("LPT")))) {
+ filename = "___";
filename += stem[3];
- filename += '_';
- filename += extension;
- } else if (stem.starts_with("LPT") && stem.length() == 4 && std::isdigit(stem[3]) && stem[3] != '0') {
- filename = "_LPT";
- filename += stem[3];
- filename += '_';
filename += extension;
}
// Files cannot end with a period - weird
if (extension == ".") {
filename.pop_back();
+ filename += '_';
}
- filePath = (path.parent_path() / filename).string();
+ path = (filePath.parent_path() / filename).string();
}
#endif
@@ -126,9 +114,9 @@ void fixFilePathForWindows(std::string& filePath) {
PackFile::PackFile(std::string fullFilePath_, PackFileOptions options_)
: fullFilePath(std::move(fullFilePath_))
- , options(options_) {}
+ , options(options_) {}
-std::unique_ptr PackFile::open(const std::string& path, PackFileOptions options, const Callback& callback) {
+std::unique_ptr PackFile::open(const std::string& path, PackFileOptions options, const EntryCallback& callback) {
auto extension = std::filesystem::path{path}.extension().string();
string::toLower(extension);
const auto& registry = PackFile::getOpenExtensionRegistry();
@@ -170,37 +158,25 @@ bool PackFile::verifyPackFileSignature() const {
return true;
}
-bool PackFile::hasEntry(const std::string& filename_, bool includeUnbaked) const {
- return static_cast(this->findEntry(filename_, includeUnbaked));
+bool PackFile::hasEntry(const std::string& path, bool includeUnbaked) const {
+ return static_cast(this->findEntry(path, includeUnbaked));
}
-std::optional PackFile::findEntry(const std::string& filename_, bool includeUnbaked) const {
- auto filename = filename_;
- string::normalizeSlashes(filename);
- if (!this->isCaseSensitive()) {
- string::toLower(filename);
+std::optional PackFile::findEntry(const std::string& path_, bool includeUnbaked) const {
+ auto path = this->cleanEntryPath(path_);
+ if (auto it = this->entries.find(path); it != this->entries.end()) {
+ return *it;
}
- auto [dir, name] = splitFilenameAndParentDir(filename);
-
- if (this->entries.contains(dir)) {
- for (const Entry& entry : this->entries.at(dir)) {
- if (entry.path == filename) {
- return entry;
- }
- }
- }
- if (includeUnbaked && this->unbakedEntries.contains(dir)) {
- for (const Entry& unbakedEntry : this->unbakedEntries.at(dir)) {
- if (unbakedEntry.path == filename) {
- return unbakedEntry;
- }
+ if (includeUnbaked) {
+ if (auto it = this->unbakedEntries.find(path); it != this->unbakedEntries.end()) {
+ return *it;
}
}
return std::nullopt;
}
-std::optional PackFile::readEntryText(const Entry& entry) const {
- auto bytes = this->readEntry(entry);
+std::optional PackFile::readEntryText(const std::string& path) const {
+ auto bytes = this->readEntry(path);
if (!bytes) {
return std::nullopt;
}
@@ -213,23 +189,24 @@ std::optional PackFile::readEntryText(const Entry& entry) const {
return out;
}
-void PackFile::addEntry(const std::string& filename_, const std::string& pathToFile, EntryOptions options_) {
+void PackFile::addEntry(const std::string& entryPath, const std::string& filepath, EntryOptions options_) {
if (this->isReadOnly()) {
return;
}
- auto buffer = fs::readFileBuffer(pathToFile);
+ auto buffer = fs::readFileBuffer(filepath);
Entry entry{};
entry.unbaked = true;
entry.unbakedUsingByteBuffer = false;
- entry.unbakedData = pathToFile;
+ entry.unbakedData = filepath;
- Entry& finalEntry = this->addEntryInternal(entry, filename_, buffer, options_);
- finalEntry.unbakedData = pathToFile;
+ auto path = this->cleanEntryPath(entryPath);
+ this->addEntryInternal(entry, path, buffer, options_);
+ this->unbakedEntries.emplace(path, entry);
}
-void PackFile::addEntry(const std::string& filename_, std::vector&& buffer, EntryOptions options_) {
+void PackFile::addEntry(const std::string& path, std::vector&& buffer, EntryOptions options_) {
if (this->isReadOnly()) {
return;
}
@@ -238,70 +215,115 @@ void PackFile::addEntry(const std::string& filename_, std::vector&& b
entry.unbaked = true;
entry.unbakedUsingByteBuffer = true;
- Entry& finalEntry = this->addEntryInternal(entry, filename_, buffer, options_);
- finalEntry.unbakedData = std::move(buffer);
+ auto path_ = this->cleanEntryPath(path);
+ this->addEntryInternal(entry, path_, buffer, options_);
+ entry.unbakedData = std::move(buffer);
+ this->unbakedEntries.emplace(path_, entry);
}
-void PackFile::addEntry(const std::string& filename_, const std::byte* buffer, uint64_t bufferLen, EntryOptions options_) {
+void PackFile::addEntry(const std::string& path, const std::byte* buffer, uint64_t bufferLen, EntryOptions options_) {
std::vector data;
if (buffer && bufferLen > 0) {
data.resize(bufferLen);
std::memcpy(data.data(), buffer, bufferLen);
}
- this->addEntry(filename_, std::move(data), options_);
+ 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 entryPaths;
+ std::vector 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& filename_) {
+bool PackFile::removeEntry(const std::string& path_) {
if (this->isReadOnly()) {
return false;
}
- auto filename = filename_;
- if (!this->isCaseSensitive()) {
- string::toLower(filename);
+ auto path = this->cleanEntryPath(path_);
+ if (this->entries.find(path) != this->entries.end()) {
+ this->entries.erase(path);
+ return true;
}
- auto [dir, name] = splitFilenameAndParentDir(filename);
-
- // Check unbaked entries first
- if (this->unbakedEntries.contains(dir)) {
- for (auto& [preexistingDir, unbakedEntryVec] : this->unbakedEntries) {
- if (preexistingDir != dir) {
- continue;
- }
- for (auto it = unbakedEntryVec.begin(); it != unbakedEntryVec.end(); ++it) {
- if (it->path == filename) {
- unbakedEntryVec.erase(it);
- return true;
- }
- }
- }
+ if (this->unbakedEntries.find(path) != this->unbakedEntries.end()) {
+ this->unbakedEntries.erase(path);
+ return true;
}
+ return false;
+}
- // If it's not in regular entries either you can't remove it!
- if (!this->entries.contains(dir)) {
+std::size_t PackFile::removeDirectory(const std::string& dirName_) {
+ if (this->isReadOnly()) {
return false;
}
- for (auto it = this->entries.at(dir).begin(); it != this->entries.at(dir).end(); ++it) {
- if (it->path == filename) {
- this->entries.at(dir).erase(it);
- return true;
- }
+ auto dirName = this->cleanEntryPath(dirName_);
+ dirName += '/';
+ if (dirName == "/") {
+ const auto size = this->getEntryCount();
+ this->entries.clear();
+ this->unbakedEntries.clear();
+ return size;
}
- return false;
+ std::size_t count = this->entries.erase_prefix(dirName);
+ count += this->unbakedEntries.erase_prefix(dirName);
+ return count;
}
-bool PackFile::extractEntry(const Entry& entry, const std::string& filePath) const {
- if (filePath.empty()) {
+bool PackFile::extractEntry(const std::string& entryPath, const std::string& filepath) const {
+ if (filepath.empty()) {
return false;
}
- auto data = this->readEntry(entry);
+ auto data = this->readEntry(entryPath);
if (!data) {
return false;
}
- FileStream stream{filePath, FileStream::OPT_TRUNCATE | FileStream::OPT_CREATE_IF_NONEXISTENT};
+ FileStream stream{filepath, FileStream::OPT_TRUNCATE | FileStream::OPT_CREATE_IF_NONEXISTENT};
if (!stream) {
return false;
}
@@ -310,48 +332,28 @@ bool PackFile::extractEntry(const Entry& entry, const std::string& filePath) con
return true;
}
-bool PackFile::extractDirectory(const std::string& dir, const std::string& outputDir) const {
- if (dir.empty() || dir == "/") {
+bool PackFile::extractDirectory(const std::string& dir_, const std::string& outputDir) const {
+ auto dir = this->cleanEntryPath(dir_);
+ dir += '/';
+ if (dir == "/") {
return this->extractAll(outputDir, false);
}
- auto testDir = dir;
- if (testDir.starts_with('/')) {
- testDir = testDir.substr(1);
- }
- if (testDir.ends_with('/')) {
- testDir.pop_back();
- }
- auto outputDirPath = std::filesystem::path{outputDir} / std::filesystem::path{testDir}.filename();
+ auto outputDirPath = std::filesystem::path{outputDir} / std::filesystem::path{dir}.filename();
bool noneFailed = true;
- for (const auto& [dir_, bakedEntries_] : this->getBakedEntries()) {
- if (!dir_.starts_with(testDir)) {
- continue;
- }
- for (const auto& entry : bakedEntries_) {
- std::string entryPath = entry.path.substr(testDir.length() + 1);
-#ifdef _WIN32
- ::fixFilePathForWindows(entryPath);
-#endif
- if (!this->extractEntry(entry, (outputDirPath / entryPath).string())) {
- noneFailed = false;
- }
+ this->runForAllEntries([this, &dir, &outputDirPath, &noneFailed](const std::string& path, const Entry& entry) {
+ if (!path.starts_with(dir)) {
+ return;
}
- }
- for (const auto& [dir_, unbakedEntries_] : this->getUnbakedEntries()) {
- if (!dir_.starts_with(testDir)) {
- continue;
- }
- for (const auto& entry : unbakedEntries_) {
- std::string entryPath = entry.path.substr(testDir.length() + 1);
+
+ std::string outputPath = path.substr(dir.length());
#ifdef _WIN32
- ::fixFilePathForWindows(entryPath);
+ ::fixFilePathForWindows(outputPath);
#endif
- if (!this->extractEntry(entry, (outputDirPath / entryPath).string())) {
- noneFailed = false;
- }
+ if (!this->extractEntry(path, (outputDirPath / outputPath).string())) {
+ noneFailed = false;
}
- }
+ });
return noneFailed;
}
@@ -365,63 +367,43 @@ bool PackFile::extractAll(const std::string& outputDir, bool createUnderPackFile
outputDirPath /= this->getTruncatedFilestem();
}
bool noneFailed = true;
- for (const auto& [dir, bakedEntries_] : this->getBakedEntries()) {
- for (const auto& entry : bakedEntries_) {
- std::string entryPath = entry.path;
+ this->runForAllEntries([this, &outputDirPath, &noneFailed](const std::string& path, const Entry& entry) {
+ std::string entryPath = path;
#ifdef _WIN32
- ::fixFilePathForWindows(entryPath);
-#endif
- if (!this->extractEntry(entry, (outputDirPath / entryPath).string())) {
- noneFailed = false;
- }
- }
- }
- for (const auto& [dir, unbakedEntries_] : this->getUnbakedEntries()) {
- for (const auto& entry : unbakedEntries_) {
- std::string entryPath = entry.path;
-#ifdef _WIN32
- ::fixFilePathForWindows(entryPath);
+ ::fixFilePathForWindows(entryPath);
#endif
- if (!this->extractEntry(entry, (outputDirPath / entryPath).string())) {
- noneFailed = false;
- }
+ if (!this->extractEntry(path, (outputDirPath / entryPath).string())) {
+ noneFailed = false;
}
- }
+ });
return noneFailed;
}
-bool PackFile::extractAll(const std::string& outputDir, const std::function& predicate) const {
+bool PackFile::extractAll(const std::string& outputDir, const EntryPredicate& predicate, bool stripSharedDirs) const {
if (outputDir.empty() || !predicate) {
return false;
}
// Get list of paths
- std::vector saveEntries;
- for (const auto& [dir, bakedEntries_] : this->getBakedEntries()) {
- for (const auto& entry : bakedEntries_) {
- if (predicate(entry)) {
- saveEntries.push_back(entry);
- }
- }
- }
- for (const auto& [dir, unbakedEntries_] : this->getUnbakedEntries()) {
- for (const auto& entry : unbakedEntries_) {
- if (predicate(entry)) {
- saveEntries.push_back(entry);
- }
+ std::vector saveEntryPaths;
+ this->runForAllEntries([&predicate, &saveEntryPaths](const std::string& path, const Entry& entry) {
+ if (predicate(path, entry)) {
+ saveEntryPaths.push_back(path);
}
- }
- if (saveEntries.empty()) {
+ });
+ if (saveEntryPaths.empty()) {
return false;
}
- // Strip shared directories until we have a root folder
- std::vector rootDirList;
- {
+ std::size_t rootDirLen = 0;
+ if (stripSharedDirs) {
+ // Strip shared directories until we have a root folder
+ std::vector rootDirList;
+
std::vector> pathSplits;
- pathSplits.reserve(saveEntries.size());
- for (const auto& entry : saveEntries) {
- pathSplits.push_back(::splitPath(entry.path));
+ pathSplits.reserve(saveEntryPaths.size());
+ for (const auto& path : saveEntryPaths) {
+ pathSplits.push_back(::splitPath(path));
}
while (true) {
bool allTheSame = true;
@@ -444,43 +426,67 @@ bool PackFile::extractAll(const std::string& outputDir, const std::functionextractEntry(entry, (outputDirPath / entryPath).string())) {
+ if (!this->extractEntry(path, (outputDirPath / savePath.substr(rootDirLen)).string())) {
noneFailed = false;
}
}
return noneFailed;
}
-const std::unordered_map>& PackFile::getBakedEntries() const {
+const PackFile::EntryTrie& PackFile::getBakedEntries() const {
return this->entries;
}
-const std::unordered_map>& PackFile::getUnbakedEntries() const {
+const PackFile::EntryTrie& PackFile::getUnbakedEntries() const {
return this->unbakedEntries;
}
std::size_t PackFile::getEntryCount(bool includeUnbaked) const {
std::size_t count = 0;
- for (const auto& [directory, entries_] : this->entries) {
- count += entries_.size();
+ count += this->entries.size();
+ if (includeUnbaked) {
+ count += this->unbakedEntries.size();
+ }
+ return count;
+}
+
+void PackFile::runForAllEntries(const EntryCallback& operation, bool includeUnbaked) const {
+ std::string key;
+ for (auto entry = this->entries.cbegin(); entry != this->entries.cend(); ++entry) {
+ entry.key(key);
+ operation(key, entry.value());
}
if (includeUnbaked) {
- for (const auto& [directory, entries_] : this->unbakedEntries) {
- count += entries_.size();
+ for (auto entry = this->unbakedEntries.cbegin(); entry != this->unbakedEntries.cend(); ++entry) {
+ entry.key(key);
+ operation(key, entry.value());
+ }
+ }
+}
+
+void PackFile::runForAllEntries(const std::function