summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2022-08-08 23:33:51 +0200
committerAki <please@ignore.pl>2022-08-08 23:33:51 +0200
commitf5851278765e468f7fe04f943b8d69021e22e004 (patch)
tree1d687d444d28ca8020a3cd5c42826a031fded24b
parentc5657b5cf6e72df9f573f149fe027374bf634fa7 (diff)
downloadstarshatter-f5851278765e468f7fe04f943b8d69021e22e004.zip
starshatter-f5851278765e468f7fe04f943b8d69021e22e004.tar.gz
starshatter-f5851278765e468f7fe04f943b8d69021e22e004.tar.bz2
Added a functionality that enables extracting files by their path
-rw-r--r--ArchiveEx/Archive.cpp41
-rw-r--r--ArchiveEx/Archive.h2
2 files changed, 42 insertions, 1 deletions
diff --git a/ArchiveEx/Archive.cpp b/ArchiveEx/Archive.cpp
index 3eea0fe..2e3aa52 100644
--- a/ArchiveEx/Archive.cpp
+++ b/ArchiveEx/Archive.cpp
@@ -2,6 +2,7 @@
#include <cstdint>
#include <cstdio>
+#include <cstring>
#include <memory>
#include <vector>
@@ -18,7 +19,8 @@ using UniqueFileHandle = std::unique_ptr<std::FILE, decltype(&std::fclose)>;
static constexpr std::size_t DIRECTORY_MARGIN {64};
-static std::size_t BytesToBlocks(std::size_t bytes);
+static inline std::size_t BytesToBlocks(std::size_t bytes);
+static inline std::size_t ConvertPathSeparator(const char* src, char* dest);
Archive::Archive(const char* p) :
@@ -85,6 +87,29 @@ Archive::Expand(const int index, std::uint8_t*& buffer, const bool null_terminat
}
+int
+Archive::Expand(const char* filepath, std::uint8_t*& buffer, const bool null_terminated) const
+{
+ const int index = Find(filepath);
+ if (-1 == index)
+ return -1;
+ return Expand(index, buffer, null_terminated);
+}
+
+
+int
+Archive::Find(const char* filepath) const
+{
+ std::vector<char> path(std::strlen(filepath) + 1);
+ ConvertPathSeparator(filepath, path.data());
+ for (std::size_t i = 0; i < entries.size(); ++i) {
+ if (0 == std::strcmp(entries[i].name, path.data()))
+ return i;
+ }
+ return -1;
+}
+
+
void
Archive::PrintNamesOfEntries() const
{
@@ -110,4 +135,18 @@ BytesToBlocks(const std::size_t bytes)
}
+std::size_t
+ConvertPathSeparator(const char* src, char* dest)
+{
+ std::size_t i;
+ for (i = 0; 0 != src[i]; ++i) {
+ if ('\\' == src[i])
+ dest[i] = '/';
+ else
+ dest[i] = src[i];
+ }
+ return i;
+}
+
+
} // namespace Archive
diff --git a/ArchiveEx/Archive.h b/ArchiveEx/Archive.h
index 6870194..0f1be0c 100644
--- a/ArchiveEx/Archive.h
+++ b/ArchiveEx/Archive.h
@@ -40,6 +40,8 @@ class Archive
public:
explicit Archive(const char* path);
int Expand(int index, std::uint8_t*& buffer, bool null_terminated=false) const;
+ int Expand(const char* filepath, std::uint8_t*& buffer, bool null_terminated=false) const;
+ int Find(const char* filepath) const;
void PrintNamesOfEntries() const;
std::size_t DirectoryBlocks() const;
private: