diff options
Diffstat (limited to 'src/lib/util/un7z.cpp')
-rw-r--r-- | src/lib/util/un7z.cpp | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/src/lib/util/un7z.cpp b/src/lib/util/un7z.cpp index bca825c1f71..d4761c5347d 100644 --- a/src/lib/util/un7z.cpp +++ b/src/lib/util/un7z.cpp @@ -124,12 +124,21 @@ public: archive_file::error initialize(); - int first_file() { return search(0, 0, std::string(), false, false); } - int next_file() { return (m_curr_file_idx < 0) ? -1 : search(m_curr_file_idx + 1, 0, std::string(), false, false); } + int first_file() { return search(0, 0, std::string(), false, false, false); } + int next_file() { return (m_curr_file_idx < 0) ? -1 : search(m_curr_file_idx + 1, 0, std::string(), false, false, false); } - int search(std::uint32_t crc) { return search(0, crc, std::string(), true, false); } - int search(const std::string &filename) { return search(0, 0, filename, false, true); } - int search(std::uint32_t crc, const std::string &filename) { return search(0, crc, filename, true, true); } + int search(std::uint32_t crc) + { + return search(0, crc, std::string(), true, false, false); + } + int search(const std::string &filename, bool partialpath) + { + return search(0, 0, filename, false, true, partialpath); + } + int search(std::uint32_t crc, const std::string &filename, bool partialpath) + { + return search(0, crc, filename, true, true, partialpath); + } bool current_is_directory() const { return m_curr_is_dir; } const std::string ¤t_name() const { return m_curr_name; } @@ -144,7 +153,13 @@ private: m7z_file_impl &operator=(const m7z_file_impl &) = delete; m7z_file_impl &operator=(m7z_file_impl &&) = delete; - int search(int i, std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname); + int search( + int i, + std::uint32_t search_crc, + const std::string &search_filename, + bool matchcrc, + bool matchname, + bool partialpath); void make_utf8_name(int index); static constexpr std::size_t CACHE_SIZE = 8; @@ -187,9 +202,18 @@ public: virtual int first_file() override { return m_impl->first_file(); } virtual int next_file() override { return m_impl->next_file(); } - virtual int search(std::uint32_t crc) override { return m_impl->search(crc); } - virtual int search(const std::string &filename) override { return m_impl->search(filename); } - virtual int search(std::uint32_t crc, const std::string &filename) override { return m_impl->search(crc, filename); } + virtual int search(std::uint32_t crc) override + { + return m_impl->search(crc); + } + virtual int search(const std::string &filename, bool partialpath) override + { + return m_impl->search(filename, partialpath); + } + virtual int search(std::uint32_t crc, const std::string &filename, bool partialpath) override + { + return m_impl->search(crc, filename, partialpath); + } virtual bool current_is_directory() const override { return m_impl->current_is_directory(); } virtual const std::string ¤t_name() const override { return m_impl->current_name(); } @@ -373,7 +397,13 @@ archive_file::error m7z_file_impl::decompress(void *buffer, std::uint32_t length } -int m7z_file_impl::search(int i, std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname) +int m7z_file_impl::search( + int i, + std::uint32_t search_crc, + const std::string &search_filename, + bool matchcrc, + bool matchname, + bool partialpath) { for ( ; i < m_db.db.NumFiles; i++) { @@ -383,7 +413,11 @@ int m7z_file_impl::search(int i, std::uint32_t search_crc, const std::string &se const std::uint64_t size(f.Size); const std::uint32_t crc(f.Crc); const bool crcmatch(crc == search_crc); - const bool namematch(!core_stricmp(search_filename.c_str(), &m_utf8_buf[0])); + auto const partialoffset(m_utf8_buf.size() - 1 - search_filename.length()); + bool const partialpossible((m_utf8_buf.size() > (search_filename.length() + 1)) && (m_utf8_buf[partialoffset - 1] == '/')); + const bool namematch( + !core_stricmp(search_filename.c_str(), &m_utf8_buf[0]) || + (partialpath && partialpossible && !core_stricmp(search_filename.c_str(), &m_utf8_buf[partialoffset]))); const bool found = ((!matchcrc && !matchname) || !f.IsDir) && (!matchcrc || crcmatch) && (!matchname || namematch); if (found) |