Skip to content

Commit

Permalink
refactor ArchiveExtractor to allow more flexibility for ExtractLzmaIn…
Browse files Browse the repository at this point in the history
…Proc and bExtractLzmaUsing7Zip options
  • Loading branch information
nam20485 committed May 5, 2024
1 parent e4d92b7 commit c04b952
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 51 deletions.
115 changes: 68 additions & 47 deletions Utils/ArchiveExtractor.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "ArchiveExtractor.h"
#include "ArchiveExtractor.h"
#include <filesystem>
#include "libarchive_extract.h"
#include "Logger.h"
Expand All @@ -7,17 +8,21 @@
#include "str_utils.h"
#include <cstdlib>
#include <stdexcept>
#include <string>
#include "lzma.h"

using namespace std::filesystem;

namespace Utils
{
ArchiveExtractor::ArchiveExtractor(const std::string& path)
ArchiveExtractor::ArchiveExtractor(const std::string& path, bool bExtractLzmaInProc /* = false*/, bool bExtractLzmaUsing7Zip /* = true*/)
: m_path(path)
, m_bExtractLzmaInProc(bExtractLzmaInProc)
, m_bExtractLzmaUsing7Zip(bExtractLzmaUsing7Zip)
{
}

std::string ArchiveExtractor::GetPath() const
path ArchiveExtractor::GetPath() const
{
return m_path;
}
Expand All @@ -27,7 +32,7 @@ namespace Utils
return m_extractionDirectory;
}

bool ArchiveExtractor::IsArchiveTypeSupported(const std::filesystem::path& file)
bool ArchiveExtractor::IsArchiveTypeSupported(const path& file)
{
if (ALLOW_ALL_ARCHIVE_EXTENSION_TYPES) return true;

Expand All @@ -45,73 +50,89 @@ namespace Utils

bool ArchiveExtractor::IsArchiveTypeSupported(const std::string& file)
{
return IsArchiveTypeSupported(std::filesystem::path(file));
return IsArchiveTypeSupported(path(file));
}

bool ArchiveExtractor::Extract()
{
auto path = std::filesystem::path(m_path);
//auto extractionPath = path.replace_extension().string();
auto extractionPath = path.parent_path() / path.stem();
auto extractionPath = m_path.parent_path() / m_path.stem();
return Extract(extractionPath.string());
}

bool ArchiveExtractor::Extract(const std::string& destinationPath)
bool Utils::ArchiveExtractor::ExtractLzmaInProc(const std::filesystem::path& destinationPath)
{
path p(m_path);
if (p.extension() == ".Z" || p.extension() == ".z")
{
// https://documentation.help/7-Zip/extract_full.htm
return false;
}

bool ArchiveExtractor::ExtractLzmaOutOfProc(const path& destinationPath)
{
// https://documentation.help/7-Zip/extract_full.htm

std::stringstream ss;
ss << "7z"
<< " x " << '"' << m_path << '"' // extract w/ full paths and archive path
<< " -o" << '"' << destinationPath << '"' // output path
<< " -y" // yes to all prompts
<< " -aoa"; // overwrite all
std::stringstream ss;
ss << "7z"
<< " x " /*<< '"'*/ << m_path /*<< '"'*/ // extract w/ full paths and archive path
<< " -o" /*<< '"'*/ << destinationPath /*<< '"'*/ // output path
<< " -y" // yes to all prompts
<< " -aoa"; // overwrite all

const auto silent = true;
if (silent)
const auto silent = true;
if (silent)
{
bool isWindows = true;
if (isWindows)
{
bool isWindows = true;
if (isWindows)
{
ss << " >$null 2>&1";
}
else
{
ss << " >nul 2>nul";
}
ss << " >$null 2>&1";
}
else
{
ss << " >nul 2>nul";
}
}

auto command = ss.str();
auto command = ss.str();

loginfo("running 7z command: [" + command + "]...");
loginfo("running 7z command: [" + command + "]...");

auto exitCode = std::system(command.c_str());
auto exitCode = std::system(command.c_str());

#if defined(__linux__) || defined(__apple__)
exitCode = WEXITSTATUS(exitCode);
exitCode = WEXITSTATUS(exitCode);
#endif

if (exitCode != (int) e7zExitCode::Success &&
exitCode != (int) e7zExitCode::Warning)
{
auto message = "7z command failed (exit code = " + std::to_string(exitCode) + ")";
logerror(message);
throw std::runtime_error(message.c_str());
//return false;
}
if (exitCode != static_cast<int>(e7zExitCode::Success) &&
exitCode != static_cast<int>(e7zExitCode::Warning))
{
auto message = "7z command failed (exit code = " + std::to_string(exitCode) + ")";
logerror(message);
throw std::runtime_error(message.c_str());
//return false;
}

loginfo("7z command succeeded");
loginfo("7z command succeeded");

m_extractionDirectory = destinationPath;
return true;
m_extractionDirectory = destinationPath.string();
return true;
}

bool ArchiveExtractor::Extract(const std::string& destinationPath)
{
if (m_bExtractLzmaUsing7Zip &&
std::find(LZMA_FILE_EXTENSIONS.begin(), LZMA_FILE_EXTENSIONS.end(), m_path.extension()) != LZMA_FILE_EXTENSIONS.end())
{
if (m_bExtractLzmaInProc)
{
return ExtractLzmaInProc(destinationPath);
}
else
{
return ExtractLzmaOutOfProc(destinationPath);
}
}
else if (extract(m_path.c_str(), destinationPath.c_str()))
else if (extract(m_path.string().c_str(), destinationPath.c_str()))
{
//std::filesystem::path p(destinationPath);
//p /= std::filesystem::path(m_path).stem();
//path p(destinationPath);
//p /= path(m_path).stem();
m_extractionDirectory = destinationPath;
return true;
}
Expand Down Expand Up @@ -161,5 +182,5 @@ namespace Utils
}

return uncompressedPath;
}
}
}
16 changes: 12 additions & 4 deletions Utils/ArchiveExtractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <string>
#include <filesystem>
#include "utils_export.h"
#include <vector>


namespace Utils
Expand All @@ -21,10 +22,10 @@ namespace Utils
UserStopped = 255
};

ArchiveExtractor(const std::string& path);
ArchiveExtractor(const std::string& path, bool bExtractLzmaInProc = false, bool bExtractLzmaUsing7Zip = true);
//~ArchiveExtractor();

std::string GetPath() const;
std::filesystem::path GetPath() const;
std::string GetExtractionDirectory() const;

static bool IsArchiveTypeSupported(const std::filesystem::path& file);
Expand All @@ -35,12 +36,19 @@ namespace Utils

static std::filesystem::path getUncompressedFilePath(const std::filesystem::path& directory, const std::string& filename);

inline static bool ALLOW_ALL_ARCHIVE_EXTENSION_TYPES = false;
constexpr static inline bool ALLOW_ALL_ARCHIVE_EXTENSION_TYPES = false;
constexpr static inline const char* SupportedExtensions[] = { "tgz", "tar.gz", "gz", "zip", "Z", "gzip", "tar" };

private:
std::string m_path;
std::filesystem::path m_path;
std::string m_extractionDirectory;
bool m_bExtractLzmaInProc = false;
bool m_bExtractLzmaUsing7Zip = true;

bool ExtractLzmaOutOfProc(const std::filesystem::path& destinationPath);
bool ExtractLzmaInProc(const std::filesystem::path& destinationPath);

static inline const std::vector<std::string> LZMA_FILE_EXTENSIONS = { ".Z", ".z", ".lzma", ".lz" };

};
}

0 comments on commit c04b952

Please sign in to comment.