From ee8b50877ffd066078a3805bbadfda13894cd9ea Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 3 Nov 2024 08:50:42 +0100
Subject: [PATCH 01/31] Update project version in CMakeLists.txt
---
CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2eb86345..5378bb34 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,7 +5,7 @@
cmake_minimum_required( VERSION 3.14 )
project( bit7z
- VERSION 4.0.8
+ VERSION 4.0.9
DESCRIPTION "A C++ static library offering a clean and simple interface to the 7-zip/p7zip shared libraries"
HOMEPAGE_URL "https://github.com/rikyoz/bit7z/" )
set( CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "ON" )
From 6e135d9b6a29934ef4b2250be4e7f44ad7345748 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 3 Nov 2024 08:55:55 +0100
Subject: [PATCH 02/31] Update CPM.cmake to v0.40.2
---
cmake/Dependencies.cmake | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake
index 49498016..d853052e 100644
--- a/cmake/Dependencies.cmake
+++ b/cmake/Dependencies.cmake
@@ -1,6 +1,6 @@
# Downloading the CPM.cmake package manager
-set( CPM_DOWNLOAD_VERSION 0.38.6 )
-set( CPM_DOWNLOAD_HASH 11c3fa5f1ba14f15d31c2fb63dbc8628ee133d81c8d764caad9a8db9e0bacb07 )
+set( CPM_DOWNLOAD_VERSION 0.40.2 )
+set( CPM_DOWNLOAD_HASH "c8cdc32c03816538ce22781ed72964dc864b2a34a310d3b7104812a5ca2d835d" )
set( CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake" )
if( NOT ( EXISTS ${CPM_DOWNLOAD_LOCATION} ) )
message( STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}" )
From 919710f8371e607f33e0f2a764515b9272819e07 Mon Sep 17 00:00:00 2001
From: Oz
Date: Wed, 21 Aug 2024 21:55:36 +0200
Subject: [PATCH 03/31] Update README badges
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 3e6d9fc7..992f27f3 100644
--- a/README.md
+++ b/README.md
@@ -15,9 +15,9 @@
## ⚡️ Introduction
From ffe0a94351c089682289ca72e725aa98db059dc1 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 3 Nov 2024 09:53:26 +0100
Subject: [PATCH 04/31] Add support for checking archive start at the beginning
of a file
---
include/bit7z/bitarchivereader.hpp | 69 ++++++++++++++++++++++++++++--
include/bit7z/bitarchivewriter.hpp | 48 +++++++++++++++++++++
include/bit7z/bitinputarchive.hpp | 58 +++++++++++++++++--------
include/bit7z/bitoutputarchive.hpp | 16 +++++--
src/bitarchiveeditor.cpp | 4 +-
src/bitarchivereader.cpp | 23 +++++++++-
src/bitarchivewriter.cpp | 26 ++++++++++-
src/bitinputarchive.cpp | 36 +++++++++++-----
src/bitoutputarchive.cpp | 23 ++++++----
9 files changed, 257 insertions(+), 46 deletions(-)
diff --git a/include/bit7z/bitarchivereader.hpp b/include/bit7z/bitarchivereader.hpp
index dcc7fe2a..f0b4bdcc 100644
--- a/include/bit7z/bitarchivereader.hpp
+++ b/include/bit7z/bitarchivereader.hpp
@@ -36,11 +36,53 @@ class BitArchiveReader final : public BitAbstractArchiveOpener, public BitInputA
*
* @param lib the 7z library used.
* @param inArchive the path to the archive to be read.
+ * @param archiveStart whether to search for the archive's start throughout the entire file
+ * or only at the beginning.
* @param format the format of the input archive.
- * @param password the password needed for opening the input archive.
+ * @param password (optional) the password needed for opening the input archive.
*/
BitArchiveReader( const Bit7zLibrary& lib,
const tstring& inArchive,
+ ArchiveStartOffset archiveStart,
+ const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
+ const tstring& password = {} );
+
+ /**
+ * @brief Constructs a BitArchiveReader object, opening the input file archive.
+ *
+ * @note When bit7z is compiled using the `BIT7Z_AUTO_FORMAT` option, the format
+ * argument has the default value BitFormat::Auto (automatic format detection of the input archive).
+ * On the contrary, when `BIT7Z_AUTO_FORMAT` is not defined (i.e., no auto format detection available),
+ * the format argument must be specified.
+ *
+ * @param lib the 7z library used.
+ * @param inArchive the path to the archive to be read.
+ * @param format the format of the input archive.
+ * @param password (optional) the password needed for opening the input archive.
+ */
+ BitArchiveReader( const Bit7zLibrary& lib,
+ const tstring& inArchive,
+ const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
+ const tstring& password = {} );
+
+ /**
+ * @brief Constructs a BitArchiveReader object, opening the archive in the input buffer.
+ *
+ * @note When bit7z is compiled using the `BIT7Z_AUTO_FORMAT` option, the format
+ * argument has the default value BitFormat::Auto (automatic format detection of the input archive).
+ * On the contrary, when `BIT7Z_AUTO_FORMAT` is not defined (i.e., no auto format detection available),
+ * the format argument must be specified.
+ *
+ * @param lib the 7z library used.
+ * @param inArchive the input buffer containing the archive to be read.
+ * @param archiveStart whether to search for the archive's start throughout the entire file
+ * or only at the beginning.
+ * @param format the format of the input archive.
+ * @param password (optional) the password needed for opening the input archive.
+ */
+ BitArchiveReader( const Bit7zLibrary& lib,
+ const buffer_t& inArchive,
+ ArchiveStartOffset archiveStart,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
const tstring& password = {} );
@@ -55,13 +97,34 @@ class BitArchiveReader final : public BitAbstractArchiveOpener, public BitInputA
* @param lib the 7z library used.
* @param inArchive the input buffer containing the archive to be read.
* @param format the format of the input archive.
- * @param password the password needed for opening the input archive.
+ * @param password (optional) the password needed for opening the input archive.
*/
BitArchiveReader( const Bit7zLibrary& lib,
const std::vector< byte_t >& inArchive,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
const tstring& password = {} );
+ /**
+ * @brief Constructs a BitArchiveReader object, opening the archive from the standard input stream.
+ *
+ * @note When bit7z is compiled using the `BIT7Z_AUTO_FORMAT` option, the format
+ * argument has the default value BitFormat::Auto (automatic format detection of the input archive).
+ * On the contrary, when `BIT7Z_AUTO_FORMAT` is not defined (i.e., no auto format detection available),
+ * the format argument must be specified.
+ *
+ * @param lib the 7z library used.
+ * @param inArchive the standard input stream of the archive to be read.
+ * @param archiveStart whether to search for the archive's start throughout the entire file
+ * or only at the beginning.
+ * @param format the format of the input archive.
+ * @param password (optional) the password needed for opening the input archive.
+ */
+ BitArchiveReader( const Bit7zLibrary& lib,
+ std::istream& inArchive,
+ ArchiveStartOffset archiveStart,
+ const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
+ const tstring& password = {} );
+
/**
* @brief Constructs a BitArchiveReader object, opening the archive from the standard input stream.
*
@@ -73,7 +136,7 @@ class BitArchiveReader final : public BitAbstractArchiveOpener, public BitInputA
* @param lib the 7z library used.
* @param inArchive the standard input stream of the archive to be read.
* @param format the format of the input archive.
- * @param password the password needed for opening the input archive.
+ * @param password (optional) the password needed for opening the input archive.
*/
BitArchiveReader( const Bit7zLibrary& lib,
std::istream& inArchive,
diff --git a/include/bit7z/bitarchivewriter.hpp b/include/bit7z/bitarchivewriter.hpp
index 1b53ca80..080b62f6 100644
--- a/include/bit7z/bitarchivewriter.hpp
+++ b/include/bit7z/bitarchivewriter.hpp
@@ -32,11 +32,43 @@ class BitArchiveWriter : public BitAbstractArchiveCreator, public BitOutputArchi
*
* @param lib the 7z library to use.
* @param inArchive the path to an input archive file.
+ * @param startOffset whether to search for the archive's start throughout the entire file
+ * or only at the beginning.
* @param format the input/output archive format.
* @param password (optional) the password needed to read the input archive.
*/
BitArchiveWriter( const Bit7zLibrary& lib,
const tstring& inArchive,
+ ArchiveStartOffset startOffset,
+ const BitInOutFormat& format,
+ const tstring& password = {} );
+
+ /**
+ * @brief Constructs a BitArchiveWriter object, reading the given archive file path.
+ *
+ * @param lib the 7z library to use.
+ * @param inArchive the path to an input archive file.
+ * @param format the input/output archive format.
+ * @param password (optional) the password needed to read the input archive.
+ */
+ BitArchiveWriter( const Bit7zLibrary& lib,
+ const tstring& inArchive,
+ const BitInOutFormat& format,
+ const tstring& password = {} );
+
+ /**
+ * @brief Constructs a BitArchiveWriter object, reading the archive in the given buffer.
+ *
+ * @param lib the 7z library to use.
+ * @param inArchive the buffer containing the input archive.
+ * @param startOffset whether to search for the archive's start throughout the entire file
+ * or only at the beginning.
+ * @param format the input/output archive format.
+ * @param password (optional) the password needed to read the input archive.
+ */
+ BitArchiveWriter( const Bit7zLibrary& lib,
+ const buffer_t& inArchive,
+ ArchiveStartOffset startOffset,
const BitInOutFormat& format,
const tstring& password = {} );
@@ -53,6 +85,22 @@ class BitArchiveWriter : public BitAbstractArchiveCreator, public BitOutputArchi
const BitInOutFormat& format,
const tstring& password = {} );
+ /**
+ * @brief Constructs a BitArchiveWriter object, reading the archive from the given standard input stream.
+ *
+ * @param lib the 7z library to use.
+ * @param inArchive the standard stream of the input archive.
+ * @param startOffset whether to search for the archive's start throughout the entire file
+ * or only at the beginning.
+ * @param format the input/output archive format.
+ * @param password (optional) the password needed to read the input archive.
+ */
+ BitArchiveWriter( const Bit7zLibrary& lib,
+ std::istream& inArchive,
+ ArchiveStartOffset startOffset,
+ const BitInOutFormat& format,
+ const tstring& password = {} );
+
/**
* @brief Constructs a BitArchiveWriter object, reading the archive from the given standard input stream.
*
diff --git a/include/bit7z/bitinputarchive.hpp b/include/bit7z/bitinputarchive.hpp
index e83545f5..9e630465 100644
--- a/include/bit7z/bitinputarchive.hpp
+++ b/include/bit7z/bitinputarchive.hpp
@@ -25,6 +25,12 @@ namespace bit7z {
using std::vector;
+enum struct ArchiveStartOffset : std::uint8_t {
+ None, ///< Don't specify an archive start offset. For some formats, like Zip archives,
+ ///< this means that the whole input file will be searched for the archive's start.
+ FileStart ///< Check only the file start for the archive's start.
+};
+
/**
* @brief The BitInputArchive class, given a handler object, allows reading/extracting the content of archives.
*/
@@ -33,38 +39,54 @@ class BitInputArchive {
/**
* @brief Constructs a BitInputArchive object, opening the input file archive.
*
- * @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
- * be used for reading the input archive
- * @param inFile the path to the input archive file
+ * @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
+ * be used for reading the input archive
+ * @param inFile the path to the input archive file
+ * @param startOffset (optional) specifies whether to search for the archive's start throughout the
+ * entire file or only at the beginning. The default behavior is to search at the beginning.
*/
- BitInputArchive( const BitAbstractArchiveHandler& handler, const tstring& inFile );
+ BitInputArchive( const BitAbstractArchiveHandler& handler,
+ const tstring& inFile,
+ ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitInputArchive object, opening the input file archive.
*
- * @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
- * be used for reading the input archive
- * @param arcPath the path to the input archive file
+ * @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
+ * be used for reading the input archive
+ * @param arcPath the path to the input archive file
+ * @param startOffset (optional) whether to search for the archive's start throughout the entire file
+ * or only at the beginning. The default behavior is to search at the beginning.
*/
- BitInputArchive( const BitAbstractArchiveHandler& handler, const fs::path& arcPath );
+ BitInputArchive( const BitAbstractArchiveHandler& handler,
+ const fs::path& arcPath,
+ ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitInputArchive object, opening the archive given in the input buffer.
*
- * @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
- * be used for reading the input archive
- * @param inBuffer the buffer containing the input archive
+ * @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
+ * be used for reading the input archive
+ * @param inBuffer the buffer containing the input archive
+ * @param startOffset (optional) whether to search for the archive's start throughout the entire file
+ * or only at the beginning. The default behavior is to search at the beginning.
*/
- BitInputArchive( const BitAbstractArchiveHandler& handler, const std::vector< byte_t >& inBuffer );
+ BitInputArchive( const BitAbstractArchiveHandler& handler,
+ const buffer_t& inBuffer,
+ ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitInputArchive object, opening the archive by reading the given input stream.
*
- * @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
- * be used for reading the input archive
- * @param inStream the standard input stream of the input archive
+ * @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
+ * be used for reading the input archive
+ * @param inStream the standard input stream of the input archive
+ * @param startOffset (optional) whether to search for the archive's start throughout the entire file
+ * or only at the beginning. The default behavior is to search at the beginning.
*/
- BitInputArchive( const BitAbstractArchiveHandler& handler, std::istream& inStream );
+ BitInputArchive( const BitAbstractArchiveHandler& handler,
+ std::istream& inStream,
+ ArchiveStartOffset startOffset = ArchiveStartOffset::None );
BitInputArchive( const BitInputArchive& ) = delete;
@@ -275,7 +297,8 @@ class BitInputArchive {
const BitAbstractArchiveHandler& mArchiveHandler;
tstring mArchivePath;
- auto openArchiveStream( const fs::path& name, IInStream* inStream ) -> IInArchive*;
+ BIT7Z_NODISCARD
+ auto openArchiveStream( const fs::path& name, IInStream* inStream, ArchiveStartOffset startOffset ) -> IInArchive*;
public:
/**
@@ -397,6 +420,7 @@ class BitInputArchive {
* @return the item at the given index within the archive.
*/
BIT7Z_NODISCARD auto itemAt( uint32_t index ) const -> BitArchiveItemOffset;
+
};
} // namespace bit7z
diff --git a/include/bit7z/bitoutputarchive.hpp b/include/bit7z/bitoutputarchive.hpp
index a9175d41..5f49d568 100644
--- a/include/bit7z/bitoutputarchive.hpp
+++ b/include/bit7z/bitoutputarchive.hpp
@@ -78,7 +78,9 @@ class BitOutputArchive {
* be used for creating the new archive and reading the (optional) input archive.
* @param inFile (optional) the path to an input archive file.
*/
- explicit BitOutputArchive( const BitAbstractArchiveCreator& creator, const tstring& inFile );
+ explicit BitOutputArchive( const BitAbstractArchiveCreator& creator,
+ const tstring& inFile,
+ ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitOutputArchive object, opening an input file archive from the given buffer.
@@ -91,7 +93,9 @@ class BitOutputArchive {
* be used for creating the new archive and reading the (optional) input archive.
* @param inBuffer the buffer containing an input archive file.
*/
- BitOutputArchive( const BitAbstractArchiveCreator& creator, const std::vector< byte_t >& inBuffer );
+ BitOutputArchive( const BitAbstractArchiveCreator& creator,
+ const buffer_t& inBuffer,
+ ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitOutputArchive object, reading an input file archive from the given std::istream.
@@ -100,7 +104,9 @@ class BitOutputArchive {
* be used for creating the new archive and reading the (optional) input archive.
* @param inStream the standard input stream of the input archive file.
*/
- BitOutputArchive( const BitAbstractArchiveCreator& creator, std::istream& inStream );
+ BitOutputArchive( const BitAbstractArchiveCreator& creator,
+ std::istream& inStream,
+ ArchiveStartOffset startOffset = ArchiveStartOffset::None );
BitOutputArchive( const BitOutputArchive& ) = delete;
@@ -344,7 +350,9 @@ class BitOutputArchive {
auto initOutFileStream( const fs::path& outArchive, bool updatingArchive ) const -> CMyComPtr< IOutStream >;
- BitOutputArchive( const BitAbstractArchiveCreator& creator, const fs::path& inArc );
+ BitOutputArchive( const BitAbstractArchiveCreator& creator,
+ const fs::path& inArc,
+ ArchiveStartOffset archiveStart );
void compressToFile( const fs::path& outFile, UpdateCallback* updateCallback );
diff --git a/src/bitarchiveeditor.cpp b/src/bitarchiveeditor.cpp
index 2bbe1f67..ae0efe93 100644
--- a/src/bitarchiveeditor.cpp
+++ b/src/bitarchiveeditor.cpp
@@ -28,7 +28,7 @@ BitArchiveEditor::BitArchiveEditor( const Bit7zLibrary& lib,
const tstring& inFile,
const BitInOutFormat& format,
const tstring& password )
- : BitArchiveWriter( lib, inFile, format, password ) {
+ : BitArchiveWriter( lib, inFile, ArchiveStartOffset::FileStart, format, password ) {
if ( inputArchive() != nullptr ) {
return; // Input file was correctly read by base class BitOutputArchive constructor
}
@@ -198,7 +198,7 @@ void BitArchiveEditor::applyChanges() {
auto archivePath = inputArchive()->archivePath();
compressTo( archivePath );
mEditedItems.clear();
- setInputArchive( std::make_unique< BitInputArchive >( *this, archivePath ) );
+ setInputArchive( std::make_unique< BitInputArchive >( *this, archivePath, ArchiveStartOffset::FileStart ) );
}
auto BitArchiveEditor::findItem( const tstring& itemPath ) -> uint32_t {
diff --git a/src/bitarchivereader.cpp b/src/bitarchivereader.cpp
index 3c318712..cffd4a1d 100644
--- a/src/bitarchivereader.cpp
+++ b/src/bitarchivereader.cpp
@@ -18,6 +18,13 @@
using namespace bit7z;
+BitArchiveReader::BitArchiveReader( const Bit7zLibrary& lib,
+ const tstring& inArchive,
+ ArchiveStartOffset archiveStart,
+ const BitInFormat& format,
+ const tstring& password )
+ : BitAbstractArchiveOpener( lib, format, password ), BitInputArchive( *this, inArchive, archiveStart ) {}
+
BitArchiveReader::BitArchiveReader( const Bit7zLibrary& lib,
const tstring& inArchive,
const BitInFormat& format,
@@ -25,11 +32,25 @@ BitArchiveReader::BitArchiveReader( const Bit7zLibrary& lib,
: BitAbstractArchiveOpener( lib, format, password ), BitInputArchive( *this, inArchive ) {}
BitArchiveReader::BitArchiveReader( const Bit7zLibrary& lib,
- const std::vector< byte_t >& inArchive,
+ const buffer_t& inArchive,
+ ArchiveStartOffset archiveStart,
+ const BitInFormat& format,
+ const tstring& password )
+ : BitAbstractArchiveOpener( lib, format, password ), BitInputArchive( *this, inArchive, archiveStart ) {}
+
+BitArchiveReader::BitArchiveReader( const Bit7zLibrary& lib,
+ const buffer_t& inArchive,
const BitInFormat& format,
const tstring& password )
: BitAbstractArchiveOpener( lib, format, password ), BitInputArchive( *this, inArchive ) {}
+BitArchiveReader::BitArchiveReader( const Bit7zLibrary& lib,
+ std::istream& inArchive,
+ ArchiveStartOffset archiveStart,
+ const BitInFormat& format,
+ const tstring& password )
+ : BitAbstractArchiveOpener( lib, format, password ), BitInputArchive( *this, inArchive, archiveStart ) {}
+
BitArchiveReader::BitArchiveReader( const Bit7zLibrary& lib,
std::istream& inArchive,
const BitInFormat& format,
diff --git a/src/bitarchivewriter.cpp b/src/bitarchivewriter.cpp
index e91e20fa..66e74185 100644
--- a/src/bitarchivewriter.cpp
+++ b/src/bitarchivewriter.cpp
@@ -18,6 +18,14 @@ namespace bit7z {
BitArchiveWriter::BitArchiveWriter( const Bit7zLibrary& lib, const BitInOutFormat& format )
: BitAbstractArchiveCreator( lib, format ), BitOutputArchive( *this, tstring{} ) {}
+BitArchiveWriter::BitArchiveWriter( const Bit7zLibrary& lib,
+ const tstring& inArchive,
+ ArchiveStartOffset startOffset,
+ const BitInOutFormat& format,
+ const tstring& password )
+ : BitAbstractArchiveCreator( lib, format, password, UpdateMode::Append ),
+ BitOutputArchive( *this, inArchive, startOffset ) {}
+
BitArchiveWriter::BitArchiveWriter( const Bit7zLibrary& lib,
const tstring& inArchive,
const BitInOutFormat& format,
@@ -26,12 +34,28 @@ BitArchiveWriter::BitArchiveWriter( const Bit7zLibrary& lib,
BitOutputArchive( *this, inArchive ) {}
BitArchiveWriter::BitArchiveWriter( const Bit7zLibrary& lib,
- const std::vector< byte_t >& inArchive,
+ const buffer_t& inArchive,
+ ArchiveStartOffset startOffset,
+ const BitInOutFormat& format,
+ const tstring& password )
+ : BitAbstractArchiveCreator( lib, format, password, UpdateMode::Append ),
+ BitOutputArchive( *this, inArchive, startOffset ) {}
+
+BitArchiveWriter::BitArchiveWriter( const Bit7zLibrary& lib,
+ const buffer_t& inArchive,
const BitInOutFormat& format,
const tstring& password )
: BitAbstractArchiveCreator( lib, format, password, UpdateMode::Append ),
BitOutputArchive( *this, inArchive ) {}
+BitArchiveWriter::BitArchiveWriter( const Bit7zLibrary& lib,
+ std::istream& inArchive,
+ ArchiveStartOffset startOffset,
+ const BitInOutFormat& format,
+ const tstring& password )
+ : BitAbstractArchiveCreator( lib, format, password, UpdateMode::Append ),
+ BitOutputArchive( *this, inArchive, startOffset ) {}
+
BitArchiveWriter::BitArchiveWriter( const Bit7zLibrary& lib,
std::istream& inArchive,
const BitInOutFormat& format,
diff --git a/src/bitinputarchive.cpp b/src/bitinputarchive.cpp
index a73f1217..9aacff49 100644
--- a/src/bitinputarchive.cpp
+++ b/src/bitinputarchive.cpp
@@ -59,7 +59,9 @@ void extract_arc( IInArchive* inArchive,
}
}
-auto BitInputArchive::openArchiveStream( const fs::path& name, IInStream* inStream ) -> IInArchive* {
+auto BitInputArchive::openArchiveStream( const fs::path& name,
+ IInStream* inStream,
+ ArchiveStartOffset startOffset ) -> IInArchive* {
#ifdef BIT7Z_AUTO_FORMAT
bool detectedBySignature = false;
if ( *mDetectedFormat == BitFormat::Auto ) {
@@ -81,7 +83,13 @@ auto BitInputArchive::openArchiveStream( const fs::path& name, IInStream* inStre
#ifndef BIT7Z_AUTO_FORMAT
const
#endif
- HRESULT res = inArchive->Open( inStream, nullptr, openCallback );
+ HRESULT res = [&]() -> HRESULT {
+ if ( startOffset == ArchiveStartOffset::FileStart ) {
+ const UInt64 maxCheckStartPosition = 0;
+ return inArchive->Open( inStream, &maxCheckStartPosition, openCallback );
+ }
+ return inArchive->Open( inStream, nullptr, openCallback );
+ }();
#ifdef BIT7Z_AUTO_FORMAT
if ( res != S_OK && mArchiveHandler.format() == BitFormat::Auto && !detectedBySignature ) {
@@ -119,10 +127,14 @@ inline auto detect_format( const BitInFormat& format, const fs::path& arcPath )
#endif
}
-BitInputArchive::BitInputArchive( const BitAbstractArchiveHandler& handler, const tstring& inFile )
- : BitInputArchive( handler, tstring_to_path( inFile ) ) {}
+BitInputArchive::BitInputArchive( const BitAbstractArchiveHandler& handler,
+ const tstring& inFile,
+ ArchiveStartOffset startOffset )
+ : BitInputArchive( handler, tstring_to_path( inFile ), startOffset ) {}
-BitInputArchive::BitInputArchive( const BitAbstractArchiveHandler& handler, const fs::path& arcPath )
+BitInputArchive::BitInputArchive( const BitAbstractArchiveHandler& handler,
+ const fs::path& arcPath,
+ ArchiveStartOffset startOffset )
: mDetectedFormat{ detect_format( handler.format(), arcPath ) },
mArchiveHandler{ handler },
mArchivePath{ path_to_tstring( arcPath ) } {
@@ -132,21 +144,25 @@ BitInputArchive::BitInputArchive( const BitAbstractArchiveHandler& handler, cons
} else {
fileStream = bit7z::make_com< CFileInStream, IInStream >( arcPath );
}
- mInArchive = openArchiveStream( arcPath, fileStream );
+ mInArchive = openArchiveStream( arcPath, fileStream, startOffset );
}
-BitInputArchive::BitInputArchive( const BitAbstractArchiveHandler& handler, const std::vector< byte_t >& inBuffer )
+BitInputArchive::BitInputArchive( const BitAbstractArchiveHandler& handler,
+ const buffer_t& inBuffer,
+ ArchiveStartOffset startOffset )
: mDetectedFormat{ &handler.format() }, // if auto, detect the format from content, otherwise try the passed format.
mArchiveHandler{ handler } {
auto bufStream = bit7z::make_com< CBufferInStream, IInStream >( inBuffer );
- mInArchive = openArchiveStream( fs::path{}, bufStream );
+ mInArchive = openArchiveStream( fs::path{}, bufStream, startOffset );
}
-BitInputArchive::BitInputArchive( const BitAbstractArchiveHandler& handler, std::istream& inStream )
+BitInputArchive::BitInputArchive( const BitAbstractArchiveHandler& handler,
+ std::istream& inStream,
+ ArchiveStartOffset startOffset )
: mDetectedFormat{ &handler.format() }, // if auto, detect the format from content, otherwise try the passed format.
mArchiveHandler{ handler } {
auto stdStream = bit7z::make_com< CStdInStream, IInStream >( inStream );
- mInArchive = openArchiveStream( fs::path{}, stdStream );
+ mInArchive = openArchiveStream( fs::path{}, stdStream, startOffset );
}
auto BitInputArchive::archiveProperty( BitProperty property ) const -> BitPropVariant {
diff --git a/src/bitoutputarchive.cpp b/src/bitoutputarchive.cpp
index 0872ecda..babcc37e 100644
--- a/src/bitoutputarchive.cpp
+++ b/src/bitoutputarchive.cpp
@@ -26,10 +26,14 @@ namespace bit7z {
BitOutputArchive::BitOutputArchive( const BitAbstractArchiveCreator& creator )
: mArchiveCreator{ creator }, mInputArchiveItemsCount{ 0 } {}
-BitOutputArchive::BitOutputArchive( const BitAbstractArchiveCreator& creator, const tstring& inFile )
- : BitOutputArchive( creator, tstring_to_path( inFile ) ) {}
+BitOutputArchive::BitOutputArchive( const BitAbstractArchiveCreator& creator,
+ const tstring& inFile,
+ ArchiveStartOffset startOffset )
+ : BitOutputArchive( creator, tstring_to_path( inFile ), startOffset ) {}
-BitOutputArchive::BitOutputArchive( const BitAbstractArchiveCreator& creator, const fs::path& inArc )
+BitOutputArchive::BitOutputArchive( const BitAbstractArchiveCreator& creator,
+ const fs::path& inArc,
+ ArchiveStartOffset archiveStart )
: mArchiveCreator{ creator }, mInputArchiveItemsCount{ 0 } {
if ( mArchiveCreator.overwriteMode() != OverwriteMode::None ) {
return;
@@ -55,23 +59,26 @@ BitOutputArchive::BitOutputArchive( const BitAbstractArchiveCreator& creator, co
make_error_code( BitError::FormatFeatureNotSupported ) );
}
- mInputArchive = std::make_unique< BitInputArchive >( creator, inArc );
+ mInputArchive = std::make_unique< BitInputArchive >( creator, inArc, archiveStart );
mInputArchiveItemsCount = mInputArchive->itemsCount();
}
BitOutputArchive::BitOutputArchive( const BitAbstractArchiveCreator& creator,
- const std::vector< bit7z::byte_t >& inBuffer )
+ const buffer_t& inBuffer,
+ ArchiveStartOffset startOffset )
: mArchiveCreator{ creator }, mInputArchiveItemsCount{ 0 } {
if ( !inBuffer.empty() ) {
- mInputArchive = std::make_unique< BitInputArchive >( creator, inBuffer );
+ mInputArchive = std::make_unique< BitInputArchive >( creator, inBuffer, startOffset );
mInputArchiveItemsCount = mInputArchive->itemsCount();
}
}
-BitOutputArchive::BitOutputArchive( const BitAbstractArchiveCreator& creator, std::istream& inStream )
+BitOutputArchive::BitOutputArchive( const BitAbstractArchiveCreator& creator,
+ std::istream& inStream,
+ ArchiveStartOffset startOffset )
: mArchiveCreator{ creator }, mInputArchiveItemsCount{ 0 } {
if ( inStream.good() ) {
- mInputArchive = std::make_unique< BitInputArchive >( creator, inStream );
+ mInputArchive = std::make_unique< BitInputArchive >( creator, inStream, startOffset );
mInputArchiveItemsCount = mInputArchive->itemsCount();
}
}
From 7d640d53f56b445aa7f7ed0a362967338f0ec7ae Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 3 Nov 2024 10:12:52 +0100
Subject: [PATCH 05/31] Add tests for archive start offset
---
tests/CMakeLists.txt | 2 +-
tests/src/test_bitarchivereader.cpp | 183 +++++++++++++++++++++++++++-
2 files changed, 183 insertions(+), 2 deletions(-)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 7956ebc8..bdf87f19 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -53,7 +53,7 @@ if( BIT7Z_TESTS_FILESYSTEM )
include( FetchContent )
FetchContent_Declare( bit7z-test-data
GIT_REPOSITORY https://github.com/rikyoz/bit7z-test-data.git
- GIT_TAG abc1adc273dd8dd17f55969838811f98872d77b8
+ GIT_TAG 5e8143dfefac51cf3c67e72d733f64a3c1e44174
GIT_SHALLOW ON
SOURCE_DIR ${BIT7Z_TESTS_DATA_DIR} )
FetchContent_MakeAvailable( bit7z-test-data )
diff --git a/tests/src/test_bitarchivereader.cpp b/tests/src/test_bitarchivereader.cpp
index c3fdbdb3..ea89c02d 100644
--- a/tests/src/test_bitarchivereader.cpp
+++ b/tests/src/test_bitarchivereader.cpp
@@ -980,4 +980,185 @@ TEST_CASE( "BitArchiveReader: Format detection of archives", "[bitarchivereader]
}
}
-#endif
\ No newline at end of file
+#endif
+
+
+// NOLINTNEXTLINE(*-err58-cpp)
+TEMPLATE_TEST_CASE( "BitInputArchive: Reading the archive from the start of the input file",
+ "[bitinputarchive]", tstring, buffer_t, stream_t ) {
+ const TestDirectory testDir{ fs::path{ test_archives_dir } / "extraction" / "single_file" };
+
+#ifdef BIT7Z_BUILD_FOR_P7ZIP
+ const auto testArchive = GENERATE( as< TestInputFormat >(),
+ TestInputFormat{ "7z", BitFormat::SevenZip },
+ TestInputFormat{ "bz2", BitFormat::BZip2 },
+ TestInputFormat{ "gz", BitFormat::GZip },
+ TestInputFormat{ "iso", BitFormat::Iso },
+ TestInputFormat{ "lzh", BitFormat::Lzh },
+ TestInputFormat{ "lzma", BitFormat::Lzma },
+ TestInputFormat{ "tar", BitFormat::Tar },
+ TestInputFormat{ "wim", BitFormat::Wim },
+ TestInputFormat{ "xz", BitFormat::Xz },
+ TestInputFormat{ "zip", BitFormat::Zip } );
+#else
+ const auto testArchive = GENERATE( as< TestInputFormat >(),
+ TestInputFormat{ "7z", BitFormat::SevenZip },
+ TestInputFormat{ "bz2", BitFormat::BZip2 },
+ TestInputFormat{ "gz", BitFormat::GZip },
+ TestInputFormat{ "iso", BitFormat::Iso },
+ TestInputFormat{ "lzh", BitFormat::Lzh },
+ TestInputFormat{ "lzma", BitFormat::Lzma },
+ TestInputFormat{ "rar4.rar", BitFormat::Rar },
+ TestInputFormat{ "rar5.rar", BitFormat::Rar5 },
+ TestInputFormat{ "tar", BitFormat::Tar },
+ TestInputFormat{ "wim", BitFormat::Wim },
+ TestInputFormat{ "xz", BitFormat::Xz },
+ TestInputFormat{ "zip", BitFormat::Zip } );
+#endif
+
+ DYNAMIC_SECTION( "Archive format: " << testArchive.extension ) {
+ const fs::path arcFileName = fs::path{ clouds.name }.concat( "." + testArchive.extension );
+
+ TestType inputArchive{};
+ getInputArchive( arcFileName, inputArchive );
+ const Bit7zLibrary lib{ test::sevenzip_lib_path() };
+ REQUIRE_NOTHROW( BitArchiveReader( lib, inputArchive, ArchiveStartOffset::FileStart, testArchive.format ) );
+ }
+}
+
+// NOLINTNEXTLINE(*-err58-cpp)
+TEMPLATE_TEST_CASE( "BitInputArchive: Scanning a file for the archive start",
+ "[bitinputarchive]", tstring, buffer_t, stream_t ) {
+ const TestDirectory testDir{ fs::path{ test_archives_dir } / "extraction" / "nested" };
+
+ const fs::path arcFileName = "multiple_nested2.tar";
+
+ TestType inputArchive{};
+ getInputArchive( arcFileName, inputArchive );
+ const Bit7zLibrary lib{ test::sevenzip_lib_path() };
+
+#ifdef BIT7Z_AUTO_FORMAT
+ SECTION( "Detecting the format from the file extension (extension is correct)" ) {
+ const BitArchiveReader reader( lib, inputArchive, ArchiveStartOffset::None );
+ REQUIRE_NOTHROW( reader.detectedFormat() == BitFormat::Tar );
+ }
+#endif
+
+ SECTION( "Opening the archive with the Zip format succeeds, "
+ "as 7-Zip will scan the input Tar archive and find the nested Zip archive" ) {
+ REQUIRE_NOTHROW( BitArchiveReader( lib, inputArchive, ArchiveStartOffset::None, BitFormat::Zip ) );
+ }
+
+ SECTION( "Opening the archive with the 7z format succeeds, "
+ "as 7-Zip will scan the input Tar archive and find the nested 7z archive" ) {
+ REQUIRE_NOTHROW( BitArchiveReader( lib, inputArchive, ArchiveStartOffset::None, BitFormat::SevenZip ) );
+ }
+
+ SECTION( "The BZip2 format doesn't support scanning the input file for the archive start,"
+ "so the opening must fail even though the Tar archive contains a BZip2 file") {
+ REQUIRE_THROWS( BitArchiveReader( lib, inputArchive, ArchiveStartOffset::None, BitFormat::BZip2 ) );
+ }
+}
+
+// NOLINTNEXTLINE(*-err58-cpp)
+TEMPLATE_TEST_CASE( "BitInputArchive: Checking only the file start for the archive start",
+ "[bitinputarchive]", tstring, buffer_t, stream_t ) {
+ const TestDirectory testDir{ fs::path{ test_archives_dir } / "extraction" / "nested" };
+
+ const fs::path arcFileName = "multiple_nested2.tar";
+
+ TestType inputArchive{};
+ getInputArchive( arcFileName, inputArchive );
+ const Bit7zLibrary lib{ test::sevenzip_lib_path() };
+
+#ifdef BIT7Z_AUTO_FORMAT
+ SECTION( "Detecting the format from the file extension (extension is correct)" ) {
+ const BitArchiveReader reader( lib, inputArchive, ArchiveStartOffset::FileStart );
+ REQUIRE_NOTHROW( reader.detectedFormat() == BitFormat::Tar );
+ }
+#endif
+
+ SECTION( "Opening the Tar file as a Zip archive fails, as 7-Zip will check the format only at the file start" ) {
+ REQUIRE_THROWS( BitArchiveReader( lib, inputArchive, ArchiveStartOffset::FileStart, BitFormat::Zip ) );
+ }
+
+ SECTION( "Opening the Tar file as a 7z archive fails, as 7-Zip will check the format only at the file start" ) {
+ REQUIRE_THROWS( BitArchiveReader( lib, inputArchive, ArchiveStartOffset::FileStart, BitFormat::SevenZip ) );
+ }
+
+ SECTION( "Opening the Tar file as a BZip2 archive fails, as 7-Zip will check the format only at the file start" ) {
+ REQUIRE_THROWS( BitArchiveReader( lib, inputArchive, ArchiveStartOffset::FileStart, BitFormat::BZip2 ) );
+ }
+}
+
+// NOLINTNEXTLINE(*-err58-cpp)
+TEMPLATE_TEST_CASE( "BitInputArchive: Reading a nested archive with wrong extension",
+ "[bitinputarchive]", tstring, buffer_t, stream_t ) {
+ const TestDirectory testDir{ fs::path{ test_archives_dir } / "detection" };
+
+ const fs::path arcFileName = "nested_wrong_extension.zip"; // 7z file with zip extension
+
+ TestType inputArchive{};
+ getInputArchive( arcFileName, inputArchive );
+ const Bit7zLibrary lib{ test::sevenzip_lib_path() };
+
+ SECTION( "Checking archive start at input file start" ){
+#ifdef BIT7Z_AUTO_FORMAT
+ const BitArchiveReader reader( lib, inputArchive, ArchiveStartOffset::FileStart );
+ REQUIRE( reader.detectedFormat() == BitFormat::SevenZip );
+ REQUIRE_NOTHROW( reader.test() );
+#else
+ REQUIRE_THROWS( BitArchiveReader( lib, inputArchive, ArchiveStartOffset::FileStart, BitFormat::Zip ) );
+#endif
+ }
+
+ SECTION( "Checking archive start by scanning through the input file" ){
+#ifdef BIT7Z_AUTO_FORMAT
+ const BitArchiveReader reader( lib, inputArchive, ArchiveStartOffset::None );
+ if ( reader.archivePath().empty() ) {
+ REQUIRE( reader.detectedFormat() == BitFormat::SevenZip );
+ REQUIRE_NOTHROW( reader.test() );
+ } else {
+ REQUIRE( reader.detectedFormat() == BitFormat::Zip );
+ REQUIRE_THROWS( reader.test() );
+ }
+#else
+ const BitArchiveReader reader( lib, inputArchive, ArchiveStartOffset::None, BitFormat::Zip );
+ REQUIRE_THROWS( reader.test() );
+#endif
+ }
+}
+
+// NOLINTNEXTLINE(*-err58-cpp)
+TEMPLATE_TEST_CASE( "BitInputArchive: Reading a nested zip archive",
+ "[bitinputarchive]", tstring, buffer_t, stream_t ) {
+ const TestDirectory testDir{ fs::path{ test_archives_dir } / "extraction" / "nested" };
+
+ const fs::path arcFileName = "nested_zip.zip";
+
+ TestType inputArchive{};
+ getInputArchive( arcFileName, inputArchive );
+ const Bit7zLibrary lib{ test::sevenzip_lib_path() };
+
+ SECTION( "Checking archive start at input file start" ){
+#ifdef BIT7Z_AUTO_FORMAT
+ const BitArchiveReader reader( lib, inputArchive, ArchiveStartOffset::FileStart );
+ REQUIRE( reader.detectedFormat() == BitFormat::Zip );
+#else
+ const BitArchiveReader reader( lib, inputArchive, ArchiveStartOffset::FileStart, BitFormat::Zip );
+#endif
+ REQUIRE_NOTHROW( reader.test() );
+ REQUIRE( reader.contains( italy.name ) );
+ }
+
+ SECTION( "Checking archive start by scanning through the input file" ){
+#ifdef BIT7Z_AUTO_FORMAT
+ const BitArchiveReader reader( lib, inputArchive, ArchiveStartOffset::None );
+ REQUIRE( reader.detectedFormat() == BitFormat::Zip );
+#else
+ const BitArchiveReader reader( lib, inputArchive, ArchiveStartOffset::None, BitFormat::Zip );
+#endif
+ REQUIRE_NOTHROW( reader.test() );
+ REQUIRE( reader.contains( italy.name ) );
+ }
+}
\ No newline at end of file
From 1739c615c9cf1a9efaac646e9ee858fd1826f649 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 28 Sep 2024 21:39:16 +0200
Subject: [PATCH 06/31] Fix missing change from v3 in README
Close issue #245
---
README.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/README.md b/README.md
index 992f27f3..7b4d3162 100644
--- a/README.md
+++ b/README.md
@@ -219,6 +219,10 @@ The newest bit7z v4 introduced some significant breaking changes to the library'
+ The old `BitCompressor` class is now called `BitFileCompressor`.
+ Now `BitCompressor` is just the name of a template class for all the compression classes.
+ The `ProgressCallback` now must return a `bool` value indicating whether the current operation can continue (`true`) or not (`false`).
++ The `BitException` class now inherits from `std::system_error` rather than `std::runtime_error`.
+
+ + The method `BitException::getErrorCode()` was renamed `BitException::hresultCode()`.
+
+ The project structure changed:
+ Public API headers moved from `include/` to the `include/bit7z/` folder, so `#include` directives now need to prepend `bit7z/` to the included header name (e.g., `#include `).
+ Even though it is a bit verbose, it is a typical structure for C and C++ libraries, and it makes explicit which third-party library a header file belongs to.
From a0e483171c41d4387b9088aac524cfeea32e405c Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 6 Oct 2024 11:07:48 +0200
Subject: [PATCH 07/31] Fix long path support for UNC paths
Close issue #240
---
src/internal/fsutil.cpp | 10 +++++++++-
tests/src/test_fsutil.cpp | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/src/internal/fsutil.cpp b/src/internal/fsutil.cpp
index ffbd9f3a..10be36f5 100644
--- a/src/internal/fsutil.cpp
+++ b/src/internal/fsutil.cpp
@@ -302,7 +302,9 @@ auto fsutil::get_file_attributes_ex( const fs::path& filePath,
#if defined( _WIN32 ) && defined( BIT7Z_AUTO_PREFIX_LONG_PATHS )
+namespace {
constexpr auto kLongPathPrefix = BIT7Z_NATIVE_STRING( R"(\\?\)" );
+} // namespace
auto fsutil::should_format_long_path( const fs::path& path ) -> bool {
constexpr auto kMaxDosFilenameSize = 12;
@@ -311,7 +313,7 @@ auto fsutil::should_format_long_path( const fs::path& path ) -> bool {
return false;
}
const auto& pathStr = path.native();
- if ( pathStr.size() < ( MAX_PATH - kMaxDosFilenameSize ) ) {
+ if ( pathStr.size() < static_cast( MAX_PATH - kMaxDosFilenameSize ) ) {
return false;
}
return !starts_with( pathStr, kLongPathPrefix );
@@ -319,6 +321,12 @@ auto fsutil::should_format_long_path( const fs::path& path ) -> bool {
auto fsutil::format_long_path( const fs::path& path ) -> fs::path {
fs::path longPath = kLongPathPrefix;
+ // Note: we call this function after checking if we should format the given path as a long path.
+ // This means that if the path starts with the \\ prefix,
+ // it is a UNC path and not a long path prefixed with \\?\.
+ if ( starts_with( path.native(), BIT7Z_NATIVE_STRING( R"(\\)" ) ) ) {
+ longPath += L"UNC\\";
+ }
longPath += path;
return longPath;
}
diff --git a/tests/src/test_fsutil.cpp b/tests/src/test_fsutil.cpp
index ffaa88a5..8a4d81ba 100644
--- a/tests/src/test_fsutil.cpp
+++ b/tests/src/test_fsutil.cpp
@@ -237,6 +237,40 @@ TEST_CASE( "fsutil: In-archive path computation", "[fsutil][in_archive_path]" )
#endif
+#if defined( _WIN32 ) && defined( BIT7Z_AUTO_PREFIX_LONG_PATHS )
+TEST_CASE( "fsutil: Format long Windows paths", "[fsutil][format_long_path]" ) {
+ const std::wstring kLongPathPrefix = BIT7Z_NATIVE_STRING( R"(\\?\)" );
+
+ constexpr auto short_path = L"short_path\\file.txt";
+ REQUIRE_FALSE( should_format_long_path( short_path ) );
+
+ constexpr auto very_long_path = LR"(C:\very\long\dummy\path\)"
+ LR"(ABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyz\0123456789\)"
+ LR"(Lorem ipsum dolor sit amet\consectetur adipiscing elit\)"
+ LR"(Mauris ac leo dui\Morbi non elit lacus\)"
+ LR"(Ut ullamcorper sapien eget commodo eleifend\Curabitur varius magna sit\)"
+ LR"(Hello_World.txt)";
+ REQUIRE( should_format_long_path( very_long_path ) );
+ REQUIRE( format_long_path( very_long_path ) == ( kLongPathPrefix + very_long_path ) );
+
+
+ const auto prefixed_very_long_path = std::wstring{ LR"(\\?\)" } + very_long_path;
+ REQUIRE_FALSE( should_format_long_path( prefixed_very_long_path ) );
+
+ constexpr auto very_long_unc_path = LR"(\\very\long\dummy\UNC\path\)"
+ LR"(ABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyz\0123456789\)"
+ LR"(Lorem ipsum dolor sit amet\consectetur adipiscing elit\)"
+ LR"(Mauris ac leo dui\Morbi non elit lacus\)"
+ LR"(Ut ullamcorper sapien eget commodo eleifend\Curabitur varius magna sit\)"
+ LR"(Hello_World.txt)";
+ REQUIRE( should_format_long_path( very_long_unc_path ) );
+ REQUIRE( format_long_path( very_long_unc_path ) == ( kLongPathPrefix + L"UNC\\" + very_long_unc_path ) );
+
+ const auto prefixed_very_long_unc_path = std::wstring{ LR"(\\?\UNC\)" } + very_long_unc_path;
+ REQUIRE_FALSE( should_format_long_path( prefixed_very_long_unc_path ) );
+}
+#endif
+
#if defined( _WIN32 ) && defined( BIT7Z_PATH_SANITIZATION )
TEST_CASE( "fsutil: Sanitizing Windows paths", "[fsutil][sanitize_path]" ) {
REQUIRE( sanitize_path( L"hello world.txt" ) == L"hello world.txt" );
From ecd6c3014c83876f4d3210ac5e554c3a3ac8e76f Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 6 Oct 2024 15:52:18 +0200
Subject: [PATCH 08/31] Improve error handling in OpenCallback
---
src/internal/opencallback.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/internal/opencallback.cpp b/src/internal/opencallback.cpp
index 427aa865..ce1be868 100644
--- a/src/internal/opencallback.cpp
+++ b/src/internal/opencallback.cpp
@@ -60,8 +60,9 @@ STDMETHODIMP OpenCallback::GetStream( const wchar_t* name, IInStream** inStream
if ( name != nullptr ) {
streamPath = streamPath.parent_path();
streamPath.append( name );
- const auto streamStatus = fs::status( streamPath );
- if ( !fs::exists( streamStatus ) || fs::is_directory( streamStatus ) ) { // avoid exceptions using status
+ std::error_code error;
+ const auto streamStatus = fs::status( streamPath, error );
+ if ( error || !fs::exists( streamStatus ) || fs::is_directory( streamStatus ) ) {
return S_FALSE;
}
}
From 9921e0cd145dfc25059c268645d299032ff7e9e0 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 19 Oct 2024 16:39:41 +0200
Subject: [PATCH 09/31] Explicitly use wide variant of Windows API functions in
fsutil
---
src/internal/fsutil.cpp | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/internal/fsutil.cpp b/src/internal/fsutil.cpp
index 10be36f5..8df736e1 100644
--- a/src/internal/fsutil.cpp
+++ b/src/internal/fsutil.cpp
@@ -238,13 +238,13 @@ auto fsutil::set_file_time( const fs::path& filePath,
}
bool res = false;
- HANDLE hFile = ::CreateFile( filePath.c_str(),
- GENERIC_READ | FILE_WRITE_ATTRIBUTES,
- FILE_SHARE_READ,
- nullptr,
- OPEN_EXISTING,
- 0,
- nullptr );
+ HANDLE hFile = ::CreateFileW( filePath.c_str(),
+ GENERIC_READ | FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ,
+ nullptr,
+ OPEN_EXISTING,
+ 0,
+ nullptr );
if ( hFile != INVALID_HANDLE_VALUE ) { // NOLINT(cppcoreguidelines-pro-type-cstyle-cast,performance-no-int-to-ptr)
res = ::SetFileTime( hFile, &creation, &access, &modified ) != FALSE;
CloseHandle( hFile );
@@ -273,7 +273,7 @@ auto fsutil::get_file_attributes_ex( const fs::path& filePath,
#ifdef _WIN32
(void)symlinkPolicy;
- return ::GetFileAttributesEx( filePath.c_str(), GetFileExInfoStandard, &fileMetadata ) != FALSE;
+ return ::GetFileAttributesExW( filePath.c_str(), GetFileExInfoStandard, &fileMetadata ) != FALSE;
#else
stat_t statInfo{};
const auto statRes = symlinkPolicy == SymlinkPolicy::Follow ?
From 71b4388532b4272f4bf50d9e7f2f05c4b01e6e2e Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 19 Oct 2024 16:40:43 +0200
Subject: [PATCH 10/31] Fix and improve the README
---
README.md | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 7b4d3162..51cd0a30 100644
--- a/README.md
+++ b/README.md
@@ -255,14 +255,16 @@ You can also clone/download this repository and build the library yourself (plea
+ **Operating System:** Windows, Linux, macOS, Android[^1].
+ **Architecture:** x86, x86_64, arm, arm64.
+ **Language Standard:** C++11 (for using the library), C++14 (for building the library).
-+ **Compiler:** MSVC 2015 or later[^2], MinGW v6.4 or later, GCC v4.9 or later, Clang 3.6 or later.
-+ **Shared Library:** a 7-zip `.dll` library on Windows, a 7-zip/p7zip `.so` library on Unix[^3].
++ **Compiler:** MSVC 2015 or later[^2], MinGW v6.4 or later[^3], GCC v4.9 or later, Clang 3.6 or later.
++ **Shared Library:** a 7-zip `.dll` library on Windows, a 7-zip/p7zip `.so` library on Unix[^4].
[^1]: On Windows, you should link your program _also_ with _oleaut32_ (e.g., `-lbit7z -loleaut32`). On Linux and macOS, you should link your program _also_ with _dl_ (e.g., `-lbit7z -ldl`). If you are using the library via CMake, these dependencies will be linked automatically to your project.
[^2]: MSVC 2010 was supported until v2.x, MSVC 2012/2013 until v3.x.
-[^3]: bit7z doesn't ship with the 7-zip shared libraries. You can build them from the source code available at [7-zip.org](http://www.7-zip.org/).
+[^3]: When using MinGW, you should link your program also with `libuuid` (e.g. `-lbit7z -loleaut32 -luuid`).
+
+[^4]: bit7z doesn't ship with the 7-zip shared libraries. You can build them from the source code available at [7-zip.org](http://www.7-zip.org/).
## ⚙️ Building and Using bit7z
From bd1c89f6e0660fd720ae2f9f521e40f1bf55a580 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 3 Nov 2024 10:22:04 +0100
Subject: [PATCH 11/31] Increase maximum dictionary size limit for LZMA
Close issue #256
---
src/bitabstractarchivecreator.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/bitabstractarchivecreator.cpp b/src/bitabstractarchivecreator.cpp
index 19f31c56..15182b8f 100644
--- a/src/bitabstractarchivecreator.cpp
+++ b/src/bitabstractarchivecreator.cpp
@@ -41,9 +41,9 @@ auto is_valid_compression_method( const BitInOutFormat& format, BitCompressionMe
}
auto is_valid_dictionary_size( BitCompressionMethod method, uint32_t dictionarySize ) noexcept -> bool {
- constexpr auto kMaxLzmaDictionarySize = 1536 * ( 1LL << 20 ); // less than 1536 MiB
- constexpr auto kMaxPpmdDictionarySize = ( 1LL << 30 ); // less than 1 GiB, i.e., 2^30 bytes
- constexpr auto kMaxBzip2DictionarySize = 900 * ( 1LL << 10 ); // less than 900 KiB
+ constexpr auto kMaxLzmaDictionarySize = 3840 * ( 1ull << 20ull ); // less than 3840 MiB
+ constexpr auto kMaxPpmdDictionarySize = ( 1ull << 30ull ); // less than 1 GiB, i.e., 2^30 bytes
+ constexpr auto kMaxBzip2DictionarySize = 900 * ( 1ull << 10ull ); // less than 900 KiB
switch ( method ) {
case BitCompressionMethod::Lzma:
From 32af0f5c2a0d00e5b364b2f2438df6820bb2af5b Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 3 Nov 2024 10:27:30 +0100
Subject: [PATCH 12/31] Add support for using format properties in
BitInputArchive
Close issue #248
---
include/bit7z/bitinputarchive.hpp | 21 +++++++++++++++++++++
include/bit7z/bittypes.hpp | 4 ++++
src/bitinputarchive.cpp | 18 ++++++++++++++++++
3 files changed, 43 insertions(+)
diff --git a/include/bit7z/bitinputarchive.hpp b/include/bit7z/bitinputarchive.hpp
index 9e630465..32bcfbc5 100644
--- a/include/bit7z/bitinputarchive.hpp
+++ b/include/bit7z/bitinputarchive.hpp
@@ -152,6 +152,27 @@ class BitInputArchive {
*/
BIT7Z_NODISCARD auto handler() const noexcept -> const BitAbstractArchiveHandler&;
+ /**
+ * @brief Use the given format property to read the archive.
+ *
+ * @param name the name of the property.
+ * @param property the property value.
+ */
+ void useFormatProperty( const wchar_t* name, const BitPropVariant& property ) const;
+
+ /**
+ * @brief Use the given format property to read the archive.
+ *
+ * @tparam T the type of the property.
+ * @param name the name of the property.
+ * @param value the property value.
+ */
+ template< typename T,
+ typename = typename std::enable_if< is_explicitly_convertible< T, BitPropVariant >::value >::type >
+ void useFormatProperty( const wchar_t* name, T&& value ) const { // NOLINT(*-avoid-c-arrays)
+ useFormatProperty( name, BitPropVariant{ std::forward< T >( value ) } );
+ }
+
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
inline void extract( const tstring& outDir, const std::vector< uint32_t >& indices = {} ) const {
extractTo( outDir, indices );
diff --git a/include/bit7z/bittypes.hpp b/include/bit7z/bittypes.hpp
index d0ebfbfa..cbefc9cc 100644
--- a/include/bit7z/bittypes.hpp
+++ b/include/bit7z/bittypes.hpp
@@ -120,6 +120,10 @@ auto to_tstring( const native_string& str ) -> tstring;
auto to_tstring( const native_string& str ) -> const tstring&;
#endif
+template< typename From, typename To >
+using is_explicitly_convertible = std::integral_constant< bool, std::is_constructible< To, From >::value &&
+ !std::is_convertible< From, To >::value >;
+
} // namespace bit7z
#endif // BITTYPES_HPP
diff --git a/src/bitinputarchive.cpp b/src/bitinputarchive.cpp
index 9aacff49..54b1347c 100644
--- a/src/bitinputarchive.cpp
+++ b/src/bitinputarchive.cpp
@@ -237,6 +237,24 @@ auto BitInputArchive::handler() const noexcept -> const BitAbstractArchiveHandle
return mArchiveHandler;
}
+void BitInputArchive::useFormatProperty( const wchar_t* name, const BitPropVariant& property ) const {
+ CMyComPtr< ISetProperties > setProperties;
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ HRESULT res = mInArchive->QueryInterface( ::IID_ISetProperties, reinterpret_cast< void** >( &setProperties ) );
+ if ( res != S_OK ) {
+ throw BitException( "ISetProperties unsupported", make_hresult_code( res ) );
+ }
+
+ const auto propertyNames = { name };
+ const auto propertyValues = { property };
+ res = setProperties->SetProperties( propertyNames.begin(),
+ propertyValues.begin(),
+ static_cast< std:: uint32_t >( propertyNames.size() ) );
+ if ( res != S_OK ) {
+ throw BitException( "Cannot use the archive format property", make_hresult_code( res ) );
+ }
+}
+
void BitInputArchive::extractTo( const tstring& outDir ) const {
auto callback = bit7z::make_com< FileExtractCallback, ExtractCallback >( *this, outDir );
extract_arc( mInArchive, {}, callback );
From 4669e81f21d6f29f052855fc46e43193cd2ce872 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 3 Nov 2024 10:31:39 +0100
Subject: [PATCH 13/31] Add tests for reading zip archives using a different
codepage encoding
---
tests/CMakeLists.txt | 2 +-
tests/src/test_bitarchivereader.cpp | 27 ++++++++++++++++++++++++++-
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index bdf87f19..60da280d 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -53,7 +53,7 @@ if( BIT7Z_TESTS_FILESYSTEM )
include( FetchContent )
FetchContent_Declare( bit7z-test-data
GIT_REPOSITORY https://github.com/rikyoz/bit7z-test-data.git
- GIT_TAG 5e8143dfefac51cf3c67e72d733f64a3c1e44174
+ GIT_TAG 077e407b1c07b7443626b5902eeb4819388bf656
GIT_SHALLOW ON
SOURCE_DIR ${BIT7Z_TESTS_DATA_DIR} )
FetchContent_MakeAvailable( bit7z-test-data )
diff --git a/tests/src/test_bitarchivereader.cpp b/tests/src/test_bitarchivereader.cpp
index ea89c02d..0c0c9726 100644
--- a/tests/src/test_bitarchivereader.cpp
+++ b/tests/src/test_bitarchivereader.cpp
@@ -1161,4 +1161,29 @@ TEMPLATE_TEST_CASE( "BitInputArchive: Reading a nested zip archive",
REQUIRE_NOTHROW( reader.test() );
REQUIRE( reader.contains( italy.name ) );
}
-}
\ No newline at end of file
+}
+
+#ifdef _WIN32
+TEMPLATE_TEST_CASE( "BitInputArchive: Reading a zip archive using a different encoding",
+ "[bitinputarchive]", tstring, buffer_t, stream_t ) {
+ const TestDirectory testDir{ fs::path{ test_archives_dir } / "metadata" / "unicode" };
+
+ const fs::path arcFileName = "codepage.zip";
+
+ TestType inputArchive{};
+ getInputArchive( arcFileName, inputArchive );
+ const Bit7zLibrary lib{ test::sevenzip_lib_path() };
+ const BitArchiveReader reader{ lib, inputArchive, BitFormat::Zip };
+ REQUIRE( reader.itemsCount() == 1 );
+
+ constexpr auto expectedItemName = BIT7Z_NATIVE_STRING( "ユニコード.pdf" );
+
+ // The archive uses the Shift-JS encoding (Codepage 932) for the file names.
+ // If we do not set the codepage to be used, 7-Zip will report a wrongly-encoded string for the name.
+ REQUIRE_FALSE( reader.itemAt( 0 ).nativePath() == expectedItemName );
+
+ // Setting the correct codepage will make 7-Zip correctly encode the string.
+ reader.useFormatProperty( L"cp", 932u );
+ REQUIRE( reader.itemAt( 0 ).nativePath() == expectedItemName );
+}
+#endif
\ No newline at end of file
From 8da189b905b6bba7d4c48b3fee6a56316bb2cd04 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 3 Nov 2024 10:32:56 +0100
Subject: [PATCH 14/31] [Test] Fix building tests using MinGW
---
tests/src/test_cbufferinstream.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/src/test_cbufferinstream.cpp b/tests/src/test_cbufferinstream.cpp
index 8f43b958..e5159dac 100644
--- a/tests/src/test_cbufferinstream.cpp
+++ b/tests/src/test_cbufferinstream.cpp
@@ -17,6 +17,7 @@
#include
+#include
#include
using bit7z::byte_t;
From 9db31f286cfa20781b4db4e0f2650ddcacc0b81c Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 9 Nov 2024 21:34:44 +0100
Subject: [PATCH 15/31] Update and improve the README
---
README.md | 107 +++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 78 insertions(+), 29 deletions(-)
diff --git a/README.md b/README.md
index 51cd0a30..652bcfd8 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,27 @@
bit7z
-A C++ static library offering a clean and simple interface to the 7-zip shared libraries
+A C++ static library offering a clean and simple interface to the 7-zip shared libraries.
+
+
Supported Features •
Getting Started •
Download •
Requirements •
- Building & Using •
+ Installation •
+ Configuration •
Donate •
License
+
-
## ⚡️ Introduction
@@ -45,12 +48,12 @@ It supports compression and extraction to and from the filesystem or the memory,
+ **Operation callbacks** for obtaining real-time information about ongoing operations.
+ **Canceling** or **pausing** the current operation.
-### Notes
-
-The presence or not of some of the above features depends on the particular shared library used along with bit7z.
-For example, 7z.dll should support all these features, 7za.dll should work only with the 7z file format, and 7zxa.dll can only extract 7z files. For more information about the 7-zip DLLs, please check this [wiki page](https://github.com/rikyoz/bit7z/wiki/7z-DLLs).
-
-In the end, some other features (e.g., _automatic format detection_ and _selective extraction using regular expressions_) are disabled by default, and macro definitions must be used during compilation to have them available ([wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library)).
+> [!NOTE]
+>
+> The presence or not of some of the above features depends on the particular shared library used along with bit7z.
+> For example, 7z.dll should support all these features, 7za.dll should work only with the 7z file format, and 7zxa.dll can only extract 7z files. For more information about the 7-zip DLLs, please check this [wiki page](https://github.com/rikyoz/bit7z/wiki/7z-DLLs).
+>
+> In the end, some other features (e.g., _automatic format detection_ and _selective extraction using regular expressions_) are disabled by default, and macro definitions must be used during compilation to have them available ([wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library)).
## 🔥 Getting Started (Library Usage)
@@ -256,7 +259,7 @@ You can also clone/download this repository and build the library yourself (plea
+ **Architecture:** x86, x86_64, arm, arm64.
+ **Language Standard:** C++11 (for using the library), C++14 (for building the library).
+ **Compiler:** MSVC 2015 or later[^2], MinGW v6.4 or later[^3], GCC v4.9 or later, Clang 3.6 or later.
-+ **Shared Library:** a 7-zip `.dll` library on Windows, a 7-zip/p7zip `.so` library on Unix[^4].
++ **Shared Library:** a 7-zip `.dll` library on Windows, a 7-zip/p7zip[^4] `.so` library on Unix[^5].
[^1]: On Windows, you should link your program _also_ with _oleaut32_ (e.g., `-lbit7z -loleaut32`). On Linux and macOS, you should link your program _also_ with _dl_ (e.g., `-lbit7z -ldl`). If you are using the library via CMake, these dependencies will be linked automatically to your project.
@@ -264,11 +267,56 @@ You can also clone/download this repository and build the library yourself (plea
[^3]: When using MinGW, you should link your program also with `libuuid` (e.g. `-lbit7z -loleaut32 -luuid`).
-[^4]: bit7z doesn't ship with the 7-zip shared libraries. You can build them from the source code available at [7-zip.org](http://www.7-zip.org/).
+[^4]: bit7z doesn't support RAR archives when using the p7zip `.so` libraries.
+
+[^5]: bit7z doesn't ship with the 7-zip shared libraries. You can build them from the source code available at [7-zip.org](http://www.7-zip.org/).
+
+## 🔗 Installation
+
+Bit7z can be used as a dependency in several alternative ways:
+
+### Using [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake)
+
+```cmake
+CPMAddPackage("gh:rikyoz/bit7z@") # Replace with the version of bit7z you want to use.
+# To enable/disable build options, use set(BIT7Z_ ON CACHE BOOL "enable option" FORCE) here.
+target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
+```
+
+### Using [vcpkg](https://vcpkg.io/en/)
+
+First, you need to install the library:
+
+```cmd
+vcpkg install bit7z
+```
+
+Then, you add bit7z as a dependency in your project's CMakeLists.txt:
+
+```cmake
+find_package(unofficial-bit7z CONFIG REQUIRED)
+target_link_libraries(${YOUR_TARGET} PRIVATE unofficial::bit7z::bit7z64)
+```
+
+### Using CMake
+
+You can also directly integrate the library into your CMake project:
+
++ Either download bit7z's sources to a sub-directory of your project (e.g., `third_party`), or add this repository as a git submodule of yours.
++ Then, use the command `add_subdirectory()` in your `CMakeLists.txt` to include bit7z.
++ Finally, link the `bit7z` library using the `target_link_libraries()` command.
+
+For example:
-## ⚙️ Building and Using bit7z
+```cmake
+add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/bit7z)
+# To enable/disable build options, use set(BIT7Z_ ON CACHE BOOL "enable option" FORCE) here.
+target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
+```
+
+### Building from sources and manually linking
-For building the library:
+For manually building the library:
```bash
cd
@@ -277,21 +325,20 @@ cmake ../ -DCMAKE_BUILD_TYPE=Release
cmake --build . -j --config Release
```
-A more detailed guide on how to build this library is available [here](https://github.com/rikyoz/bit7z/wiki/Building-the-library).
-
-You can also directly integrate the library into your project via CMake:
+A `.lib`/`.a` library file will be produced in the `/lib//` folder.
-+ Download bit7z and copy it into a sub-directory of your project (e.g., `third_party`), or add it as a git submodule of your repository.
-+ Then, use the command `add_subdirectory()` in your `CMakeLists.txt` to include bit7z.
-+ Finally, link the `bit7z` library using the `target_link_libraries()` command.
+A more detailed guide on how to build this library is available [here](https://github.com/rikyoz/bit7z/wiki/Building-the-library).
-For example:
+Once built, you can copy the library file and bit7z's `include` folder in the desired subfolders of your project, and then manually link the library to your application, e.g., in your CMake project:
```cmake
-add_subdirectory( ${CMAKE_SOURCE_DIR}/third_party/bit7z )
-target_link_libraries( ${YOUR_TARGET} PRIVATE bit7z )
+target_include_directories(${YOUR_TARGET} PRIVATE "")
+target_link_directories(${YOUR_TARGET} PRIVATE "")
+target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
```
+## ⚙️ Configuration
+
The library is highly customizable: for a detailed list of the available build options, please refer to the [wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library#%EF%B8%8F-build-options).
### 📌 7-zip Version
@@ -302,7 +349,10 @@ Optionally, you can specify a different version of 7-zip via the CMake option `B
Alternatively, you can specify a custom path containing the 7-zip source code via the option `BIT7Z_CUSTOM_7ZIP_PATH`.
-Please note that, in general, it is best to use the same version of 7-zip of the shared libraries that you will use at runtime.
+> [!NOTE]
+>
+> In general, it is best to use the same version of 7-zip of the shared libraries that you will use at runtime.
+>
#### Using 7-zip v23.01 on Linux and macOS
@@ -315,7 +365,6 @@ If you plan to use the `7z.so` from p7zip or 7-zip v22.01 and earlier instead, y
Expand for more details
-
_On Linux and macOS_, 7-zip v23.01 introduced breaking changes to the IUnknown interface.
As a result, if you build bit7z for such a version of 7-zip (the default), it will not support using the shared libraries from previous versions of 7-zip (or from p7zip).
Conversely, bit7z made for earlier versions of 7-zip or for p7zip is incompatible with the shared libraries from 7-zip v23.01 and later.
@@ -359,7 +408,7 @@ However, if you need to handle non-ASCII/Unicode characters, as it is likely, yo
```cpp
#include //for _O_U16TEXT
#include //for _setmode
-
+
_setmode(_fileno(stdout), _O_U16TEXT); // setting the stdout encoding to UTF16
_setmode(_fileno(stdin), _O_U16TEXT); // setting the stdin encoding to UTF16
```
From 3d389f14269774e6528bee989bb1736f9e7d1ecd Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 9 Nov 2024 21:36:07 +0100
Subject: [PATCH 16/31] Fix menu in README
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 652bcfd8..c4f639bb 100644
--- a/README.md
+++ b/README.md
@@ -14,9 +14,9 @@
Getting Started •
Download •
Requirements •
- Installation •
- Configuration •
- Donate •
+ Installation •
+ Configuration •
+ Donate •
License
From b177d4bfad6c3f1e7ecccb98a6912248adb72d32 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 9 Nov 2024 21:43:21 +0100
Subject: [PATCH 17/31] Improve the README
---
README.md | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/README.md b/README.md
index c4f639bb..4d86c32d 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,7 @@
bit7z
-A C++ static library offering a clean and simple interface to the 7-zip shared libraries.
+A C++ static library offering a clean and simple interface to the 7-zip shared libraries.
-
@@ -22,6 +17,12 @@
+
+
## ⚡️ Introduction
@@ -50,10 +51,13 @@ It supports compression and extraction to and from the filesystem or the memory,
> [!NOTE]
>
-> The presence or not of some of the above features depends on the particular shared library used along with bit7z.
-> For example, 7z.dll should support all these features, 7za.dll should work only with the 7z file format, and 7zxa.dll can only extract 7z files. For more information about the 7-zip DLLs, please check this [wiki page](https://github.com/rikyoz/bit7z/wiki/7z-DLLs).
+> The presence or not of some of the above features depends on the particular shared library used along with bit7z. For example, 7z.dll should support all these features, 7za.dll should work only with the 7z file format, and 7zxa.dll can only extract 7z files.
+>
+> For more information about the 7-zip DLLs, please check this [wiki page](https://github.com/rikyoz/bit7z/wiki/7z-DLLs).
+
+> [!NOTE]
>
-> In the end, some other features (e.g., _automatic format detection_ and _selective extraction using regular expressions_) are disabled by default, and macro definitions must be used during compilation to have them available ([wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library)).
+> Some other features (e.g., _automatic format detection_ and _selective extraction using regular expressions_) are disabled by default, and macro definitions must be used during compilation to have them available ([wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library)).
## 🔥 Getting Started (Library Usage)
@@ -278,8 +282,9 @@ Bit7z can be used as a dependency in several alternative ways:
### Using [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake)
```cmake
-CPMAddPackage("gh:rikyoz/bit7z@") # Replace with the version of bit7z you want to use.
-# To enable/disable build options, use set(BIT7Z_ ON CACHE BOOL "enable option" FORCE) here.
+CPMAddPackage("gh:rikyoz/bit7z@") # Replace with the one you want to use.
+# Set bit7z's build options you want here, e.g.:
+# set(BIT7Z_AUTO_FORMAT ON CACHE BOOL "enable auto format support" FORCE)
target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
```
@@ -310,7 +315,8 @@ For example:
```cmake
add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/bit7z)
-# To enable/disable build options, use set(BIT7Z_ ON CACHE BOOL "enable option" FORCE) here.
+# Set bit7z's build options you want here, e.g.:
+# set(BIT7Z_USE_NATIVE_STRING ON CACHE BOOL "enable using native OS strings" FORCE)
target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
```
@@ -333,7 +339,7 @@ Once built, you can copy the library file and bit7z's `include` folder in the de
```cmake
target_include_directories(${YOUR_TARGET} PRIVATE "")
-target_link_directories(${YOUR_TARGET} PRIVATE "")
+link_directories(${YOUR_TARGET} PRIVATE "")
target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
```
From 3fed0539b2744459f66984e810d6cadd81707268 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 9 Nov 2024 22:01:01 +0100
Subject: [PATCH 18/31] Improve the README
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 4d86c32d..3c328b4a 100644
--- a/README.md
+++ b/README.md
@@ -282,8 +282,8 @@ Bit7z can be used as a dependency in several alternative ways:
### Using [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake)
```cmake
-CPMAddPackage("gh:rikyoz/bit7z@") # Replace with the one you want to use.
-# Set bit7z's build options you want here, e.g.:
+CPMAddPackage("gh:rikyoz/bit7z@") # Replace with the desired one.
+# Here you can set bit7z's build options you want, e.g.:
# set(BIT7Z_AUTO_FORMAT ON CACHE BOOL "enable auto format support" FORCE)
target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
```
@@ -315,7 +315,7 @@ For example:
```cmake
add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/bit7z)
-# Set bit7z's build options you want here, e.g.:
+# Here you can set bit7z's build options you want, e.g.:
# set(BIT7Z_USE_NATIVE_STRING ON CACHE BOOL "enable using native OS strings" FORCE)
target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
```
From a19955414e005de5cface6997d67a83731d03ebe Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 10 Nov 2024 10:28:46 +0100
Subject: [PATCH 19/31] Fix and improve the README
---
README.md | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index 3c328b4a..dcfb737e 100644
--- a/README.md
+++ b/README.md
@@ -277,13 +277,13 @@ You can also clone/download this repository and build the library yourself (plea
## 🔗 Installation
-Bit7z can be used as a dependency in several alternative ways:
+The library can be used as a dependency in a number of different ways:
### Using [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake)
```cmake
CPMAddPackage("gh:rikyoz/bit7z@") # Replace with the desired one.
-# Here you can set bit7z's build options you want, e.g.:
+# Here you can enable/disable bit7z's build options, e.g.:
# set(BIT7Z_AUTO_FORMAT ON CACHE BOOL "enable auto format support" FORCE)
target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
```
@@ -315,7 +315,7 @@ For example:
```cmake
add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/bit7z)
-# Here you can set bit7z's build options you want, e.g.:
+# Here you can enable/disable bit7z's build options, e.g.:
# set(BIT7Z_USE_NATIVE_STRING ON CACHE BOOL "enable using native OS strings" FORCE)
target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
```
@@ -335,12 +335,15 @@ A `.lib`/`.a` library file will be produced in the `/lib//`
A more detailed guide on how to build this library is available [here](https://github.com/rikyoz/bit7z/wiki/Building-the-library).
-Once built, you can copy the library file and bit7z's `include` folder in the desired subfolders of your project, and then manually link the library to your application, e.g., in your CMake project:
+Once built, you can copy the library file and bit7z's `include` folder in the desired subfolders of your project, and then manually link the library and its runtime dependencies to your application, e.g., in your CMake project:
```cmake
target_include_directories(${YOUR_TARGET} PRIVATE "")
-link_directories(${YOUR_TARGET} PRIVATE "")
-target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
+find_library(BIT7Z_LIB bit7z HINTS "")
+target_link_libraries(${YOUR_TARGET} PRIVATE ${BIT7Z_LIB}
+ $<$:oleaut32>
+ $<$:uuid>
+ $<$:dl>)
```
## ⚙️ Configuration
From 7e51a51468ea9562cea759593a2bf4d83e49a3d6 Mon Sep 17 00:00:00 2001
From: Oz
Date: Fri, 22 Nov 2024 21:56:48 +0100
Subject: [PATCH 20/31] Fix and improve the README
---
README.md | 61 +++++++++++++++++++++++++++++++------------------------
1 file changed, 35 insertions(+), 26 deletions(-)
diff --git a/README.md b/README.md
index dcfb737e..95c44b04 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
bit7z
-A C++ static library offering a clean and simple interface to the 7-zip shared libraries.
+A C++ static library offering a clean and simple interface to the 7-Zip shared libraries.
@@ -26,7 +26,7 @@
## ⚡️ Introduction
-**bit7z** is a _cross-platform_ C++ static library that allows the _compression/extraction of archive files_ through a _clean_ and _simple_ wrapper interface to the dynamic libraries from the [7-zip](https://www.7-zip.org/ "7-zip Project Homepage") project.
+**bit7z** is a _cross-platform_ C++ static library that allows the _compression/extraction of archive files_ through a _clean_ and _simple_ wrapper interface to the dynamic libraries from the [7-Zip](https://www.7-zip.org/ "7-Zip Project Homepage") project.
It supports compression and extraction to and from the filesystem or the memory, reading archives metadata, updating existing ones, creating multi-volume archives, operation progress callbacks, and many other functionalities.
## 🎯 Supported Features
@@ -51,13 +51,15 @@ It supports compression and extraction to and from the filesystem or the memory,
> [!NOTE]
>
-> The presence or not of some of the above features depends on the particular shared library used along with bit7z. For example, 7z.dll should support all these features, 7za.dll should work only with the 7z file format, and 7zxa.dll can only extract 7z files.
+> The presence or not of some of the above features depends on the specific 7-Zip shared library used.
>
-> For more information about the 7-zip DLLs, please check this [wiki page](https://github.com/rikyoz/bit7z/wiki/7z-DLLs).
+> For example, 7z.dll should support all these features, 7za.dll should work only with the 7z file format, and 7zxa.dll can only extract 7z files.
+>
+> For more information about the 7-Zip DLLs, please check this [wiki page](https://github.com/rikyoz/bit7z/wiki/7z-DLLs).
> [!NOTE]
>
-> Some other features (e.g., _automatic format detection_ and _selective extraction using regular expressions_) are disabled by default, and macro definitions must be used during compilation to have them available ([wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library)).
+> Some features (e.g., _automatic format detection_ and _selective extraction using regular expressions_) are disabled by default, and macro definitions must be used during compilation to have them available ([wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library)).
## 🔥 Getting Started (Library Usage)
@@ -263,18 +265,25 @@ You can also clone/download this repository and build the library yourself (plea
+ **Architecture:** x86, x86_64, arm, arm64.
+ **Language Standard:** C++11 (for using the library), C++14 (for building the library).
+ **Compiler:** MSVC 2015 or later[^2], MinGW v6.4 or later[^3], GCC v4.9 or later, Clang 3.6 or later.
-+ **Shared Library:** a 7-zip `.dll` library on Windows, a 7-zip/p7zip[^4] `.so` library on Unix[^5].
++ **Shared Library:** a 7-Zip `.dll` library on Windows, a 7-Zip/p7zip `.so` library on Unix.
-[^1]: On Windows, you should link your program _also_ with _oleaut32_ (e.g., `-lbit7z -loleaut32`). On Linux and macOS, you should link your program _also_ with _dl_ (e.g., `-lbit7z -ldl`). If you are using the library via CMake, these dependencies will be linked automatically to your project.
+> [!NOTE]
+>
+> The library does not support RAR archives when using the p7zip `.so` libraries.
+>
+> To extract RAR archives, you need to use 7-Zip's `.so` libraries.
+
+> [!NOTE]
+>
+> bit7z doesn't ship with the 7-Zip shared libraries.
+>
+> You can build them from the source code available at [7-zip.org](http://www.7-zip.org/).
+[^1]: On Windows, you should link your program _also_ with _oleaut32_ (e.g., `-lbit7z -loleaut32`). On Linux and macOS, you should link your program _also_ with _dl_ (e.g., `-lbit7z -ldl`). If you are using the library via CMake, these dependencies will be linked automatically to your project.
[^2]: MSVC 2010 was supported until v2.x, MSVC 2012/2013 until v3.x.
[^3]: When using MinGW, you should link your program also with `libuuid` (e.g. `-lbit7z -loleaut32 -luuid`).
-[^4]: bit7z doesn't support RAR archives when using the p7zip `.so` libraries.
-
-[^5]: bit7z doesn't ship with the 7-zip shared libraries. You can build them from the source code available at [7-zip.org](http://www.7-zip.org/).
-
## 🔗 Installation
The library can be used as a dependency in a number of different ways:
@@ -350,36 +359,36 @@ target_link_libraries(${YOUR_TARGET} PRIVATE ${BIT7Z_LIB}
The library is highly customizable: for a detailed list of the available build options, please refer to the [wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library#%EF%B8%8F-build-options).
-### 📌 7-zip Version
+### 📌 7-Zip Version
-While configuring bit7z via CMake, it automatically downloads the latest version of 7-zip supported by the library.
+While configuring bit7z via CMake, it automatically downloads the latest version of 7-Zip supported by the library.
-Optionally, you can specify a different version of 7-zip via the CMake option `BIT7Z_7ZIP_VERSION` (e.g., `-DBIT7Z_7ZIP_VERSION="22.01"`).
+Optionally, you can specify a different version of 7-Zip via the CMake option `BIT7Z_7ZIP_VERSION` (e.g., `-DBIT7Z_7ZIP_VERSION="22.01"`).
-Alternatively, you can specify a custom path containing the 7-zip source code via the option `BIT7Z_CUSTOM_7ZIP_PATH`.
+Alternatively, you can specify a custom path containing the 7-Zip source code via the option `BIT7Z_CUSTOM_7ZIP_PATH`.
> [!NOTE]
>
-> In general, it is best to use the same version of 7-zip of the shared libraries that you will use at runtime.
+> In general, it is best to use the same version of 7-Zip of the shared libraries that you will use at runtime.
>
-#### Using 7-zip v23.01 on Linux and macOS
+#### Using 7-Zip v23.01 on Linux and macOS
-By default, bit7z is compatible with the `7z.so` from 7-zip v23.01 and later.
+By default, bit7z is compatible with the `7z.so` from 7-Zip v23.01 and later.
-If you plan to use the `7z.so` from p7zip or 7-zip v22.01 and earlier instead, you have two ways to make bit7z compatible:
+If you plan to use the `7z.so` from p7zip or 7-Zip v22.01 and earlier instead, you have two ways to make bit7z compatible:
+ Configure bit7z with the CMake option `-DBIT7Z_USE_LEGACY_IUNKNOWN=ON`; _or_
-+ Configure bit7z for 7-zip v22.01 (i.e., `-DBIT7Z_7ZIP_VERSION="22.01"`).
++ Configure bit7z for 7-Zip v22.01 (i.e., `-DBIT7Z_7ZIP_VERSION="22.01"`).
Expand for more details
-_On Linux and macOS_, 7-zip v23.01 introduced breaking changes to the IUnknown interface.
-As a result, if you build bit7z for such a version of 7-zip (the default), it will not support using the shared libraries from previous versions of 7-zip (or from p7zip).
-Conversely, bit7z made for earlier versions of 7-zip or for p7zip is incompatible with the shared libraries from 7-zip v23.01 and later.
+_On Linux and macOS_, 7-Zip v23.01 introduced breaking changes to the IUnknown interface.
+As a result, if you build bit7z for such a version of 7-Zip (the default), it will not support using the shared libraries from previous versions of 7-Zip (or from p7zip).
+Conversely, bit7z made for earlier versions of 7-Zip or for p7zip is incompatible with the shared libraries from 7-Zip v23.01 and later.
-You can build the shared libraries of 7-zip v23.01 in a backward-compatible mode by defining the macro `Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN`.
-If this is your case, you'll need to enable the `BIT7Z_USE_LEGACY_IUNKNOWN` to make bit7z work (in this case, bit7z will be compatible also with previous versions of 7-zip/p7zip).
+You can build the shared libraries of 7-Zip v23.01 in a backward-compatible mode by defining the macro `Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN`.
+If this is your case, you'll need to enable the `BIT7Z_USE_LEGACY_IUNKNOWN` to make bit7z work (in this case, bit7z will be compatible also with previous versions of 7-Zip/p7zip).
@@ -409,7 +418,7 @@ However, if you need to handle non-ASCII/Unicode characters, as it is likely, yo
+ User-input strings (e.g., the password of an archive) can be handled as explained [here](https://nullprogram.com/blog/2020/05/04/); in short: read the input as an UTF-16 wide string (e.g., via `ReadConsoleW`), and convert it to UTF-8 (bit7z provides a utility function for this, `bit7z::to_tstring`).
+ You can correctly print the UTF-8 output strings from bit7z (e.g., the path/name metadata of a file in an archive) to the console by calling [`SetConsoleOutputCP(CP_UTF8)`](https://learn.microsoft.com/en-us/windows/console/setconsoleoutputcp) before.
+ Configuring bit7z to use UTF-16 encoded wide strings (i.e., `std::wstring`) by enabling the `BIT7Z_USE_NATIVE_STRING` option via CMake.
- + If your program is Windows-only, or you already use wide strings on Windows, this might be the best choice since it will avoid any internal string conversions (7-zip always uses wide strings).
+ + If your program is Windows-only, or you already use wide strings on Windows, this might be the best choice since it will avoid any internal string conversions (7-Zip always uses wide strings).
+ This option makes developing cross-platform applications slightly inconvenient since you'll still have to use `std::string` on POSIX systems.
+ The library provides a type alias `bit7z::tstring` and a macro function `BIT7Z_STRING` for defining wide string variables and literals on Windows and narrow ones on other platforms.
+ You must programmatically set the standard input and output encoding to UTF-16 to correctly read and print Unicode characters:
From 900d4810f59a12ac80e634fb14ce2efe98d13733 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 23 Nov 2024 11:46:11 +0100
Subject: [PATCH 21/31] Improve the README
---
README.md | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 95c44b04..0721f489 100644
--- a/README.md
+++ b/README.md
@@ -269,15 +269,13 @@ You can also clone/download this repository and build the library yourself (plea
> [!NOTE]
>
-> The library does not support RAR archives when using the p7zip `.so` libraries.
+> The library does not support RAR archives when using the p7zip `.so` libraries: to extract RAR archives on Unix systems, you need to use 7-Zip's `.so` libraries.
>
-> To extract RAR archives, you need to use 7-Zip's `.so` libraries.
> [!NOTE]
>
-> bit7z doesn't ship with the 7-Zip shared libraries.
+> The library doesn't ship with the 7-Zip shared libraries. You can build them from the source code available at [7-zip.org](http://www.7-zip.org/).
>
-> You can build them from the source code available at [7-zip.org](http://www.7-zip.org/).
[^1]: On Windows, you should link your program _also_ with _oleaut32_ (e.g., `-lbit7z -loleaut32`). On Linux and macOS, you should link your program _also_ with _dl_ (e.g., `-lbit7z -ldl`). If you are using the library via CMake, these dependencies will be linked automatically to your project.
[^2]: MSVC 2010 was supported until v2.x, MSVC 2012/2013 until v3.x.
From 52e9f336da185f52181764b21aab72fa5f06ca07 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 23 Nov 2024 11:50:22 +0100
Subject: [PATCH 22/31] Fix the README
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 0721f489..981a8013 100644
--- a/README.md
+++ b/README.md
@@ -274,7 +274,7 @@ You can also clone/download this repository and build the library yourself (plea
> [!NOTE]
>
-> The library doesn't ship with the 7-Zip shared libraries. You can build them from the source code available at [7-zip.org](http://www.7-zip.org/).
+> The library doesn't ship with the 7-Zip shared libraries, which can be built from the source code available at [7-zip.org](https://www.7-zip.org/).
>
[^1]: On Windows, you should link your program _also_ with _oleaut32_ (e.g., `-lbit7z -loleaut32`). On Linux and macOS, you should link your program _also_ with _dl_ (e.g., `-lbit7z -ldl`). If you are using the library via CMake, these dependencies will be linked automatically to your project.
From c12dff7cc4e00b5645fed614d21d5171d9159246 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 23 Nov 2024 21:49:26 +0100
Subject: [PATCH 23/31] Improve the README
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 981a8013..77238111 100644
--- a/README.md
+++ b/README.md
@@ -269,12 +269,12 @@ You can also clone/download this repository and build the library yourself (plea
> [!NOTE]
>
-> The library does not support RAR archives when using the p7zip `.so` libraries: to extract RAR archives on Unix systems, you need to use 7-Zip's `.so` libraries.
+> The library does not support RAR archives when using the p7zip `.so` libraries. To extract RAR archives on Unix systems, you must use 7-Zip's `.so` libraries.
>
> [!NOTE]
>
-> The library doesn't ship with the 7-Zip shared libraries, which can be built from the source code available at [7-zip.org](https://www.7-zip.org/).
+> Bit7z doesn't ship with the 7-Zip shared libraries: you can use the precompiled binaries or build them from the source code at [7-zip.org](https://www.7-zip.org/).
>
[^1]: On Windows, you should link your program _also_ with _oleaut32_ (e.g., `-lbit7z -loleaut32`). On Linux and macOS, you should link your program _also_ with _dl_ (e.g., `-lbit7z -ldl`). If you are using the library via CMake, these dependencies will be linked automatically to your project.
From b3fdbe2324e98a198cdf633bef038f9bbfa13699 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 1 Dec 2024 12:20:46 +0100
Subject: [PATCH 24/31] Fix error reporting in MSVC 2015
---
src/bit7zlibrary.cpp | 9 ++++++---
src/internal/cfileinstream.cpp | 4 ++--
src/internal/cfileoutstream.cpp | 4 ++--
src/internal/fsitem.cpp | 3 ++-
4 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/bit7zlibrary.cpp b/src/bit7zlibrary.cpp
index 0e14757c..0c6fcdf8 100644
--- a/src/bit7zlibrary.cpp
+++ b/src/bit7zlibrary.cpp
@@ -35,14 +35,16 @@ using namespace bit7z;
Bit7zLibrary::Bit7zLibrary( const tstring& libraryPath ) : mLibrary( Bit7zLoadLibrary( libraryPath ) ) {
if ( mLibrary == nullptr ) {
- throw BitException( "Failed to load the 7-zip library", ERROR_CODE( std::errc::bad_file_descriptor ) );
+ const auto error = ERROR_CODE( std::errc::bad_file_descriptor );
+ throw BitException( "Failed to load the 7-zip library", error );
}
mCreateObjectFunc = GetProcAddress( mLibrary, "CreateObject" );
if ( mCreateObjectFunc == nullptr ) {
FreeLibrary( mLibrary );
- throw BitException( "Failed to get CreateObject function", ERROR_CODE( std::errc::invalid_seek ) );
+ const auto error = ERROR_CODE( std::errc::invalid_seek );
+ throw BitException( "Failed to get CreateObject function", error );
}
}
@@ -56,7 +58,8 @@ void Bit7zLibrary::setLargePageMode() {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto pSetLargePageMode = reinterpret_cast< SetLargePageMode >( GetProcAddress( mLibrary, "SetLargePageMode" ) );
if ( pSetLargePageMode == nullptr ) {
- throw BitException( "Failed to get SetLargePageMode function", ERROR_CODE( std::errc::invalid_seek ) );
+ const auto error = ERROR_CODE( std::errc::invalid_seek );
+ throw BitException( "Failed to get SetLargePageMode function", error );
}
const HRESULT res = pSetLargePageMode();
if ( res != S_OK ) {
diff --git a/src/internal/cfileinstream.cpp b/src/internal/cfileinstream.cpp
index 431448e5..374e1d27 100644
--- a/src/internal/cfileinstream.cpp
+++ b/src/internal/cfileinstream.cpp
@@ -33,10 +33,10 @@ void CFileInStream::openFile( const fs::path& filePath ) {
if ( mFileStream.fail() ) {
#if defined( __MINGW32__ ) || defined( __MINGW64__ )
std::error_code error{ errno, std::generic_category() };
- throw BitException( "Failed to open the archive file", error, path_to_tstring( filePath ) );
#else
- throw BitException( "Failed to open the archive file", last_error_code(), path_to_tstring( filePath ) );
+ const auto error = last_error_code();
#endif
+ throw BitException( "Failed to open the archive file", error, path_to_tstring( filePath ) );
}
}
diff --git a/src/internal/cfileoutstream.cpp b/src/internal/cfileoutstream.cpp
index f9c3ff65..48d9340e 100644
--- a/src/internal/cfileoutstream.cpp
+++ b/src/internal/cfileoutstream.cpp
@@ -37,10 +37,10 @@ CFileOutStream::CFileOutStream( fs::path filePath, bool createAlways )
if ( mFileStream.fail() ) {
#if defined( __MINGW32__ ) || defined( __MINGW64__ )
error = std::error_code{ errno, std::generic_category() };
- throw BitException( "Failed to open the output file", error, path_to_tstring( mFilePath ) );
#else
- throw BitException( "Failed to open the output file", last_error_code(), path_to_tstring( mFilePath ) );
+ error = last_error_code();
#endif
+ throw BitException( "Failed to open the output file", error, path_to_tstring( mFilePath ) );
}
// Unbuffered streams are slow for Visual Studio 2015
#if !defined(_MSC_VER) || _MSC_VER != 1900
diff --git a/src/internal/fsitem.cpp b/src/internal/fsitem.cpp
index d7fa9cd7..094f8d7c 100644
--- a/src/internal/fsitem.cpp
+++ b/src/internal/fsitem.cpp
@@ -62,7 +62,8 @@ FilesystemItem::FilesystemItem( fs::directory_entry entry, const fs::path& searc
void FilesystemItem::initAttributes( const fs::path& itemPath ) {
if ( !fsutil::get_file_attributes_ex( itemPath.c_str(), mSymlinkPolicy, mFileAttributeData ) ) {
//should not happen, but anyway...
- throw BitException( "Could not retrieve file attributes", last_error_code(), path_to_tstring( itemPath ) );
+ const auto error = last_error_code();
+ throw BitException( "Could not retrieve file attributes", error, path_to_tstring( itemPath ) );
}
}
From dfb9516ecd690e432ee65e08ed26c1c400bf5450 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 14 Dec 2024 19:25:15 +0100
Subject: [PATCH 25/31] Fix and improve the README
---
README.md | 82 ++++++++++++++++++-------------------------------------
1 file changed, 26 insertions(+), 56 deletions(-)
diff --git a/README.md b/README.md
index 77238111..65b0c185 100644
--- a/README.md
+++ b/README.md
@@ -227,11 +227,11 @@ The newest bit7z v4 introduced some significant breaking changes to the library'
+ Now `BitExtractor` is just the name of a template class for all the extraction classes.
+ The old `BitCompressor` class is now called `BitFileCompressor`.
+ Now `BitCompressor` is just the name of a template class for all the compression classes.
++ The old `BitArchiveInfo` class is now called `BitArchiveReader`, and it allows to extract single archives.
+ The `ProgressCallback` now must return a `bool` value indicating whether the current operation can continue (`true`) or not (`false`).
+ The `BitException` class now inherits from `std::system_error` rather than `std::runtime_error`.
+ The method `BitException::getErrorCode()` was renamed `BitException::hresultCode()`.
-
+ The project structure changed:
+ Public API headers moved from `include/` to the `include/bit7z/` folder, so `#include` directives now need to prepend `bit7z/` to the included header name (e.g., `#include `).
+ Even though it is a bit verbose, it is a typical structure for C and C++ libraries, and it makes explicit which third-party library a header file belongs to.
@@ -261,30 +261,39 @@ You can also clone/download this repository and build the library yourself (plea
## 🧰 Requirements
-+ **Operating System:** Windows, Linux, macOS, Android[^1].
++ **Operating System:** Windows, Linux, macOS, Android.
+ **Architecture:** x86, x86_64, arm, arm64.
+ **Language Standard:** C++11 (for using the library), C++14 (for building the library).
-+ **Compiler:** MSVC 2015 or later[^2], MinGW v6.4 or later[^3], GCC v4.9 or later, Clang 3.6 or later.
++ **Compiler:** MSVC 2015 or later[^1], MinGW v6.4 or later, GCC v4.9 or later, Clang 3.6 or later.
+ **Shared Library:** a 7-Zip `.dll` library on Windows, a 7-Zip/p7zip `.so` library on Unix.
> [!NOTE]
>
-> The library does not support RAR archives when using the p7zip `.so` libraries. To extract RAR archives on Unix systems, you must use 7-Zip's `.so` libraries.
->
+> + **RAR Archive Support:** The library supports RAR archives *only* when using 7-Zip's `7z.dll`/`7z.so`. It doesn't support p7zip's unrar plugin. For RAR extraction on Unix-based systems, you need to build the 7-Zip `7z.so` library.
+> + **7-Zip Libraries:** Bit7z does **not** ship with the 7-Zip shared libraries. You can download the precompiled binaries or build them from the source at [7-zip.org](https://www.7-zip.org/).
-> [!NOTE]
->
-> Bit7z doesn't ship with the 7-Zip shared libraries: you can use the precompiled binaries or build them from the source code at [7-zip.org](https://www.7-zip.org/).
->
+[^1]: MSVC 2010 was supported until v2.x, MSVC 2012/2013 until v3.x.
-[^1]: On Windows, you should link your program _also_ with _oleaut32_ (e.g., `-lbit7z -loleaut32`). On Linux and macOS, you should link your program _also_ with _dl_ (e.g., `-lbit7z -ldl`). If you are using the library via CMake, these dependencies will be linked automatically to your project.
-[^2]: MSVC 2010 was supported until v2.x, MSVC 2012/2013 until v3.x.
+## 🔗 Installation
-[^3]: When using MinGW, you should link your program also with `libuuid` (e.g. `-lbit7z -loleaut32 -luuid`).
+The library can be installed as a dependency of your project in a number of different ways:
-## 🔗 Installation
+### Using CMake's `add_subdirectory`
+
+You can directly integrate the library into your CMake project:
-The library can be used as a dependency in a number of different ways:
++ Either download bit7z's sources to a sub-directory of your project (e.g., `third_party`), or add this repository as a git submodule of yours.
++ Then, use the command `add_subdirectory()` in your `CMakeLists.txt` to include bit7z.
++ Finally, link the `bit7z` library using the `target_link_libraries()` command.
+
+For example:
+
+```cmake
+add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/bit7z) # Path to bit7z's repository
+# Here you can enable/disable bit7z's build options, e.g.:
+# set(BIT7Z_USE_NATIVE_STRING ON CACHE BOOL "enable using native OS strings" FORCE)
+target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
+```
### Using [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake)
@@ -310,52 +319,13 @@ find_package(unofficial-bit7z CONFIG REQUIRED)
target_link_libraries(${YOUR_TARGET} PRIVATE unofficial::bit7z::bit7z64)
```
-### Using CMake
+### Building from source and manually linking
-You can also directly integrate the library into your CMake project:
-
-+ Either download bit7z's sources to a sub-directory of your project (e.g., `third_party`), or add this repository as a git submodule of yours.
-+ Then, use the command `add_subdirectory()` in your `CMakeLists.txt` to include bit7z.
-+ Finally, link the `bit7z` library using the `target_link_libraries()` command.
-
-For example:
-
-```cmake
-add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/bit7z)
-# Here you can enable/disable bit7z's build options, e.g.:
-# set(BIT7Z_USE_NATIVE_STRING ON CACHE BOOL "enable using native OS strings" FORCE)
-target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
-```
-
-### Building from sources and manually linking
-
-For manually building the library:
-
-```bash
-cd
-mkdir build && cd build
-cmake ../ -DCMAKE_BUILD_TYPE=Release
-cmake --build . -j --config Release
-```
-
-A `.lib`/`.a` library file will be produced in the `/lib//` folder.
-
-A more detailed guide on how to build this library is available [here](https://github.com/rikyoz/bit7z/wiki/Building-the-library).
-
-Once built, you can copy the library file and bit7z's `include` folder in the desired subfolders of your project, and then manually link the library and its runtime dependencies to your application, e.g., in your CMake project:
-
-```cmake
-target_include_directories(${YOUR_TARGET} PRIVATE "")
-find_library(BIT7Z_LIB bit7z HINTS "")
-target_link_libraries(${YOUR_TARGET} PRIVATE ${BIT7Z_LIB}
- $<$:oleaut32>
- $<$:uuid>
- $<$:dl>)
-```
+The wiki provides instructions on how to [build](https://github.com/rikyoz/bit7z/wiki/Building-the-library) the library from the source code and how to [manually link](https://github.com/rikyoz/bit7z/wiki/Installing-the-library#manually-linking) it into your project.
## ⚙️ Configuration
-The library is highly customizable: for a detailed list of the available build options, please refer to the [wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library#%EF%B8%8F-build-options).
+The library is highly customizable: for a detailed list of the available build options, please refer to the [wiki](https://github.com/rikyoz/bit7z/wiki/Build-options).
### 📌 7-Zip Version
From 636df1b8f0ad8ba14c030339238b97c9b959d2f7 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 14 Dec 2024 19:25:45 +0100
Subject: [PATCH 26/31] Fix and update appveyor.yml
---
appveyor.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/appveyor.yml b/appveyor.yml
index 6df6cfcb..29311b7a 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -128,8 +128,8 @@ for:
- cd ..
- mkdir -p pkg/bit7z/
- mkdir -p pkg/bit7z/include/
- - cp -r lib pkg/bit7z
- - cp -r include pkg/bit7z/include/
+ - cp -r lib pkg/bit7z/
+ - cp -r include pkg/bit7z/
- cp README.md pkg/bit7z/
- cp LICENSE pkg/bit7z/
- echo $bit7z_version $compiler_tag > "pkg/bit7z/BUILD.txt"
@@ -198,7 +198,7 @@ deploy:
tag: $(APPVEYOR_REPO_TAG_NAME)
description: 'Binaries of Bit7z %bit7z_version%'
auth_token:
- secure: 5b0wRmYrS2S5MEu+5rslOkBY//wJ+ShwhxNeOhxaAaMjTYRbSDqe4cme0CukKSgp
+ secure: aaQkoEIZv7oaBSZT2f/bST7NfLOdqKXitnhWmUqaW1T493Pr2/atcZWHIlExsLAx
artifact: /.*\.7z/
draft: true
prerelease: false
From b42324e208442f1e0867776ff1828adf31e30fb2 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 14 Dec 2024 19:26:09 +0100
Subject: [PATCH 27/31] Fix code formatting in test_fsutil.cpp
---
tests/src/test_fsutil.cpp | 50 +++++++++++++++++++--------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/tests/src/test_fsutil.cpp b/tests/src/test_fsutil.cpp
index 8a4d81ba..b2ab6378 100644
--- a/tests/src/test_fsutil.cpp
+++ b/tests/src/test_fsutil.cpp
@@ -196,33 +196,33 @@ TEST_CASE( "fsutil: In-archive path computation", "[fsutil][in_archive_path]" )
// Note: since we are using the function fs::absolute(...), the content of this vector depends on the current
// directory, hence we must declare the vector inside the test case and not outside!
const std::array< TestItem, 28 > testItems{ {
- { ".", "" },
- { "./", "" },
- { "..", "" },
- { "../", "" },
- { "italy.svg", "italy.svg" },
- { "folder", "folder" },
- { "folder/", "folder/" },
- { "folder/clouds.jpg", "folder/clouds.jpg" },
- { "folder/subfolder2", "folder/subfolder2" },
- { "folder/subfolder2/", "folder/subfolder2/" },
+ { ".", "" },
+ { "./", "" },
+ { "..", "" },
+ { "../", "" },
+ { "italy.svg", "italy.svg" },
+ { "folder", "folder" },
+ { "folder/", "folder/" },
+ { "folder/clouds.jpg", "folder/clouds.jpg" },
+ { "folder/subfolder2", "folder/subfolder2" },
+ { "folder/subfolder2/", "folder/subfolder2/" },
{ "folder/subfolder2/homework.doc", "folder/subfolder2/homework.doc" },
- { "./italy.svg", "italy.svg" },
- { "./folder", "folder" },
- { "./folder/", "folder" },
- { "./folder/clouds.jpg", "clouds.jpg" },
- { "./folder/subfolder2", "subfolder2" },
+ { "./italy.svg", "italy.svg" },
+ { "./folder", "folder" },
+ { "./folder/", "folder" },
+ { "./folder/clouds.jpg", "clouds.jpg" },
+ { "./folder/subfolder2", "subfolder2" },
{ "./folder/subfolder2/homework.doc", "homework.doc" },
- { "./../test_filesystem/", "test_filesystem" },
- { "./../test_filesystem/folder/", "folder" },
- { fs::absolute( "." ), "test_filesystem" },
- { fs::absolute( "../" ), "data" },
- { fs::absolute( "./italy.svg" ), "italy.svg" },
- { fs::absolute( "./folder" ), "folder" },
- { fs::absolute( "./folder/" ), "folder" },
- { fs::absolute( "./folder/clouds.jpg" ), "clouds.jpg" },
- { fs::absolute( "./folder/subfolder2" ), "subfolder2" },
- { fs::absolute( "./folder/subfolder2/" ), "subfolder2" },
+ { "./../test_filesystem/", "test_filesystem" },
+ { "./../test_filesystem/folder/", "folder" },
+ { fs::absolute( "." ), "test_filesystem" },
+ { fs::absolute( "../" ), "data" },
+ { fs::absolute( "./italy.svg" ), "italy.svg" },
+ { fs::absolute( "./folder" ), "folder" },
+ { fs::absolute( "./folder/" ), "folder" },
+ { fs::absolute( "./folder/clouds.jpg" ), "clouds.jpg" },
+ { fs::absolute( "./folder/subfolder2" ), "subfolder2" },
+ { fs::absolute( "./folder/subfolder2/" ), "subfolder2" },
{ fs::absolute( "./folder/subfolder2/homework.doc" ), "homework.doc" }
} };
From 38f3b6d7be62c53ba777712046fbcbcfe6d52a55 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 14 Dec 2024 19:26:25 +0100
Subject: [PATCH 28/31] [Test] Fix fsutil tests
---
tests/src/test_fsutil.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/src/test_fsutil.cpp b/tests/src/test_fsutil.cpp
index b2ab6378..68bbad71 100644
--- a/tests/src/test_fsutil.cpp
+++ b/tests/src/test_fsutil.cpp
@@ -237,7 +237,7 @@ TEST_CASE( "fsutil: In-archive path computation", "[fsutil][in_archive_path]" )
#endif
-#if defined( _WIN32 ) && defined( BIT7Z_AUTO_PREFIX_LONG_PATHS )
+#if defined( _WIN32 ) && defined( BIT7Z_AUTO_PREFIX_LONG_PATHS ) && !defined( BIT7Z_DISABLE_USE_STD_FILESYSTEM )
TEST_CASE( "fsutil: Format long Windows paths", "[fsutil][format_long_path]" ) {
const std::wstring kLongPathPrefix = BIT7Z_NATIVE_STRING( R"(\\?\)" );
From c6f12226e346672d95e812ca54b29c94b213bdf3 Mon Sep 17 00:00:00 2001
From: Oz
Date: Sat, 14 Dec 2024 19:32:32 +0100
Subject: [PATCH 29/31] Improve the README
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 65b0c185..c86dccf3 100644
--- a/README.md
+++ b/README.md
@@ -312,7 +312,7 @@ First, you need to install the library:
vcpkg install bit7z
```
-Then, you add bit7z as a dependency in your project's CMakeLists.txt:
+Then, you add bit7z as a dependency in your project's `CMakeLists.txt`:
```cmake
find_package(unofficial-bit7z CONFIG REQUIRED)
@@ -321,7 +321,7 @@ target_link_libraries(${YOUR_TARGET} PRIVATE unofficial::bit7z::bit7z64)
### Building from source and manually linking
-The wiki provides instructions on how to [build](https://github.com/rikyoz/bit7z/wiki/Building-the-library) the library from the source code and how to [manually link](https://github.com/rikyoz/bit7z/wiki/Installing-the-library#manually-linking) it into your project.
+The wiki provides instructions on how to [build](https://github.com/rikyoz/bit7z/wiki/Building-the-library) the library from the source code and [manually link](https://github.com/rikyoz/bit7z/wiki/Installing-the-library#manually-linking) it into your project.
## ⚙️ Configuration
From d2843a70b1a7252aff9ff4dc135854046eb93a6d Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 15 Dec 2024 11:56:37 +0100
Subject: [PATCH 30/31] Change the icon of the configuration section in the
README
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index c86dccf3..7011f405 100644
--- a/README.md
+++ b/README.md
@@ -323,7 +323,7 @@ target_link_libraries(${YOUR_TARGET} PRIVATE unofficial::bit7z::bit7z64)
The wiki provides instructions on how to [build](https://github.com/rikyoz/bit7z/wiki/Building-the-library) the library from the source code and [manually link](https://github.com/rikyoz/bit7z/wiki/Installing-the-library#manually-linking) it into your project.
-## ⚙️ Configuration
+## 🛠️ Configuration
The library is highly customizable: for a detailed list of the available build options, please refer to the [wiki](https://github.com/rikyoz/bit7z/wiki/Build-options).
From 1de83a69639e3128e687eba0675d8260681f757d Mon Sep 17 00:00:00 2001
From: Oz
Date: Sun, 15 Dec 2024 12:04:01 +0100
Subject: [PATCH 31/31] Fix navbar in README
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 7011f405..316aa49d 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
Download •
Requirements •
Installation •
- Configuration •
+ Configuration •
Donate •
License