Add bit7z library for loading zip files along with 7zip dll to be copied to build directory.

This commit is contained in:
Soggy_Pancake 2026-03-14 13:05:19 -07:00
parent 8dee53a565
commit 976dcc07ef
36 changed files with 4872 additions and 6 deletions

View file

@ -0,0 +1,25 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BIT7Z_HPP
#define BIT7Z_HPP
#include "bitarchiveeditor.hpp"
#include "bitarchivereader.hpp"
#include "bitarchivewriter.hpp"
#include "bitexception.hpp"
#include "bitfilecompressor.hpp"
#include "bitfileextractor.hpp"
#include "bitmemcompressor.hpp"
#include "bitmemextractor.hpp"
#include "bitstreamcompressor.hpp"
#include "bitstreamextractor.hpp"
#endif // BIT7Z_HPP

View file

@ -0,0 +1,101 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BIT7ZLIBRARY_HPP
#define BIT7ZLIBRARY_HPP
#include <string>
#include "bitformat.hpp"
#include "bittypes.hpp"
#include "bitwindows.hpp"
//! @cond IGNORE_BLOCK_IN_DOXYGEN
struct IInArchive;
struct IOutArchive;
template< typename T >
class CMyComPtr;
//! @endcond
/**
* @brief The main namespace of the bit7z library.
*/
namespace bit7z {
/**
* @brief The default file path for the 7-zip shared library to be used by bit7z
* in case the user doesn't pass a path to the constructor of the Bit7zLibrary class.
*
* @note On Windows, the default library is 7z.dll, and it is searched following the Win32 API rules
* (https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order).
*
* @note On Linux, the default library is the absolute path to the "7z.so" installed by p7zip.
*
* @note In all other cases, the value will be the relative path to a "7z.so" in the working directory of the program.
*/
#ifdef __DOXYGEN__
constexpr auto kDefaultLibrary = "<platform-dependent value>";
#elif defined( _WIN32 )
constexpr auto kDefaultLibrary = BIT7Z_STRING( "7z.dll" );
#elif defined( __linux__ )
constexpr auto kDefaultLibrary = "/usr/lib/p7zip/7z.so"; // Default installation path of the p7zip shared library.
#else
constexpr auto kDefaultLibrary = "./7z.so";
#endif
/**
* @brief The Bit7zLibrary class allows accessing the basic functionalities provided by the 7z DLLs.
*/
class Bit7zLibrary final {
public:
Bit7zLibrary( const Bit7zLibrary& ) = delete;
Bit7zLibrary( Bit7zLibrary&& ) = delete;
auto operator=( const Bit7zLibrary& ) -> Bit7zLibrary& = delete;
auto operator=( Bit7zLibrary&& ) -> Bit7zLibrary& = delete;
/**
* @brief Constructs a Bit7zLibrary object by loading the specified 7zip shared library.
*
* By default, it searches a 7z.dll in the same path of the application.
*
* @param libraryPath the path to the shared library file to be loaded.
*/
explicit Bit7zLibrary( const tstring& libraryPath = kDefaultLibrary );
/**
* @brief Destructs the Bit7zLibrary object, freeing the loaded shared library.
*/
~Bit7zLibrary();
/**
* @brief Set the 7-zip shared library to use large memory pages.
*/
void setLargePageMode();
private:
HMODULE mLibrary;
FARPROC mCreateObjectFunc;
BIT7Z_NODISCARD
auto initInArchive( const BitInFormat& format ) const -> CMyComPtr< IInArchive >;
BIT7Z_NODISCARD
auto initOutArchive( const BitInOutFormat& format ) const -> CMyComPtr< IOutArchive >;
friend class BitInputArchive;
friend class BitOutputArchive;
};
} // namespace bit7z
#endif // BIT7ZLIBRARY_HPP

View file

@ -0,0 +1,305 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITABSTRACTARCHIVECREATOR_HPP
#define BITABSTRACTARCHIVECREATOR_HPP
#include <map>
#include <memory>
#include "bitabstractarchivehandler.hpp"
#include "bitcompressionlevel.hpp"
#include "bitcompressionmethod.hpp"
#include "bitformat.hpp"
#include "bitinputarchive.hpp"
struct IOutStream;
struct ISequentialOutStream;
namespace bit7z {
using std::ostream;
class ArchiveProperties;
/**
* @brief Enumeration representing how an archive creator should deal when the output archive already exists.
*/
enum struct UpdateMode {
None, ///< The creator will throw an exception (unless the OverwriteMode is not None).
Append, ///< The creator will append the new items to the existing archive.
Update, ///< New items whose path already exists in the archive will overwrite the old ones, other will be appended.
BIT7Z_DEPRECATED_ENUMERATOR( Overwrite, Update, "Since v4.0; please use the UpdateMode::Update enumerator." ) ///< @deprecated since v4.0; please use the UpdateMode::Update enumerator.
};
/**
* @brief Abstract class representing a generic archive creator.
*/
class BitAbstractArchiveCreator : public BitAbstractArchiveHandler {
public:
BitAbstractArchiveCreator( const BitAbstractArchiveCreator& ) = delete;
BitAbstractArchiveCreator( BitAbstractArchiveCreator&& ) = delete;
auto operator=( const BitAbstractArchiveCreator& ) -> BitAbstractArchiveCreator& = delete;
auto operator=( BitAbstractArchiveCreator&& ) -> BitAbstractArchiveCreator& = delete;
~BitAbstractArchiveCreator() override = default;
/**
* @return the format used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto format() const noexcept -> const BitInFormat& override;
/**
* @return the format used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto compressionFormat() const noexcept -> const BitInOutFormat&;
/**
* @return whether the creator crypts also the headers of archives or not.
*/
BIT7Z_NODISCARD auto cryptHeaders() const noexcept -> bool;
/**
* @return the compression level used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto compressionLevel() const noexcept -> BitCompressionLevel;
/**
* @return the compression method used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto compressionMethod() const noexcept -> BitCompressionMethod;
/**
* @return the dictionary size used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto dictionarySize() const noexcept -> uint32_t;
/**
* @return the word size used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto wordSize() const noexcept -> uint32_t;
/**
* @return whether the archive creator uses solid compression or not.
*/
BIT7Z_NODISCARD auto solidMode() const noexcept -> bool;
/**
* @return the update mode used when updating existing archives.
*/
BIT7Z_NODISCARD auto updateMode() const noexcept -> UpdateMode;
/**
* @return the volume size (in bytes) used when creating multi-volume archives
* (a 0 value means that all files are going in a single archive).
*/
BIT7Z_NODISCARD auto volumeSize() const noexcept -> uint64_t;
/**
* @return the number of threads used when creating/updating an archive
* (a 0 value means that it will use the 7-zip default value).
*/
BIT7Z_NODISCARD auto threadsCount() const noexcept -> uint32_t;
/**
* @return whether the archive creator stores symbolic links as links in the output archive.
*/
BIT7Z_NODISCARD auto storeSymbolicLinks() const noexcept -> bool;
/**
* @brief Sets up a password for the output archives.
*
* When setting a password, the produced archives will be encrypted using the default
* cryptographic method of the output format. The option "crypt headers" remains unchanged,
* in contrast with what happens when calling the setPassword(tstring, bool) method.
*
* @note Calling setPassword when the output format doesn't support archive encryption
* (e.g., GZip, BZip2, etc...) does not have any effects (in other words, it doesn't
* throw exceptions, and it has no effects on compression operations).
*
* @note After a password has been set, it will be used for every subsequent operation.
* To disable the use of the password, you need to call the clearPassword method
* (inherited from BitAbstractArchiveHandler), which is equivalent to setPassword(L"").
*
* @param password the password to be used when creating/updating archives.
*/
void setPassword( const tstring& password ) override;
/**
* @brief Sets up a password for the output archive.
*
* When setting a password, the produced archive will be encrypted using the default
* cryptographic method of the output format. If the format is 7z, and the option
* "cryptHeaders" is set to true, the headers of the archive will be encrypted,
* resulting in a password request every time the output file will be opened.
*
* @note Calling setPassword when the output format doesn't support archive encryption
* (e.g., GZip, BZip2, etc...) does not have any effects (in other words, it doesn't
* throw exceptions, and it has no effects on compression operations).
*
* @note Calling setPassword with "cryptHeaders" set to true does not have effects on
* formats different from 7z.
*
* @note After a password has been set, it will be used for every subsequent operation.
* To disable the use of the password, you need to call the clearPassword method
* (inherited from BitAbstractArchiveHandler), which is equivalent to setPassword(L"").
*
* @param password the password to be used when creating/updating archives.
* @param cryptHeaders if true, the headers of the output archives will be encrypted
* (valid only when using the 7z format).
*/
void setPassword( const tstring& password, bool cryptHeaders );
/**
* @brief Sets the compression level to be used when creating/updating an archive.
*
* @param level the compression level desired.
*/
void setCompressionLevel( BitCompressionLevel level ) noexcept;
/**
* @brief Sets the compression method to be used when creating/updating an archive.
*
* @param method the compression method desired.
*/
void setCompressionMethod( BitCompressionMethod method );
/**
* @brief Sets the dictionary size to be used when creating/updating an archive.
*
* @param dictionarySize the dictionary size desired.
*/
void setDictionarySize( uint32_t dictionarySize );
/**
* @brief Sets the word size to be used when creating/updating an archive.
*
* @param wordSize the word size desired.
*/
void setWordSize( uint32_t wordSize );
/**
* @brief Sets whether to use solid compression or not.
*
* @note Setting the solid compression mode to true has effect only when using the 7z format with multiple
* input files.
*
* @param solidMode if true, it will be used the "solid compression" method.
*/
void setSolidMode( bool solidMode ) noexcept;
/**
* @brief Sets whether and how the creator can update existing archives or not.
*
* @note If set to UpdateMode::None, a subsequent compression operation may throw an exception
* if it targets an existing archive.
*
* @param mode the desired update mode.
*/
virtual void setUpdateMode( UpdateMode mode );
/**
* @brief Sets whether the creator can update existing archives or not.
*
* @deprecated since v4.0; it is provided just for an easier transition from the old v3 API.
*
* @note If set to false, a subsequent compression operation may throw an exception
* if it targets an existing archive.
*
* @param canUpdate if true, compressing operations will update existing archives.
*/
BIT7Z_DEPRECATED_MSG( "Since v4.0; please use the overloaded function that takes an UpdateMode enumerator." )
void setUpdateMode( bool canUpdate );
/**
* @brief Sets the volumeSize (in bytes) of the output archive volumes.
*
* @note This setting has effects only when the destination archive is on the filesystem.
*
* @param volumeSize The dimension of a volume.
*/
void setVolumeSize( uint64_t volumeSize ) noexcept;
/**
* @brief Sets the number of threads to be used when creating/updating an archive.
*
* @param threadsCount the number of threads desired.
*/
void setThreadsCount( uint32_t threadsCount ) noexcept;
/**
* @brief Sets whether the creator will store symbolic links as links in the output archive.
*
* @param storeSymlinks if true, symbolic links will be stored as links.
*/
void setStoreSymbolicLinks( bool storeSymlinks ) noexcept;
/**
* @brief Sets a property for the output archive format as described by the 7-zip documentation
* (e.g., https://sevenzip.osdn.jp/chm/cmdline/switches/method.htm).
*
* @tparam T An integral type (i.e., a bool or an integer type).
*
* @param name The string name of the property to be set.
* @param value The value to be used for the property.
*/
template< std::size_t N, typename T, typename = typename std::enable_if< std::is_integral< T >::value >::type >
void setFormatProperty( const wchar_t (&name)[N], T value ) noexcept { // NOLINT(*-avoid-c-arrays)
mExtraProperties[ name ] = value;
}
/**
* @brief Sets a property for the output archive format as described by the 7-zip documentation
* (e.g., https://sevenzip.osdn.jp/chm/cmdline/switches/method.htm).
*
* For example, passing the string L"tm" with a false value while creating a .7z archive
* will disable storing the last modified timestamps of the compressed files.
*
* @tparam T A non-integral type (i.e., a string).
*
* @param name The string name of the property to be set.
* @param value The value to be used for the property.
*/
template< std::size_t N, typename T, typename = typename std::enable_if< !std::is_integral< T >::value >::type >
void setFormatProperty( const wchar_t (&name)[N], const T& value ) noexcept { // NOLINT(*-avoid-c-arrays)
mExtraProperties[ name ] = value;
}
protected:
BitAbstractArchiveCreator( const Bit7zLibrary& lib,
const BitInOutFormat& format,
tstring password = {},
UpdateMode updateMode = UpdateMode::None );
BIT7Z_NODISCARD auto archiveProperties() const -> ArchiveProperties;
friend class BitOutputArchive;
private:
const BitInOutFormat& mFormat;
UpdateMode mUpdateMode;
BitCompressionLevel mCompressionLevel;
BitCompressionMethod mCompressionMethod;
uint32_t mDictionarySize;
uint32_t mWordSize;
bool mCryptHeaders;
bool mSolidMode;
uint64_t mVolumeSize;
uint32_t mThreadsCount;
bool mStoreSymbolicLinks;
std::map< std::wstring, BitPropVariant > mExtraProperties;
};
} // namespace bit7z
#endif // BITABSTRACTARCHIVECREATOR_HPP

View file

@ -0,0 +1,249 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITABSTRACTARCHIVEHANDLER_HPP
#define BITABSTRACTARCHIVEHANDLER_HPP
#include <cstdint>
#include <functional>
#include "bit7zlibrary.hpp"
#include "bitdefines.hpp"
namespace bit7z {
class BitInFormat;
/**
* @brief A std::function whose argument is the total size of the ongoing operation.
*/
using TotalCallback = std::function< void( uint64_t ) >;
/**
* @brief A std::function whose argument is the currently processed size of the ongoing operation and returns
* true or false whether the operation must continue or not.
*/
using ProgressCallback = std::function< bool( uint64_t ) >;
/**
* @brief A std::function whose arguments are the current processed input size, and the current output size of the
* ongoing operation.
*/
using RatioCallback = std::function< void( uint64_t, uint64_t ) >;
/**
* @brief A std::function whose argument is the path, in the archive, of the file currently being processed
* by the ongoing operation.
*/
using FileCallback = std::function< void( tstring ) >;
/**
* @brief A std::function returning the password to be used to handle an archive.
*/
using PasswordCallback = std::function< tstring() >;
/**
* @brief Enumeration representing how a handler should deal when an output file already exists.
*/
enum struct OverwriteMode {
None = 0, ///< The handler will throw an exception if the output file or buffer already exists.
Overwrite, ///< The handler will overwrite the old file or buffer with the new one.
Skip, ///< The handler will skip writing to the output file or buffer.
//TODO: RenameOutput,
//TODO: RenameExisting
};
/**
* @brief Enumeration representing the policy according to which the archive handler should treat
* the items that match the pattern given by the user.
*/
enum struct FilterPolicy {
Include, ///< Extract/compress the items that match the pattern.
Exclude ///< Do not extract/compress the items that match the pattern.
};
/**
* @brief Abstract class representing a generic archive handler.
*/
class BitAbstractArchiveHandler {
public:
BitAbstractArchiveHandler( const BitAbstractArchiveHandler& ) = delete;
BitAbstractArchiveHandler( BitAbstractArchiveHandler&& ) = delete;
auto operator=( const BitAbstractArchiveHandler& ) -> BitAbstractArchiveHandler& = delete;
auto operator=( BitAbstractArchiveHandler&& ) -> BitAbstractArchiveHandler& = delete;
virtual ~BitAbstractArchiveHandler() = default;
/**
* @return the Bit7zLibrary object used by the handler.
*/
BIT7Z_NODISCARD auto library() const noexcept -> const Bit7zLibrary&;
/**
* @return the format used by the handler for extracting or compressing.
*/
BIT7Z_NODISCARD virtual auto format() const -> const BitInFormat& = 0;
/**
* @return the password used to open, extract, or encrypt the archive.
*/
BIT7Z_NODISCARD auto password() const -> tstring;
/**
* @return a boolean value indicating whether the directory structure must be preserved while extracting
* or compressing the archive.
*/
BIT7Z_NODISCARD auto retainDirectories() const noexcept -> bool;
/**
* @return a boolean value indicating whether a password is defined or not.
*/
BIT7Z_NODISCARD auto isPasswordDefined() const noexcept -> bool;
/**
* @return the current total callback.
*/
BIT7Z_NODISCARD auto totalCallback() const -> TotalCallback;
/**
* @return the current progress callback.
*/
BIT7Z_NODISCARD auto progressCallback() const -> ProgressCallback;
/**
* @return the current ratio callback.
*/
BIT7Z_NODISCARD auto ratioCallback() const -> RatioCallback;
/**
* @return the current file callback.
*/
BIT7Z_NODISCARD auto fileCallback() const -> FileCallback;
/**
* @return the current password callback.
*/
BIT7Z_NODISCARD auto passwordCallback() const -> PasswordCallback;
/**
* @return the current OverwriteMode.
*/
BIT7Z_NODISCARD auto overwriteMode() const -> OverwriteMode;
/**
* @brief Sets up a password to be used by the archive handler.
*
* The password will be used to encrypt/decrypt archives by using the default
* cryptographic method of the archive format.
*
* @note Calling setPassword when the input archive is not encrypted does not have any effect on
* the extraction process.
*
* @note Calling setPassword when the output format doesn't support archive encryption
* (e.g., GZip, BZip2, etc...) does not have any effects (in other words, it doesn't
* throw exceptions, and it has no effects on compression operations).
*
* @note After a password has been set, it will be used for every subsequent operation.
* To disable the use of the password, you need to call the clearPassword method, which is equivalent
* to calling setPassword(L"").
*
* @param password the password to be used.
*/
virtual void setPassword( const tstring& password );
/**
* @brief Clear the current password used by the handler.
*
* Calling clearPassword() will disable the encryption/decryption of archives.
*
* @note This is equivalent to calling setPassword(L"").
*/
void clearPassword() noexcept;
/**
* @brief Sets whether the operations' output will preserve the input's directory structure or not.
*
* @param retain the setting for preserving or not the input directory structure
*/
void setRetainDirectories( bool retain ) noexcept;
/**
* @brief Sets the function to be called when the total size of an operation is available.
*
* @param callback the total callback to be used.
*/
void setTotalCallback( const TotalCallback& callback );
/**
* @brief Sets the function to be called when the processed size of the ongoing operation is updated.
*
* @note The completion percentage of the current operation can be obtained by calculating
* `static_cast<int>((100.0 * processed_size) / total_size)`.
*
* @param callback the progress callback to be used.
*/
void setProgressCallback( const ProgressCallback& callback );
/**
* @brief Sets the function to be called when the input processed size and current output size of the
* ongoing operation are known.
*
* @note The ratio percentage of a compression operation can be obtained by calculating
* `static_cast<int>((100.0 * output_size) / input_size)`.
*
* @param callback the ratio callback to be used.
*/
void setRatioCallback( const RatioCallback& callback );
/**
* @brief Sets the function to be called when the current file being processed changes.
*
* @param callback the file callback to be used.
*/
void setFileCallback( const FileCallback& callback );
/**
* @brief Sets the function to be called when a password is needed to complete the ongoing operation.
*
* @param callback the password callback to be used.
*/
void setPasswordCallback( const PasswordCallback& callback );
/**
* @brief Sets how the handler should behave when it tries to output to an existing file or buffer.
*
* @param mode the OverwriteMode to be used by the handler.
*/
void setOverwriteMode( OverwriteMode mode );
protected:
explicit BitAbstractArchiveHandler( const Bit7zLibrary& lib,
tstring password = {},
OverwriteMode overwriteMode = OverwriteMode::None );
private:
const Bit7zLibrary& mLibrary;
tstring mPassword;
bool mRetainDirectories;
OverwriteMode mOverwriteMode;
//CALLBACKS
TotalCallback mTotalCallback;
ProgressCallback mProgressCallback;
RatioCallback mRatioCallback;
FileCallback mFileCallback;
PasswordCallback mPasswordCallback;
};
} // namespace bit7z
#endif // BITABSTRACTARCHIVEHANDLER_HPP

View file

@ -0,0 +1,59 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITABSTRACTARCHIVEOPENER_HPP
#define BITABSTRACTARCHIVEOPENER_HPP
#include <vector>
#include <map>
#include "bitabstractarchivehandler.hpp"
#include "bitformat.hpp"
namespace bit7z {
using std::ostream;
/**
* @brief The BitAbstractArchiveOpener abstract class represents a generic archive opener.
*/
class BitAbstractArchiveOpener : public BitAbstractArchiveHandler {
public:
BitAbstractArchiveOpener( const BitAbstractArchiveOpener& ) = delete;
BitAbstractArchiveOpener( BitAbstractArchiveOpener&& ) = delete;
auto operator=( const BitAbstractArchiveOpener& ) -> BitAbstractArchiveOpener& = delete;
auto operator=( BitAbstractArchiveOpener&& ) -> BitAbstractArchiveOpener& = delete;
~BitAbstractArchiveOpener() override = default;
/**
* @return the archive format used by the archive opener.
*/
BIT7Z_NODISCARD auto format() const noexcept -> const BitInFormat& override;
/**
* @return the archive format used by the archive opener.
*/
BIT7Z_NODISCARD auto extractionFormat() const noexcept -> const BitInFormat&;
protected:
BitAbstractArchiveOpener( const Bit7zLibrary& lib,
const BitInFormat& format,
const tstring& password = {} );
private:
const BitInFormat& mFormat;
};
} // namespace bit7z
#endif // BITABSTRACTARCHIVEOPENER_HPP

View file

@ -0,0 +1,200 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEEDITOR_HPP
#define BITARCHIVEEDITOR_HPP
#include <unordered_map>
#include "bitarchivewriter.hpp"
namespace bit7z {
using std::vector;
using EditedItems = std::unordered_map< uint32_t, BitItemsVector::value_type >;
enum struct DeletePolicy : std::uint8_t {
ItemOnly,
RecurseDirs
};
/**
* @brief The BitArchiveEditor class allows creating new file archives or updating old ones.
* Update operations supported are the addition of new items,
* as well as renaming/updating/deleting old items;
*
* @note Changes are applied to the archive only after calling the applyChanges() method.
*/
class BIT7Z_MAYBE_UNUSED BitArchiveEditor final : public BitArchiveWriter {
public:
/**
* @brief Constructs a BitArchiveEditor object, reading the given archive file path.
*
* @param lib the 7z library to use.
* @param inFile 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.
*/
BitArchiveEditor( const Bit7zLibrary& lib,
const tstring& inFile,
const BitInOutFormat& format,
const tstring& password = {} );
BitArchiveEditor( const BitArchiveEditor& ) = delete;
BitArchiveEditor( BitArchiveEditor&& ) = delete;
auto operator=( const BitArchiveEditor& ) -> BitArchiveEditor& = delete;
auto operator=( BitArchiveEditor&& ) -> BitArchiveEditor& = delete;
~BitArchiveEditor() override;
/**
* @brief Sets how the editor performs the update of the items in the archive.
*
* @note BitArchiveEditor doesn't support UpdateMode::None.
*
* @param mode the desired update mode (either UpdateMode::Append or UpdateMode::Overwrite).
*/
void setUpdateMode( UpdateMode mode ) override;
/**
* @brief Requests to change the path of the item at the specified index with the given one.
*
* @param index the index of the item to be renamed.
* @param newPath the new path (in the archive) desired for the item.
*/
void renameItem( uint32_t index, const tstring& newPath );
/**
* @brief Requests to change the path of the item from oldPath to the newPath.
*
* @param oldPath the old path (in the archive) of the item to be renamed.
* @param newPath the new path (in the archive) desired for the item.
*/
void renameItem( const tstring& oldPath, const tstring& newPath );
/**
* @brief Requests to update the content of the item at the specified index
* with the data from the given file.
*
* @param index the index of the item to be updated.
* @param inFile the path to the file containing the new data for the item.
*/
void updateItem( uint32_t index, const tstring& inFile );
/**
* @brief Requests to update the content of the item at the specified index
* with the data from the given buffer.
*
* @param index the index of the item to be updated.
* @param inBuffer the buffer containing the new data for the item.
*/
void updateItem( uint32_t index, const std::vector< byte_t >& inBuffer );
/**
* @brief Requests to update the content of the item at the specified index
* with the data from the given stream.
*
* @param index the index of the item to be updated.
* @param inStream the stream of new data for the item.
*/
void updateItem( uint32_t index, std::istream& inStream );
/**
* @brief Requests to update the content of the item at the specified path
* with the data from the given file.
*
* @param itemPath the path (in the archive) of the item to be updated.
* @param inFile the path to the file containing the new data for the item.
*/
void updateItem( const tstring& itemPath, const tstring& inFile );
/**
* @brief Requests to update the content of the item at the specified path
* with the data from the given buffer.
*
* @param itemPath the path (in the archive) of the item to be updated.
* @param inBuffer the buffer containing the new data for the item.
*/
void updateItem( const tstring& itemPath, const std::vector< byte_t >& inBuffer );
/**
* @brief Requests to update the content of the item at the specified path
* with the data from the given stream.
*
* @param itemPath the path (in the archive) of the item to be updated.
* @param inStream the stream of new data for the item.
*/
void updateItem( const tstring& itemPath, istream& inStream );
/**
* @brief Marks as deleted the item at the given index.
*
* @note By default, if the item is a folder, only its metadata is deleted, not the files within it.
* If instead the policy is set to DeletePolicy::RecurseDirs,
* then the items within the folder will also be deleted.
*
* @param index the index of the item to be deleted.
* @param policy the policy to be used when deleting items.
*
* @throws BitException if the index is invalid.
*/
void deleteItem( uint32_t index, DeletePolicy policy = DeletePolicy::ItemOnly );
/**
* @brief Marks as deleted the archive's item(s) with the specified path.
*
* @note By default, if the marked item is a folder, only its metadata will be deleted, not the files within it.
* To delete the folder contents as well, set the `policy` to `DeletePolicy::RecurseDirs`.
*
* @note The specified path must not begin with a path separator.
*
* @note A path with a trailing separator will _only_ be considered if
* the policy is DeletePolicy::RecurseDirs, and will only match folders;
* with DeletePolicy::ItemOnly, no item will match a path with a trailing separator.
*
* @note Generally, archives may contain multiple items with the same paths.
* If this is the case, all matching items will be marked as deleted according to the specified policy.
*
* @param itemPath the path (in the archive) of the item to be deleted.
* @param policy the policy to be used when deleting items.
*
* @throws BitException if the specified path is empty or invalid, or if no matching item could be found.
*/
void deleteItem( const tstring& itemPath, DeletePolicy policy = DeletePolicy::ItemOnly );
/**
* @brief Applies the requested changes (i.e., rename/update/delete operations) to the input archive.
*/
void applyChanges();
private:
EditedItems mEditedItems;
auto findItem( const tstring& itemPath ) -> uint32_t;
void checkIndex( uint32_t index );
auto itemProperty( InputIndex index, BitProperty property ) const -> BitPropVariant override;
auto itemStream( InputIndex index, ISequentialInStream** inStream ) const -> HRESULT override;
auto hasNewData( uint32_t index ) const noexcept -> bool override;
auto hasNewProperties( uint32_t index ) const noexcept -> bool override;
void markItemAsDeleted( uint32_t index );
};
} // namespace bit7z
#endif //BITARCHIVEEDITOR_HPP

View file

@ -0,0 +1,112 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEITEM_HPP
#define BITARCHIVEITEM_HPP
#include "bitgenericitem.hpp"
namespace bit7z {
/**
* The BitArchiveItem class represents a generic item inside an archive.
*/
class BitArchiveItem : public BitGenericItem {
public:
/**
* @return the index of the item in the archive.
*/
BIT7Z_NODISCARD auto index() const noexcept -> uint32_t;
/**
* @return true if and only if the item is a directory (i.e., it has the property BitProperty::IsDir).
*/
BIT7Z_NODISCARD auto isDir() const -> bool override;
/**
* @return true if and only if the item is a symbolic link (either has a non-empty BitProperty::SymLink,
* or it has POSIX/Win32 symbolic link file attributes).
*/
BIT7Z_NODISCARD auto isSymLink() const -> bool override;
/**
* @return the item's name; if not available, it tries to get it from the element's path or,
* if not possible, it returns an empty string.
*/
BIT7Z_NODISCARD auto name() const -> tstring override;
/**
* @return the extension of the item, if available or if it can be inferred from the name;
* otherwise it returns an empty string (e.g., when the item is a folder).
*/
BIT7Z_NODISCARD auto extension() const -> tstring;
/**
* @return the path of the item in the archive, if available or inferable from the name, or an empty string
* otherwise.
*/
BIT7Z_NODISCARD auto path() const -> tstring override;
/**
* @note Same as path(), but returning a native string (i.e., std::wstring on Windows, std::string elsewhere).
*
* @return the path of the item in the archive, if available or inferable from the name, or an empty string
* otherwise.
*/
BIT7Z_NODISCARD auto nativePath() const -> native_string;
/**
* @return the uncompressed size of the item.
*/
BIT7Z_NODISCARD auto size() const -> uint64_t override;
/**
* @return the item creation time.
*/
BIT7Z_NODISCARD auto creationTime() const -> time_type;
/**
* @return the item last access time.
*/
BIT7Z_NODISCARD auto lastAccessTime() const -> time_type;
/**
* @return the item last write time.
*/
BIT7Z_NODISCARD auto lastWriteTime() const -> time_type;
/**
* @return the item attributes.
*/
BIT7Z_NODISCARD auto attributes() const -> uint32_t override;
/**
* @return the compressed size of the item.
*/
BIT7Z_NODISCARD auto packSize() const -> uint64_t;
/**
* @return the CRC value of the item.
*/
BIT7Z_NODISCARD auto crc() const -> uint32_t;
/**
* @return true if and only if the item is encrypted.
*/
BIT7Z_NODISCARD auto isEncrypted() const -> bool;
protected:
uint32_t mItemIndex; //Note: it is not const since the subclass BitArchiveItemOffset can increment it!
explicit BitArchiveItem( uint32_t itemIndex ) noexcept;
};
} // namespace bit7z
#endif // BITARCHIVEITEM_HPP

View file

@ -0,0 +1,54 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEITEMINFO_HPP
#define BITARCHIVEITEMINFO_HPP
#include <map>
#include "bitarchiveitem.hpp"
namespace bit7z {
using std::wstring;
using std::map;
/**
* @brief The BitArchiveItemInfo class represents an archived item and that stores all its properties for later use.
*/
class BitArchiveItemInfo final : public BitArchiveItem {
public:
/**
* @brief Gets the specified item property.
*
* @param property the property to be retrieved.
*
* @return the value of the item property, if available, or an empty BitPropVariant.
*/
BIT7Z_NODISCARD auto itemProperty( BitProperty property ) const -> BitPropVariant override;
/**
* @return a map of all the available (i.e., non-empty) item properties and their respective values.
*/
BIT7Z_NODISCARD auto itemProperties() const -> map< BitProperty, BitPropVariant >;
private:
map< BitProperty, BitPropVariant > mItemProperties;
/* BitArchiveItem objects can be created and updated only by BitArchiveReader */
explicit BitArchiveItemInfo( uint32_t itemIndex );
void setProperty( BitProperty property, const BitPropVariant& value );
friend class BitArchiveReader;
};
} // namespace bit7z
#endif // BITARCHIVEITEMINFO_HPP

View file

@ -0,0 +1,53 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEITEMOFFSET_HPP
#define BITARCHIVEITEMOFFSET_HPP
#include "bitarchiveitem.hpp"
namespace bit7z {
class BitInputArchive;
/**
* @brief The BitArchiveItemOffset class represents an archived item but doesn't store its properties.
*/
class BitArchiveItemOffset final : public BitArchiveItem {
public:
auto operator++() noexcept -> BitArchiveItemOffset&;
auto operator++( int ) noexcept -> BitArchiveItemOffset; // NOLINT(cert-dcl21-cpp)
auto operator==( const BitArchiveItemOffset& other ) const noexcept -> bool;
auto operator!=( const BitArchiveItemOffset& other ) const noexcept -> bool;
/**
* @brief Gets the specified item property.
*
* @param property the property to be retrieved.
*
* @return the value of the item property, if available, or an empty BitPropVariant.
*/
BIT7Z_NODISCARD auto itemProperty( BitProperty property ) const -> BitPropVariant override;
private:
/* Note: a pointer, instead of a reference, allows this class, and hence BitInputArchive::ConstIterator,
* to be CopyConstructible so that stl algorithms can be used with ConstIterator! */
const BitInputArchive* mArc;
BitArchiveItemOffset( uint32_t itemIndex, const BitInputArchive& inputArchive ) noexcept;
friend class BitInputArchive;
};
} // namespace bit7z
#endif // BITARCHIVEITEMOFFSET_HPP

View file

@ -0,0 +1,277 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEREADER_HPP
#define BITARCHIVEREADER_HPP
#include "bitabstractarchiveopener.hpp"
#include "bitarchiveiteminfo.hpp"
#include "bitexception.hpp"
#include "bitinputarchive.hpp"
struct IInArchive;
struct IOutArchive;
struct IArchiveExtractCallback;
namespace bit7z {
/**
* @brief The BitArchiveReader class allows reading metadata of archives, as well as extracting them.
*/
class BitArchiveReader final : public BitAbstractArchiveOpener, public BitInputArchive {
public:
/**
* @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 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 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 = {} );
/**
* @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 format the format of 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.
*
* @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 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,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
const tstring& password = {} );
BitArchiveReader( const BitArchiveReader& ) = delete;
BitArchiveReader( BitArchiveReader&& ) = delete;
auto operator=( const BitArchiveReader& ) -> BitArchiveReader& = delete;
auto operator=( BitArchiveReader&& ) -> BitArchiveReader& = delete;
/**
* @brief BitArchiveReader destructor.
*
* @note It releases the input archive file.
*/
~BitArchiveReader() override = default;
/**
* @return a map of all the available (i.e., non-empty) archive properties and their respective values.
*/
BIT7Z_NODISCARD auto archiveProperties() const -> map< BitProperty, BitPropVariant >;
/**
* @return a vector of all the archive items as BitArchiveItem objects.
*/
BIT7Z_NODISCARD auto items() const -> vector< BitArchiveItemInfo >;
/**
* @return the number of folders contained in the archive.
*/
BIT7Z_NODISCARD auto foldersCount() const -> uint32_t;
/**
* @return the number of files contained in the archive.
*/
BIT7Z_NODISCARD auto filesCount() const -> uint32_t;
/**
* @return the total uncompressed size of the archive content.
*/
BIT7Z_NODISCARD auto size() const -> uint64_t;
/**
* @return the total compressed size of the archive content.
*/
BIT7Z_NODISCARD auto packSize() const -> uint64_t;
/**
* @return true if and only if the archive has at least one encrypted item.
*/
BIT7Z_NODISCARD auto hasEncryptedItems() const -> bool;
/**
* @return true if and only if the archive has only encrypted items.
*/
BIT7Z_NODISCARD auto isEncrypted() const -> bool;
/**
* @return the number of volumes composing the archive.
*/
BIT7Z_NODISCARD auto volumesCount() const -> uint32_t;
/**
* @return true if and only if the archive is composed by multiple volumes.
*/
BIT7Z_NODISCARD auto isMultiVolume() const -> bool;
/**
* @return true if and only if the archive was created using solid compression.
*/
BIT7Z_NODISCARD auto isSolid() const -> bool;
/**
* Checks if the given archive is header-encrypted or not.
*
* @tparam T The input type of the archive (i.e., file path, buffer, or standard stream).
*
* @param lib the 7z library used.
* @param inArchive the archive to be read.
* @param format the format of the input archive.
*
* @return true if and only if the archive has at least one encrypted item.
*/
template< typename T >
BIT7Z_NODISCARD
static auto isHeaderEncrypted( const Bit7zLibrary& lib,
T&& inArchive,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT ) -> bool {
try {
const BitArchiveReader reader{ lib, std::forward< T >( inArchive ), format };
return false;
} catch ( const BitException& ex ) {
return isOpenEncryptedError( ex.code() );
}
}
/**
* Checks if the given archive contains only encrypted items.
*
* @note A header-encrypted archive is also encrypted, but the contrary is not generally true.
*
* @note An archive might contain both plain and encrypted files; in this case, this function will
* return false.
*
* @tparam T The input type of the archive (i.e., file path, buffer, or standard stream).
*
* @param lib the 7z library used.
* @param inArchive the archive to be read.
* @param format the format of the input archive.
*
* @return true if and only if the archive has only encrypted items.
*/
template< typename T >
BIT7Z_NODISCARD
static auto isEncrypted( const Bit7zLibrary& lib,
T&& inArchive,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT ) -> bool {
try {
const BitArchiveReader reader{ lib, std::forward< T >( inArchive ), format };
return reader.isEncrypted();
} catch ( const BitException& ex ) {
return isOpenEncryptedError( ex.code() );
}
}
private:
static auto isOpenEncryptedError( std::error_code error ) -> bool;
};
BIT7Z_DEPRECATED_TYPEDEF( BitArchiveInfo, BitArchiveReader, "Since v4.0; please use BitArchiveReader." );
} // namespace bit7z
#endif // BITARCHIVEREADER_HPP

View file

@ -0,0 +1,120 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEWRITER_HPP
#define BITARCHIVEWRITER_HPP
#include "bitoutputarchive.hpp"
namespace bit7z {
/**
* @brief The BitArchiveWriter class allows creating new archives or updating old ones with new items.
*/
class BitArchiveWriter : public BitAbstractArchiveCreator, public BitOutputArchive {
public:
/**
* @brief Constructs an empty BitArchiveWriter object that can write archives of the specified format.
*
* @param lib the 7z library to use.
* @param format the output archive format.
*/
BitArchiveWriter( const Bit7zLibrary& lib, const BitInOutFormat& format );
/**
* @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 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 = {} );
/**
* @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 format the input/output archive format.
* @param password (optional) the password needed to read the input archive.
*/
BitArchiveWriter( const Bit7zLibrary& lib,
const std::vector< byte_t >& inArchive,
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.
*
* @param lib the 7z library to use.
* @param inArchive the standard stream of the input archive.
* @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,
const BitInOutFormat& format,
const tstring& password = {} );
};
} // namespace bit7z
#endif //BITARCHIVEWRITER_HPP

View file

@ -0,0 +1,30 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITCOMPRESSIONLEVEL_HPP
#define BITCOMPRESSIONLEVEL_HPP
namespace bit7z {
/**
* @brief The BitCompressionLevel enum represents the compression level used by 7z when creating archives.
* @note It uses the same values used by [7-zip](https://sevenzip.osdn.jp/chm/cmdline/switches/method.htm#ZipX).
*/
enum struct BitCompressionLevel {
None = 0, ///< Copy mode (no compression)
Fastest = 1, ///< Fastest compressing
Fast = 3, ///< Fast compressing
Normal = 5, ///< Normal compressing
Max = 7, ///< Maximum compressing
Ultra = 9 ///< Ultra compressing
};
} // namespace bit7z
#endif // BITCOMPRESSIONLEVEL_HPP

View file

@ -0,0 +1,30 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITCOMPRESSIONMETHOD_HPP
#define BITCOMPRESSIONMETHOD_HPP
namespace bit7z {
/**
* @brief The BitCompressionMethod enum represents the compression methods used by 7z when creating archives.
*/
enum struct BitCompressionMethod {
Copy,
Deflate,
Deflate64,
BZip2,
Lzma,
Lzma2,
Ppmd
};
} // namespace bit7z
#endif // BITCOMPRESSIONMETHOD_HPP

View file

@ -0,0 +1,116 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITCOMPRESSOR_HPP
#define BITCOMPRESSOR_HPP
#include <vector>
#include "bitoutputarchive.hpp"
namespace bit7z {
using std::vector;
namespace filesystem { // NOLINT(modernize-concat-nested-namespaces)
namespace fsutil {
auto stem( const tstring& path ) -> tstring;
} // namespace fsutil
} // namespace filesystem
using namespace filesystem;
#ifdef __cpp_if_constexpr
#define BIT7Z_IF_CONSTEXPR if constexpr
#else
#define BIT7Z_IF_CONSTEXPR if
#endif
/**
* @brief The BitCompressor template class allows compressing files into archives.
*
* It let decide various properties of the produced archive file, such as the password
* protection and the compression level desired.
*/
template< typename Input >
class BitCompressor : public BitAbstractArchiveCreator {
public:
/**
* @brief Constructs a BitCompressor object.
*
* The Bit7zLibrary parameter is needed to have access to the functionalities
* of the 7z DLLs. On the contrary, the BitInOutFormat is required to know the
* format of the output archive.
*
* @param lib the 7z library to use.
* @param format the output archive format.
*/
BitCompressor( Bit7zLibrary const& lib, BitInOutFormat const& format )
: BitAbstractArchiveCreator( lib, format ) {}
/**
* @brief Compresses a single file.
*
* @param inFile the file to be compressed.
* @param outFile the path (relative or absolute) to the output archive file.
* @param inputName (optional) the name to give to the compressed file inside the output archive.
*/
void compressFile( Input inFile,
const tstring& outFile,
const tstring& inputName = {} ) const {
/* Note: if inFile is a filesystem path (i.e., its type is const tstring&), we can deduce the archived
* item filename using the original filename. Otherwise, if the user didn't specify the input file name,
* we use the filename (without extension) of the output file path. */
tstring name;
BIT7Z_IF_CONSTEXPR( !std::is_same< Input, const tstring& >::value ) {
name = inputName.empty() ? fsutil::stem( outFile ) : inputName;
}
BitOutputArchive outputArchive{ *this, outFile };
outputArchive.addFile( inFile, name );
outputArchive.compressTo( outFile );
}
/**
* @brief Compresses the input file to the output buffer.
*
* @param inFile the file to be compressed.
* @param outBuffer the buffer going to contain the output archive.
* @param inputName (optional) the name to give to the compressed file inside the output archive.
*/
void compressFile( Input inFile,
vector< byte_t >& outBuffer,
const tstring& inputName = {} ) const {
BitOutputArchive outputArchive{ *this, outBuffer };
outputArchive.addFile( inFile, inputName );
outputArchive.compressTo( outBuffer );
}
/**
* @brief Compresses the input file to the output stream.
*
* @param inFile the file to be compressed.
* @param outStream the output stream.
* @param inputName (optional) the name to give to the compressed file inside the output archive.
*/
void compressFile( Input inFile,
ostream& outStream,
const tstring& inputName = {} ) const {
BitOutputArchive outputArchive{ *this };
outputArchive.addFile( inFile, inputName );
outputArchive.compressTo( outStream );
}
};
} // namespace bit7z
#endif //BITCOMPRESSOR_HPP

View file

@ -0,0 +1,121 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITDEFINES_HPP
#define BITDEFINES_HPP
/* Uncomment the following macros if you don't want to define them yourself in your project files,
* and you can't enable them via CMake. */
//#define BIT7Z_AUTO_FORMAT
//#define BIT7Z_AUTO_PREFIX_LONG_PATHS
//#define BIT7Z_DISABLE_USE_STD_FILESYSTEM
//#define BIT7Z_REGEX_MATCHING
//#define BIT7Z_USE_STD_BYTE
//#define BIT7Z_USE_NATIVE_STRING
#if ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201703L ) || ( defined( __cplusplus ) && __cplusplus >= 201703L )
# define BIT7Z_CPP_STANDARD 17
#elif ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201402L ) || ( defined( __cplusplus ) && __cplusplus >= 201402L )
# define BIT7Z_CPP_STANDARD 14
#else
# define BIT7Z_CPP_STANDARD 11
#endif
#ifndef BIT7Z_DISABLE_USE_STD_FILESYSTEM
# if defined( __cpp_lib_filesystem )
# define BIT7Z_USE_STANDARD_FILESYSTEM
# elif BIT7Z_CPP_STANDARD >= 17 && defined( __has_include )
# if __has_include( <filesystem> )
# define BIT7Z_USE_STANDARD_FILESYSTEM
# endif
# endif
#endif
/* Macro defines for [[nodiscard]] and [[maybe_unused]] attributes. */
#if defined( __has_cpp_attribute )
# if __has_cpp_attribute( nodiscard )
# define BIT7Z_NODISCARD [[nodiscard]]
# endif
# if __has_cpp_attribute( maybe_unused )
# define BIT7Z_MAYBE_UNUSED [[maybe_unused]]
# endif
# if __has_cpp_attribute( deprecated )
# define BIT7Z_DEPRECATED [[deprecated]]
# define BIT7Z_DEPRECATED_MSG( msg ) [[deprecated( msg )]]
# endif
#endif
/* The compiler doesn't support __has_cpp_attribute, but it is using the C++17 standard. */
#if !defined( BIT7Z_NODISCARD ) && BIT7Z_CPP_STANDARD >= 17
# define BIT7Z_NODISCARD [[nodiscard]]
#endif
#if !defined( BIT7Z_MAYBE_UNUSED ) && BIT7Z_CPP_STANDARD >= 17
# define BIT7Z_MAYBE_UNUSED [[maybe_unused]]
#endif
#if !defined( BIT7Z_DEPRECATED ) && BIT7Z_CPP_STANDARD >= 14
# define BIT7Z_DEPRECATED [[deprecated]]
# define BIT7Z_DEPRECATED_MSG( msg ) [[deprecated( msg )]]
#endif
/* Compiler is using at most the C++14 standard, so we use the compiler-specific attributes/defines were possible. */
#ifndef BIT7Z_NODISCARD
# if defined( __GNUC__ ) || defined(__clang__)
# define BIT7Z_NODISCARD __attribute__(( warn_unused_result ))
# elif defined( _Check_return_ ) // Old MSVC versions
# define BIT7Z_NODISCARD _Check_return_
# else
# define BIT7Z_NODISCARD
# endif
#endif
#ifndef BIT7Z_MAYBE_UNUSED
# if defined( __GNUC__ ) || defined(__clang__)
# define BIT7Z_MAYBE_UNUSED __attribute__(( unused ))
# else
# define BIT7Z_MAYBE_UNUSED
# endif
#endif
/* Compiler is using the C++11 standard, so we use the compiler-specific attributes were possible.
* Note: these macros are used in the public API, so we cannot assume that we are always using a C++14 compiler.*/
#ifndef BIT7Z_DEPRECATED
# if defined( __GNUC__ ) || defined( __clang__ )
# define BIT7Z_DEPRECATED __attribute__(( __deprecated__ ))
# define BIT7Z_DEPRECATED_MSG( msg ) __attribute__(( __deprecated__( msg ) ))
# elif defined( _MSC_VER )
# define BIT7Z_DEPRECATED __declspec( deprecated )
# define BIT7Z_DEPRECATED_MSG( msg ) __declspec( deprecated( msg ) )
# else
# define BIT7Z_DEPRECATED
# define BIT7Z_DEPRECATED_MSG( msg )
# endif
#endif
#ifndef BIT7Z_DEPRECATED_ENUMERATOR
// Before v6.0, GCC didn't support deprecating single enumerators.
# if defined( __GNUC__ ) && !defined( __clang__ ) && __GNUC__ < 6
# define BIT7Z_DEPRECATED_ENUMERATOR( deprecated_value, new_value, msg ) deprecated_value = new_value
# else
# define BIT7Z_DEPRECATED_ENUMERATOR( deprecated_value, new_value, msg ) \
deprecated_value BIT7Z_DEPRECATED_MSG( msg ) = new_value
# endif
#endif
#ifndef BIT7Z_DEPRECATED_TYPEDEF
# if defined( __GNUC__ ) && !defined( __clang__ ) && __GNUC__ < 7
# define BIT7Z_DEPRECATED_TYPEDEF( alias_name, alias_value, msg ) \
using alias_name BIT7Z_MAYBE_UNUSED __attribute__(( __deprecated__( msg ) )) = alias_value
# else
# define BIT7Z_DEPRECATED_TYPEDEF( alias_name, alias_value, msg ) \
using alias_name BIT7Z_MAYBE_UNUSED BIT7Z_DEPRECATED_MSG( msg ) = alias_value
# endif
#endif
#endif //BITDEFINES_HPP

View file

@ -0,0 +1,84 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITERROR_HPP
#define BITERROR_HPP
#include <system_error>
#include "bitdefines.hpp"
namespace bit7z {
/**
* @brief The BitError enum struct values represent bit7z specific errors.
*/
enum struct BitError {
Fail = 1,
FilterNotSpecified,
FormatFeatureNotSupported,
IndicesNotSpecified,
InvalidArchivePath,
InvalidOutputBufferSize,
InvalidCompressionMethod,
InvalidDictionarySize,
InvalidIndex,
InvalidWordSize,
ItemIsAFolder,
ItemMarkedAsDeleted,
NoMatchingItems,
NoMatchingSignature,
NonEmptyOutputBuffer,
NullOutputBuffer,
RequestedWrongVariantType,
UnsupportedOperation,
UnsupportedVariantType,
WrongUpdateMode,
InvalidZipPassword,
InvalidDirectoryPath,
ItemPathOutsideOutputDirectory,
ItemHasAbsolutePath
};
auto make_error_code( BitError error ) -> std::error_code;
/**
* @brief The BitFailureSource enum struct values represent bit7z error conditions.
* They can be used for performing queries on bit7z's `error_code`s, for the purpose
* of grouping, classification, or error translation.
*/
enum struct BitFailureSource {
CRCError,
DataAfterEnd,
DataError,
InvalidArchive,
InvalidArgument,
FormatDetectionError,
HeadersError,
NoSuchItem,
OperationNotSupported,
OperationNotPermitted,
UnavailableData,
UnexpectedEnd,
WrongPassword
};
auto make_error_condition( BitFailureSource failureSource ) -> std::error_condition;
} // namespace bit7z
namespace std {
template<>
struct BIT7Z_MAYBE_UNUSED is_error_code_enum< bit7z::BitError > : public true_type {};
template <>
struct BIT7Z_MAYBE_UNUSED is_error_condition_enum< bit7z::BitFailureSource > : public true_type {};
} // namespace std
#endif //BITERROR_HPP

View file

@ -0,0 +1,103 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITEXCEPTION_HPP
#define BITEXCEPTION_HPP
#include <vector>
#include <system_error>
#include "bitdefines.hpp"
#include "bittypes.hpp"
#include "bitwindows.hpp"
namespace bit7z {
using std::system_error;
using FailedFiles = std::vector< std::pair< tstring, std::error_code > >;
auto make_hresult_code( HRESULT res ) noexcept -> std::error_code;
auto last_error_code() noexcept -> std::error_code;
/**
* @brief The BitException class represents a generic exception thrown from the bit7z classes.
*/
class BitException final : public system_error {
public:
#ifdef _WIN32
using native_code_type = HRESULT;
#else
using native_code_type = int;
#endif
/**
* @brief Constructs a BitException object with the given message, and the specific files that failed.
*
* @param message the message associated with the exception object.
* @param files the vector of files that failed, with the corresponding error codes.
* @param code the HRESULT code associated with the exception object.
*/
explicit BitException( const char* message, std::error_code code, FailedFiles&& files = {} );
/**
* @brief Constructs a BitException object with the given message, and the specific file that failed.
*
* @param message the message associated with the exception object.
* @param code the HRESULT code associated with the exception object.
* @param file the file that failed during the operation.
*/
BitException( const char* message, std::error_code code, tstring&& file );
/**
* @brief Constructs a BitException object with the given message, and the specific file that failed.
*
* @param message the message associated with the exception object.
* @param code the HRESULT code associated with the exception object.
* @param file the file that failed during the operation.
*/
BitException( const char* message, std::error_code code, const tstring& file );
/**
* @brief Constructs a BitException object with the given message.
*
* @param message the message associated with the exception object.
* @param code the HRESULT code associated with the exception object.
*/
explicit BitException( const std::string& message, std::error_code code );
/**
* @return the native error code (e.g., HRESULT on Windows, int elsewhere)
* corresponding to the exception's std::error_code.
*/
BIT7Z_NODISCARD auto nativeCode() const noexcept -> native_code_type;
/**
* @return the HRESULT error code corresponding to the exception's std::error_code.
*/
BIT7Z_NODISCARD auto hresultCode() const noexcept -> HRESULT;
/**
* @return the POSIX error code corresponding to the exception's std::error_code.
*/
BIT7Z_NODISCARD auto posixCode() const noexcept -> int;
/**
* @return the vector of files that caused the exception to be thrown, along with the corresponding
* error codes.
*/
BIT7Z_NODISCARD auto failedFiles() const noexcept -> const FailedFiles&;
private:
FailedFiles mFailedFiles;
};
} // namespace bit7z
#endif // BITEXCEPTION_HPP

View file

@ -0,0 +1,284 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITEXTRACTOR_HPP
#define BITEXTRACTOR_HPP
#include <algorithm>
#include "bitabstractarchiveopener.hpp"
#include "biterror.hpp"
#include "bitexception.hpp"
#include "bitinputarchive.hpp"
namespace bit7z {
namespace filesystem { // NOLINT(modernize-concat-nested-namespaces)
namespace fsutil {
auto wildcard_match( const tstring& pattern, const tstring& str ) -> bool;
} // namespace fsutil
} // namespace filesystem
/**
* @brief The BitExtractor template class allows extracting the content of archives from supported input types.
*
* @tparam Input the type of input archives that the generated extractor class supports.
*/
template< typename Input >
class BitExtractor final : public BitAbstractArchiveOpener {
public:
/**
* @brief Constructs a BitExtractor object.
*
* The Bit7zLibrary parameter is needed to have access to the functionalities
* of the 7z DLLs. On the contrary, the BitInFormat is required to know the
* format of the in_file archives.
*
* @note When bit7z is compiled using the BIT7Z_AUTO_FORMAT macro define, the format
* argument has the default value BitFormat::Auto (automatic format detection of the in_file archive).
* Otherwise, 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 to use.
* @param format the in_file archive format.
*/
explicit BitExtractor( const Bit7zLibrary& lib, const BitInFormat& format BIT7Z_DEFAULT_FORMAT )
: BitAbstractArchiveOpener( lib, format ) {}
/**
* @brief Extracts the given archive to the chosen directory.
*
* @param inArchive the input archive to be extracted.
* @param outDir the output directory where extracted files will be put.
*/
void extract( Input inArchive, const tstring& outDir = {} ) const {
BitInputArchive inputArchive( *this, inArchive );
inputArchive.extractTo( outDir );
}
/**
* @brief Extracts a file from the given archive to the output buffer.
*
* @param inArchive the input archive to extract from.
* @param outBuffer the output buffer where the content of the extracted file will be put.
* @param index the index of the file to be extracted from the archive.
*/
void extract( Input inArchive, vector< byte_t >& outBuffer, uint32_t index = 0 ) const {
BitInputArchive inputArchive( *this, inArchive );
inputArchive.extractTo( outBuffer, index );
}
/**
* @brief Extracts a file from the given archive to the output stream.
*
* @param inArchive the input archive to extract from.
* @param outStream the (binary) stream where the content of the extracted file will be put.
* @param index the index of the file to be extracted from the archive.
*/
void extract( Input inArchive, std::ostream& outStream, uint32_t index = 0 ) const {
BitInputArchive inputArchive( *this, inArchive );
inputArchive.extractTo( outStream, index );
}
/**
* @brief Extracts the content of the given archive into a map of memory buffers, where the keys are
* the paths of the files (inside the archive), and the values are their decompressed contents.
*
* @param inArchive the input archive to be extracted.
* @param outMap the output map.
*/
void extract( Input inArchive, std::map< tstring, vector< byte_t > >& outMap ) const {
BitInputArchive inputArchive( *this, inArchive );
inputArchive.extractTo( outMap );
}
/**
* @brief Extracts the files in the archive that match the given wildcard pattern to the chosen directory.
*
* @param inArchive the input archive to extract from.
* @param itemFilter the wildcard pattern used for matching the paths of files inside the archive.
* @param outDir the output directory where extracted files will be put.
* @param policy the filtering policy to be applied to the matched items.
*/
void extractMatching( Input inArchive,
const tstring& itemFilter,
const tstring& outDir = {},
FilterPolicy policy = FilterPolicy::Include ) const {
using namespace filesystem;
if ( itemFilter.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::FilterNotSpecified ) );
}
extractMatchingFilter( inArchive, outDir, policy, [ &itemFilter ]( const tstring& itemPath ) -> bool {
return fsutil::wildcard_match( itemFilter, itemPath );
} );
}
/**
* @brief Extracts to the output buffer the first file in the archive matching the given wildcard pattern.
*
* @param inArchive the input archive to extract from.
* @param itemFilter the wildcard pattern used for matching the paths of files inside the archive.
* @param outBuffer the output buffer where to extract the file.
* @param policy the filtering policy to be applied to the matched items.
*/
void extractMatching( Input inArchive,
const tstring& itemFilter,
vector< byte_t >& outBuffer,
FilterPolicy policy = FilterPolicy::Include ) const {
using namespace filesystem;
if ( itemFilter.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::FilterNotSpecified ) );
}
extractMatchingFilter( inArchive, outBuffer, policy,
[ &itemFilter ]( const tstring& itemPath ) -> bool {
return fsutil::wildcard_match( itemFilter, itemPath );
} );
}
/**
* @brief Extracts the specified items from the given archive to the chosen directory.
*
* @param inArchive the input archive to extract from.
* @param indices the indices of the files in the archive that should be extracted.
* @param outDir the output directory where the extracted files will be placed.
*/
void extractItems( Input inArchive,
const std::vector< uint32_t >& indices,
const tstring& outDir = {} ) const {
if ( indices.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::IndicesNotSpecified ) );
}
BitInputArchive inputArchive( *this, inArchive );
inputArchive.extractTo( outDir, indices );
}
#ifdef BIT7Z_REGEX_MATCHING
/**
* @brief Extracts the files in the archive that match the given regex pattern to the chosen directory.
*
* @note Available only when compiling bit7z using the BIT7Z_REGEX_MATCHING preprocessor define.
*
* @param inArchive the input archive to extract from.
* @param regex the regex used for matching the paths of files inside the archive.
* @param outDir the output directory where extracted files will be put.
* @param policy the filtering policy to be applied to the matched items.
*/
void extractMatchingRegex( Input inArchive,
const tstring& regex,
const tstring& outDir = {},
FilterPolicy policy = FilterPolicy::Include ) const {
if ( regex.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::FilterNotSpecified ) );
}
const tregex regexFilter( regex, tregex::ECMAScript | tregex::optimize );
extractMatchingFilter( inArchive, outDir, policy, [ &regexFilter ]( const tstring& itemPath ) -> bool {
return std::regex_match( itemPath, regexFilter );
} );
}
/**
* @brief Extracts the first file in the archive that matches the given regex pattern to the output buffer.
*
* @note Available only when compiling bit7z using the BIT7Z_REGEX_MATCHING preprocessor define.
*
* @param inArchive the input archive to extract from.
* @param regex the regex used for matching the paths of files inside the archive.
* @param outBuffer the output buffer where the extracted file will be put.
* @param policy the filtering policy to be applied to the matched items.
*/
void extractMatchingRegex( Input inArchive,
const tstring& regex,
vector< byte_t >& outBuffer,
FilterPolicy policy = FilterPolicy::Include ) const {
if ( regex.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::FilterNotSpecified ) );
}
const tregex regexFilter( regex, tregex::ECMAScript | tregex::optimize );
return extractMatchingFilter( inArchive, outBuffer, policy,
[ &regexFilter ]( const tstring& itemPath ) -> bool {
return std::regex_match( itemPath, regexFilter );
} );
}
#endif
/**
* @brief Tests the given archive without extracting its content.
*
* If the archive is not valid, a BitException is thrown!
*
* @param inArchive the input archive to be tested.
*/
void test( Input inArchive ) const {
BitInputArchive inputArchive( *this, inArchive );
inputArchive.test();
}
private:
void extractMatchingFilter( Input inArchive,
const tstring& outDir,
FilterPolicy policy,
const std::function< bool( const tstring& ) >& filter ) const {
BitInputArchive inputArchive( *this, inArchive );
vector< uint32_t > matchedIndices;
const bool shouldExtractMatchedItems = policy == FilterPolicy::Include;
// Searching for files inside the archive that match the given filter
for ( const auto& item : inputArchive ) {
const bool itemMatches = filter( item.path() );
if ( itemMatches == shouldExtractMatchedItems ) {
/* The if-condition is equivalent to an exclusive XNOR (negated XOR) between
* itemMatches and shouldExtractMatchedItems.
* In other words, it is true only if the current item either:
* - matches the filter, and we must include any matching item; or
* - doesn't match the filter, and we must exclude those that match. */
matchedIndices.push_back( item.index() );
}
}
if ( matchedIndices.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::NoMatchingItems ) );
}
inputArchive.extractTo( outDir, matchedIndices );
}
void extractMatchingFilter( Input inArchive,
vector< byte_t >& outBuffer,
FilterPolicy policy,
const std::function< bool( const tstring& ) >& filter ) const {
BitInputArchive inputArchive( *this, inArchive );
const bool shouldExtractMatchedItem = policy == FilterPolicy::Include;
// Searching for files inside the archive that match the given filter
for ( const auto& item : inputArchive ) {
const bool itemMatches = filter( item.path() );
if ( itemMatches == shouldExtractMatchedItem ) {
/* The if-condition is equivalent to an exclusive NOR (negated XOR) between
* itemMatches and shouldExtractMatchedItem. */
inputArchive.extractTo( outBuffer, item.index() );
return;
}
}
throw BitException( "Failed to extract items", make_error_code( BitError::NoMatchingItems ) );
}
};
} // namespace bit7z
#endif //BITEXTRACTOR_HPP

View file

@ -0,0 +1,150 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITFILECOMPRESSOR_HPP
#define BITFILECOMPRESSOR_HPP
#include <map>
#include <ostream>
#include <vector>
#include "bitcompressor.hpp"
namespace bit7z {
using std::vector;
using std::map;
using std::ostream;
using namespace filesystem;
/**
* @brief The BitFileCompressor class allows compressing files and directories.
* The compressed archives can be saved to the filesystem, standard streams, or memory buffers.
*
* It let decide various properties of the produced archive, such as the password
* protection and the compression level desired.
*/
class BitFileCompressor final : public BitCompressor< const tstring& > {
public:
/**
* @brief Constructs a BitFileCompressor object.
*
* The Bit7zLibrary parameter is needed to have access to the functionalities
* of the 7z DLLs. On the contrary, the BitInOutFormat is required to know the
* format of the output archive.
*
* @param lib the 7z library used.
* @param format the output archive format.
*/
BitFileCompressor( const Bit7zLibrary& lib, const BitInOutFormat& format );
/* Compression from the file system to the file system. */
/**
* @brief Compresses the given files or directories.
*
* The items in the first argument must be the relative or absolute paths to files or
* directories existing on the filesystem.
*
* @param inPaths a vector of paths.
* @param outFile the path (relative or absolute) to the output archive file.
*/
void compress( const std::vector< tstring >& inPaths, const tstring& outFile ) const;
/**
* @brief Compresses the given files or directories using the specified aliases.
*
* The items in the first argument must be the relative or absolute paths to files or
* directories existing on the filesystem.
* Each pair in the map must follow the following format:
* {"path to file in the filesystem", "alias path in the archive"}.
*
* @param inPaths a map of paths and corresponding aliases.
* @param outFile the path (relative or absolute) to the output archive file.
*/
void compress( const std::map< tstring, tstring >& inPaths, const tstring& outFile ) const;
/**
* @brief Compresses a group of files.
*
* @note Any path to a directory or to a not-existing file will be ignored!
*
* @param inFiles the path (relative or absolute) to the input files.
* @param outFile the path (relative or absolute) to the output archive file.
*/
void compressFiles( const std::vector< tstring >& inFiles, const tstring& outFile ) const;
/**
* @brief Compresses the files contained in a directory.
*
* @param inDir the path (relative or absolute) to the input directory.
* @param outFile the path (relative or absolute) to the output archive file.
* @param recursive (optional) if true, it searches files inside the sub-folders of inDir.
* @param filter (optional) the filter to use when searching files inside inDir.
*/
void compressFiles( const tstring& inDir,
const tstring& outFile,
bool recursive = true,
const tstring& filter = BIT7Z_STRING( "*" ) ) const;
/**
* @brief Compresses an entire directory.
*
* @note This method is equivalent to compressFiles with filter set to L"".
*
* @param inDir the path (relative or absolute) to the input directory.
* @param outFile the path (relative or absolute) to the output archive file.
*/
void compressDirectory( const tstring& inDir, const tstring& outFile ) const;
/**
* @brief Compresses the contents of a directory.
*
* @note Unlike compressFiles, this method includes also the metadata of the sub-folders.
*
* @param inDir the path (relative or absolute) to the input directory.
* @param outFile the path (relative or absolute) to the output archive file.
* @param recursive (optional) if true, it searches the contents inside the sub-folders of inDir.
* @param filter (optional) the filter to use when searching the contents inside inDir.
*/
void compressDirectoryContents( const tstring& inDir,
const tstring& outFile,
bool recursive = true,
const tstring& filter = BIT7Z_STRING( "*" ) ) const;
/* Compression from the file system to standard streams. */
/**
* @brief Compresses the given files or directories.
*
* The items in the first argument must be the relative or absolute paths to files or
* directories existing on the filesystem.
*
* @param inPaths a vector of paths.
* @param outStream the standard ostream where the archive will be output.
*/
void compress( const std::vector< tstring >& inPaths, std::ostream& outStream ) const;
/**
* @brief Compresses the given files or directories using the specified aliases.
*
* The items in the first argument must be the relative or absolute paths to files or
* directories existing on the filesystem.
* Each pair in the map must follow the following format:
* {"path to file in the filesystem", "alias path in the archive"}.
*
* @param inPaths a map of paths and corresponding aliases.
* @param outStream the standard ostream where to output the archive file.
*/
void compress( const std::map< tstring, tstring >& inPaths, std::ostream& outStream ) const;
};
} // namespace bit7z
#endif // BITFILECOMPRESSOR_HPP

View file

@ -0,0 +1,23 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITFILEEXTRACTOR_HPP
#define BITFILEEXTRACTOR_HPP
#include "bitextractor.hpp"
namespace bit7z {
/**
* @brief The BitFileExtractor alias allows extracting archives on the filesystem.
*/
using BitFileExtractor BIT7Z_MAYBE_UNUSED = BitExtractor< const tstring& >;
} // namespace bit7z
#endif // BITFILEEXTRACTOR_HPP

View file

@ -0,0 +1,254 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITFORMAT_HPP
#define BITFORMAT_HPP
#include <bitset>
#include <type_traits>
#include "bitcompressionmethod.hpp"
#include "bitdefines.hpp"
#include "bittypes.hpp"
namespace bit7z {
/**
* @brief The FormatFeatures enum specifies the features supported by an archive file format.
*/
enum struct FormatFeatures : unsigned {
MultipleFiles = 1u << 0, ///< The format can compress/extract multiple files (2^0 = 0000001)
SolidArchive = 1u << 1, ///< The format supports solid archives (2^1 = 0000010)
CompressionLevel = 1u << 2, ///< The format is able to use different compression levels (2^2 = 0000100)
Encryption = 1u << 3, ///< The format supports archive encryption (2^3 = 0001000)
HeaderEncryption = 1u << 4, ///< The format can encrypt the file names (2^4 = 0010000)
MultipleMethods = 1u << 5 ///< The format can use different compression methods (2^6 = 0100000)
};
template< typename Enum >
using underlying_type_t = typename std::underlying_type< Enum >::type;
template< typename Enum >
inline constexpr auto to_underlying( Enum enum_value ) noexcept -> underlying_type_t< Enum > {
return static_cast< underlying_type_t< Enum > >( enum_value );
}
inline constexpr auto operator|( FormatFeatures lhs, FormatFeatures rhs ) noexcept -> FormatFeatures {
return static_cast< FormatFeatures >( to_underlying( lhs ) | to_underlying( rhs ) );
}
using FormatFeaturesType = underlying_type_t< FormatFeatures >;
inline constexpr auto operator&( FormatFeatures lhs, FormatFeatures rhs ) noexcept -> FormatFeaturesType {
return to_underlying( lhs ) & to_underlying( rhs );
}
/**
* @brief The BitInFormat class specifies an extractable archive format.
*
* @note Usually, the user of the library should not create new formats and, instead,
* use the ones provided by the BitFormat namespace.
*/
class BitInFormat {
public:
//non-copyable
BitInFormat( const BitInFormat& other ) = delete;
auto operator=( const BitInFormat& other ) -> BitInFormat& = delete;
//non-movable
BitInFormat( BitInFormat&& other ) = delete;
auto operator=( BitInFormat&& other ) -> BitInFormat& = delete;
~BitInFormat() = default;
/**
* @brief Constructs a BitInFormat object with the ID value used by the 7z SDK.
* @param value the value of the format in the 7z SDK.
*/
constexpr explicit BitInFormat( unsigned char value ) noexcept: mValue( value ) {}
/**
* @return the value of the format in the 7z SDK.
*/
BIT7Z_NODISCARD auto value() const noexcept -> unsigned char;
/**
* @param other the target object to compare to.
* @return a boolean value indicating whether this format is equal to the "other" or not.
*/
auto operator==( BitInFormat const& other ) const noexcept -> bool;
/**
* @param other the target object to compare to.
* @return a boolean value indicating whether this format is different from the "other" or not.
*/
auto operator!=( BitInFormat const& other ) const noexcept -> bool;
private:
unsigned char mValue;
};
/**
* @brief The BitInOutFormat class specifies a format available for creating new archives and extract old ones.
*
* @note Usually, the user of the library should not create new formats and, instead,
* use the ones provided by the BitFormat namespace.
*/
class BitInOutFormat final : public BitInFormat {
public:
/**
* @brief Constructs a BitInOutFormat object with an ID value, an extension and a set of supported features.
*
* @param value the value of the format in the 7z SDK.
* @param ext the default file extension of the archive format.
* @param defaultMethod the default method used for compressing the archive format.
* @param features the set of features supported by the archive format
*/
constexpr BitInOutFormat( unsigned char value,
const tchar* ext,
BitCompressionMethod defaultMethod,
FormatFeatures features ) noexcept
: BitInFormat( value ), mExtension( ext ), mDefaultMethod( defaultMethod ), mFeatures( features ) {}
//non-copyable
BitInOutFormat( const BitInOutFormat& other ) = delete;
auto operator=( const BitInOutFormat& other ) -> BitInOutFormat& = delete;
//non-movable
BitInOutFormat( BitInOutFormat&& other ) = delete;
auto operator=( BitInOutFormat&& other ) -> BitInOutFormat& = delete;
~BitInOutFormat() = default;
/**
* @return the default file extension of the archive format.
*/
BIT7Z_NODISCARD
auto extension() const noexcept -> const tchar*;
/**
* @return the bitset of the features supported by the format.
*/
BIT7Z_NODISCARD
auto features() const noexcept -> FormatFeatures;
/**
* @brief Checks if the format has a specific feature (see FormatFeatures enum).
*
* @param feature feature to be checked.
*
* @return a boolean value indicating whether the format has the given feature.
*/
BIT7Z_NODISCARD
auto hasFeature( FormatFeatures feature ) const noexcept -> bool;
/**
* @return the default method used for compressing the archive format.
*/
BIT7Z_NODISCARD
auto defaultMethod() const noexcept -> BitCompressionMethod;
private:
const tchar* mExtension;
BitCompressionMethod mDefaultMethod;
FormatFeatures mFeatures;
};
/**
* @brief The namespace that contains a set of archive formats usable with bit7z classes.
*/
namespace BitFormat {
#ifdef BIT7Z_AUTO_FORMAT
/**
* @brief Automatic Format Detection (available only when compiling bit7z using the `BIT7Z_AUTO_FORMAT` option).
*/
extern const BitInFormat Auto;
#endif
extern const BitInFormat Rar; ///< RAR Archive Format
extern const BitInFormat Arj; ///< ARJ Archive Format
//NOLINTNEXTLINE(*-identifier-length)
extern const BitInFormat Z; ///< Z Archive Format
extern const BitInFormat Lzh; ///< LZH Archive Format
extern const BitInFormat Cab; ///< CAB Archive Format
extern const BitInFormat Nsis; ///< NSIS Archive Format
extern const BitInFormat Lzma; ///< LZMA Archive Format
extern const BitInFormat Lzma86; ///< LZMA86 Archive Format
extern const BitInFormat Ppmd; ///< PPMD Archive Format
extern const BitInFormat Zstd; ///< ZSTD Archive Format
extern const BitInFormat LVM; ///< LVM Archive Format
extern const BitInFormat AVB; ///< AVB Archive Format
extern const BitInFormat LP; ///< LP Archive Format
extern const BitInFormat Sparse; ///< Sparse Archive Format
extern const BitInFormat APFS; ///< APFS Archive Format
extern const BitInFormat Vhdx; ///< VHDX Archive Format
extern const BitInFormat COFF; ///< COFF Archive Format
extern const BitInFormat Ext; ///< EXT Archive Format
extern const BitInFormat VMDK; ///< VMDK Archive Format
extern const BitInFormat VDI; ///< VDI Archive Format
extern const BitInFormat QCow; ///< QCOW Archive Format
extern const BitInFormat GPT; ///< GPT Archive Format
extern const BitInFormat Rar5; ///< RAR5 Archive Format
extern const BitInFormat IHex; ///< IHEX Archive Format
extern const BitInFormat Hxs; ///< HXS Archive Format
//NOLINTNEXTLINE(*-identifier-length)
extern const BitInFormat TE; ///< TE Archive Format
extern const BitInFormat UEFIc; ///< UEFIc Archive Format
extern const BitInFormat UEFIs; ///< UEFIs Archive Format
extern const BitInFormat SquashFS; ///< SquashFS Archive Format
extern const BitInFormat CramFS; ///< CramFS Archive Format
extern const BitInFormat APM; ///< APM Archive Format
extern const BitInFormat Mslz; ///< MSLZ Archive Format
extern const BitInFormat Flv; ///< FLV Archive Format
extern const BitInFormat Swf; ///< SWF Archive Format
extern const BitInFormat Swfc; ///< SWFC Archive Format
extern const BitInFormat Ntfs; ///< NTFS Archive Format
extern const BitInFormat Fat; ///< FAT Archive Format
extern const BitInFormat Mbr; ///< MBR Archive Format
extern const BitInFormat Vhd; ///< VHD Archive Format
//NOLINTNEXTLINE(*-identifier-length)
extern const BitInFormat Pe; ///< PE Archive Format
extern const BitInFormat Elf; ///< ELF Archive Format
extern const BitInFormat Macho; ///< MACHO Archive Format
extern const BitInFormat Udf; ///< UDF Archive Format
extern const BitInFormat Xar; ///< XAR Archive Format
extern const BitInFormat Mub; ///< MUB Archive Format
extern const BitInFormat Hfs; ///< HFS Archive Format
extern const BitInFormat Dmg; ///< DMG Archive Format
extern const BitInFormat Compound; ///< COMPOUND Archive Format
extern const BitInFormat Iso; ///< ISO Archive Format
extern const BitInFormat Chm; ///< CHM Archive Format
extern const BitInFormat Split; ///< SPLIT Archive Format
extern const BitInFormat Rpm; ///< RPM Archive Format
extern const BitInFormat Deb; ///< DEB Archive Format
extern const BitInFormat Cpio; ///< CPIO Archive Format
extern const BitInOutFormat Zip; ///< ZIP Archive Format
extern const BitInOutFormat BZip2; ///< BZIP2 Archive Format
extern const BitInOutFormat SevenZip; ///< 7Z Archive Format
//NOLINTNEXTLINE(*-identifier-length)
extern const BitInOutFormat Xz; ///< XZ Archive Format
extern const BitInOutFormat Wim; ///< WIM Archive Format
extern const BitInOutFormat Tar; ///< TAR Archive Format
extern const BitInOutFormat GZip; ///< GZIP Archive Format
} // namespace BitFormat
#ifdef BIT7Z_AUTO_FORMAT
#define BIT7Z_DEFAULT_FORMAT = BitFormat::Auto
#else
#define BIT7Z_DEFAULT_FORMAT
#endif
} // namespace bit7z
#endif // BITFORMAT_HPP

View file

@ -0,0 +1,43 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITFS_HPP
#define BITFS_HPP
/* Header for forward declaring fs namespace. */
#include "bitdefines.hpp" /* For BIT7Z_USE_STANDARD_FILESYSTEM */
#ifdef BIT7Z_USE_STANDARD_FILESYSTEM
#include <filesystem>
#else
/* Notes: we use this forward declaration to avoid including private headers (e.g. fs.hpp).
* Since some public API headers include bitgenericitem.hpp (e.g. "bitoutputarchive.hpp"),
* including private headers here would result in the "leaking" out of these latter in the public API.*/
namespace ghc {
namespace filesystem {
class path;
} // namespace filesystem
} // namespace ghc
#endif
namespace bit7z {
namespace fs {
#ifdef BIT7Z_USE_STANDARD_FILESYSTEM
using namespace std::filesystem;
#else
using namespace ghc::filesystem;
#endif
} // namespace fs
} // namespace bit7z
#endif //BITFS_HPP

View file

@ -0,0 +1,66 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITGENERICITEM_HPP
#define BITGENERICITEM_HPP
#include "bitpropvariant.hpp"
namespace bit7z {
/**
* @brief The BitGenericItem interface class represents a generic item (either inside or outside an archive).
*/
class BitGenericItem {
public:
/**
* @return true if and only if the item is a directory (i.e., it has the property BitProperty::IsDir).
*/
BIT7Z_NODISCARD virtual auto isDir() const -> bool = 0;
/**
* @return true if and only if the item is a symbolic link.
*/
BIT7Z_NODISCARD virtual auto isSymLink() const -> bool = 0;
/**
* @return the uncompressed size of the item.
*/
BIT7Z_NODISCARD virtual auto size() const -> uint64_t = 0;
/**
* @return the name of the item, if available or inferable from the path, or an empty string otherwise.
*/
BIT7Z_NODISCARD virtual auto name() const -> tstring = 0;
/**
* @return the path of the item.
*/
BIT7Z_NODISCARD virtual auto path() const -> tstring = 0;
/**
* @return the item attributes.
*/
BIT7Z_NODISCARD virtual auto attributes() const -> uint32_t = 0;
/**
* @brief Gets the specified item property.
*
* @param property the property to be retrieved.
*
* @return the value of the item property, if available, or an empty BitPropVariant.
*/
BIT7Z_NODISCARD virtual auto itemProperty( BitProperty property ) const -> BitPropVariant = 0;
virtual ~BitGenericItem() = default;
};
} // namespace bit7z
#endif //BITGENERICITEM_HPP

View file

@ -0,0 +1,452 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITINPUTARCHIVE_HPP
#define BITINPUTARCHIVE_HPP
#include <array>
#include <map>
#include "bitabstractarchivehandler.hpp"
#include "bitarchiveitemoffset.hpp"
#include "bitformat.hpp"
#include "bitfs.hpp"
struct IInStream;
struct IInArchive;
struct IOutArchive;
namespace bit7z {
using std::vector;
/**
* @brief Offset from where the archive starts within the input file.
*/
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.
*/
class BitInputArchive {
public:
/**
* @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 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,
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 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,
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 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 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 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,
ArchiveStartOffset startOffset = ArchiveStartOffset::None );
BitInputArchive( const BitInputArchive& ) = delete;
BitInputArchive( BitInputArchive&& ) = delete;
auto operator=( const BitInputArchive& ) -> BitInputArchive& = delete;
auto operator=( BitInputArchive&& ) -> BitInputArchive& = delete;
virtual ~BitInputArchive();
/**
* @return the detected format of the file.
*/
BIT7Z_NODISCARD auto detectedFormat() const noexcept -> const BitInFormat&;
/**
* @brief Gets the specified archive property.
*
* @param property the property to be retrieved.
*
* @return the current value of the archive property or an empty BitPropVariant if no value is specified.
*/
BIT7Z_NODISCARD auto archiveProperty( BitProperty property ) const -> BitPropVariant;
/**
* @brief Gets the specified property of an item in the archive.
*
* @param index the index (in the archive) of the item.
* @param property the property to be retrieved.
*
* @return the current value of the item property or an empty BitPropVariant if the item has no value for
* the property.
*/
BIT7Z_NODISCARD auto itemProperty( uint32_t index, BitProperty property ) const -> BitPropVariant;
/**
* @return the number of items contained in the archive.
*/
BIT7Z_NODISCARD auto itemsCount() const -> uint32_t;
/**
* @param index the index of an item in the archive.
*
* @return true if and only if the item at the given index is a folder.
*/
BIT7Z_NODISCARD auto isItemFolder( uint32_t index ) const -> bool;
/**
* @param index the index of an item in the archive.
*
* @return true if and only if the item at the given index is encrypted.
*/
BIT7Z_NODISCARD auto isItemEncrypted( uint32_t index ) const -> bool;
/**
* @return the path to the archive (the empty string for buffer/stream archives).
*/
BIT7Z_NODISCARD auto archivePath() const noexcept -> const tstring&;
/**
* @return the BitAbstractArchiveHandler object containing the settings for reading the archive.
*/
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 );
}
/**
* @brief Extracts the archive to the chosen directory.
*
* @param outDir the output directory where the extracted files will be put.
*/
void extractTo( const tstring& outDir ) const;
/**
* @brief Extracts the specified items to the chosen directory.
*
* @param outDir the output directory where the extracted files will be put.
* @param indices the array of indices of the files in the archive that must be extracted.
*/
void extractTo( const tstring& outDir, const std::vector< uint32_t >& indices ) const;
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
inline void extract( std::vector< byte_t >& outBuffer, uint32_t index = 0 ) const {
extractTo( outBuffer, index );
}
/**
* @brief Extracts a file to the output buffer.
*
* @param outBuffer the output buffer where the content of the archive will be put.
* @param index the index of the file to be extracted.
*/
void extractTo( std::vector< byte_t >& outBuffer, uint32_t index = 0 ) const;
template< std::size_t N >
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
void extract( std::array< byte_t, N >& buffer, uint32_t index = 0 ) const {
extractTo( buffer.data(), buffer.size(), index );
}
/**
* @brief Extracts a file to the pre-allocated output buffer.
*
* @tparam N the size of the output buffer (it must be equal to the unpacked size
* of the item to be extracted).
* @param buffer the pre-allocated output buffer.
* @param index the index of the file to be extracted.
*/
template< std::size_t N >
void extractTo( std::array< byte_t, N >& buffer, uint32_t index = 0 ) const {
extractTo( buffer.data(), buffer.size(), index );
}
template< std::size_t N >
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
void extract( byte_t (& buffer)[N], uint32_t index = 0 ) const { // NOLINT(*-avoid-c-arrays)
extractTo( buffer, N, index );
}
/**
* @brief Extracts a file to the pre-allocated output buffer.
*
* @tparam N the size of the output buffer (it must be equal to the unpacked size
* of the item to be extracted).
* @param buffer the pre-allocated output buffer.
* @param index the index of the file to be extracted.
*/
template< std::size_t N >
void extractTo( byte_t (& buffer)[N], uint32_t index = 0 ) const { // NOLINT(*-avoid-c-arrays)
extractTo( buffer, N, index );
}
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
inline void extract( byte_t* buffer, std::size_t size, uint32_t index = 0 ) const {
extractTo( buffer, size, index );
}
/**
* @brief Extracts a file to the pre-allocated output buffer.
*
* @param buffer the pre-allocated output buffer.
* @param size the size of the output buffer (it must be equal to the unpacked size
* of the item to be extracted).
* @param index the index of the file to be extracted.
*/
void extractTo( byte_t* buffer, std::size_t size, uint32_t index = 0 ) const;
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
inline void extract( std::ostream& outStream, uint32_t index = 0 ) const {
extractTo( outStream, index );
}
/**
* @brief Extracts a file to the output stream.
*
* @param outStream the (binary) stream where the content of the archive will be put.
* @param index the index of the file to be extracted.
*/
void extractTo( std::ostream& outStream, uint32_t index = 0 ) const;
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
inline void extract( std::map< tstring, std::vector< byte_t > >& outMap ) const {
extractTo( outMap );
}
/**
* @brief Extracts the content of the archive to a map of memory buffers, where the keys are the paths
* of the files (inside the archive), and the values are their decompressed contents.
*
* @param outMap the output map.
*/
void extractTo( std::map< tstring, std::vector< byte_t > >& outMap ) const;
/**
* @brief Tests the archive without extracting its content.
*
* If the archive is not valid, a BitException is thrown!
*/
void test() const;
/**
* @brief Tests the item at the given index inside the archive without extracting it.
*
* If the archive is not valid, or there's no item at the given index, a BitException is thrown!
*
* @param index the index of the file to be tested.
*/
void testItem( uint32_t index ) const;
protected:
auto initUpdatableArchive( IOutArchive** newArc ) const -> HRESULT;
BIT7Z_NODISCARD auto close() const noexcept -> HRESULT;
friend class BitAbstractArchiveOpener;
friend class BitAbstractArchiveCreator;
friend class BitOutputArchive;
private:
IInArchive* mInArchive;
const BitInFormat* mDetectedFormat;
const BitAbstractArchiveHandler& mArchiveHandler;
tstring mArchivePath;
BIT7Z_NODISCARD
auto openArchiveStream( const fs::path& name, IInStream* inStream, ArchiveStartOffset startOffset ) -> IInArchive*;
public:
/**
* @brief An iterator for the elements contained in an archive.
*/
class ConstIterator {
public:
// iterator traits
using iterator_category BIT7Z_MAYBE_UNUSED = std::input_iterator_tag;
using value_type BIT7Z_MAYBE_UNUSED = BitArchiveItemOffset;
using reference = const BitArchiveItemOffset&;
using pointer = const BitArchiveItemOffset*;
using difference_type BIT7Z_MAYBE_UNUSED = uint32_t; //so that count_if returns an uint32_t
/**
* @brief Advances the iterator to the next element in the archive.
*
* @return the iterator pointing to the next element in the archive.
*/
auto operator++() noexcept -> ConstIterator&;
/**
* @brief Advances the iterator to the next element in the archive.
*
* @return the iterator before the advancement.
*/
auto operator++( int ) noexcept -> ConstIterator; // NOLINT(cert-dcl21-cpp)
/**
* @brief Compares the iterator with another iterator.
*
* @param other Another iterator.
*
* @return whether the two iterators point to the same element in the archive or not.
*/
auto operator==( const ConstIterator& other ) const noexcept -> bool;
/**
* @brief Compares the iterator with another iterator.
*
* @param other Another iterator.
*
* @return whether the two iterators point to the different elements in the archive or not.
*/
auto operator!=( const ConstIterator& other ) const noexcept -> bool;
/**
* @brief Accesses the pointed-to element in the archive.
*
* @return a reference to the pointed-to element in the archive.
*/
auto operator*() const noexcept -> reference;
/**
* @brief Accesses the pointed-to element in the archive.
*
* @return a pointer to the pointed-to element in the archive.
*/
auto operator->() const noexcept -> pointer;
private:
BitArchiveItemOffset mItemOffset;
ConstIterator( uint32_t itemIndex, const BitInputArchive& itemArchive ) noexcept;
friend class BitInputArchive;
};
BIT7Z_DEPRECATED_TYPEDEF( const_iterator, ConstIterator, "Use ConstIterator" );
/**
* @return an iterator to the first element of the archive; if the archive is empty,
* the returned iterator will be equal to the end() iterator.
*/
BIT7Z_NODISCARD auto begin() const noexcept -> BitInputArchive::ConstIterator;
/**
* @return an iterator to the element following the last element of the archive;
* this element acts as a placeholder: attempting to access it results in undefined behavior.
*/
BIT7Z_NODISCARD auto end() const noexcept -> BitInputArchive::ConstIterator;
/**
* @return an iterator to the first element of the archive; if the archive is empty,
* the returned iterator will be equal to the end() iterator.
*/
BIT7Z_NODISCARD auto cbegin() const noexcept -> BitInputArchive::ConstIterator;
/**
* @return an iterator to the element following the last element of the archive;
* this element acts as a placeholder: attempting to access it results in undefined behavior.
*/
BIT7Z_NODISCARD auto cend() const noexcept -> BitInputArchive::ConstIterator;
/**
* @brief Find an item in the archive that has the given path.
*
* @param path the path to be searched in the archive.
*
* @return an iterator to the item with the given path, or an iterator equal to the end() iterator
* if no item is found.
*/
BIT7Z_NODISCARD auto find( const tstring& path ) const noexcept -> BitInputArchive::ConstIterator;
/**
* @brief Find if there is an item in the archive that has the given path.
*
* @param path the path to be searched in the archive.
*
* @return true if and only if an item with the given path exists in the archive.
*/
BIT7Z_NODISCARD auto contains( const tstring& path ) const noexcept -> bool;
/**
* @brief Retrieve the item at the given index.
*
* @param index the index of the item to be retrieved.
*
* @return the item at the given index within the archive.
*/
BIT7Z_NODISCARD auto itemAt( uint32_t index ) const -> BitArchiveItemOffset;
};
} // namespace bit7z
#endif //BITINPUTARCHIVE_HPP

View file

@ -0,0 +1,172 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITITEMSVECTOR_HPP
#define BITITEMSVECTOR_HPP
#include <map>
#include <memory>
#include "bitabstractarchivehandler.hpp"
#include "bitfs.hpp"
#include "bittypes.hpp"
namespace bit7z {
using std::vector;
using std::map;
using std::unique_ptr;
namespace filesystem {
class FilesystemItem;
} // namespace filesystem
using filesystem::FilesystemItem;
struct GenericInputItem;
using GenericInputItemPtr = std::unique_ptr< GenericInputItem >;
using GenericInputItemVector = std::vector< GenericInputItemPtr >;
/** @cond **/
struct IndexingOptions {
bool recursive = true;
bool retainFolderStructure = false;
bool onlyFiles = false;
bool followSymlinks = true;
};
/** @endcond **/
/**
* @brief The BitItemsVector class represents a vector of generic input items, i.e., items that can come
* from the filesystem, from memory buffers, or from standard streams.
*/
class BitItemsVector final {
public:
using value_type = GenericInputItemPtr;
BitItemsVector() = default;
BitItemsVector( const BitItemsVector& ) = default;
BitItemsVector( BitItemsVector&& ) = default;
auto operator=( const BitItemsVector& ) -> BitItemsVector& = default;
auto operator=( BitItemsVector&& ) -> BitItemsVector& = default;
/**
* @brief Indexes the given directory, adding to the vector all the files that match the wildcard filter.
*
* @param inDir the directory to be indexed.
* @param filter (optional) the wildcard filter to be used for indexing;
* empty string means "index all files".
* @param policy (optional) the filtering policy to be applied to the matched items.
* @param options (optional) the settings to be used while indexing the given directory
* and all of its subdirectories.
*/
void indexDirectory( const fs::path& inDir,
const tstring& filter = {},
FilterPolicy policy = FilterPolicy::Include,
IndexingOptions options = {} );
/**
* @brief Indexes the given vector of filesystem paths, adding to the item vector all the files.
*
* @param inPaths the vector of filesystem paths.
* @param options (optional) the settings to be used while indexing the given directory
* and all of its subdirectories.
*/
void indexPaths( const std::vector< tstring >& inPaths, IndexingOptions options = {} );
/**
* @brief Indexes the given map of filesystem paths, adding to the vector all the files.
*
* @note Map keys represent the filesystem paths to be indexed; the corresponding mapped values are
* the user-defined (possibly different) paths wanted inside archives.
*
* @param inPaths map of filesystem paths with the corresponding user-defined path desired inside the
* output archive.
* @param options (optional) the settings to be used while indexing the given directory
* and all of its subdirectories.
*/
void indexPathsMap( const std::map< tstring, tstring >& inPaths, IndexingOptions options = {} );
/**
* @brief Indexes the given file path, with an optional user-defined path to be used in output archives.
*
* @note If a directory path is given, a BitException is thrown.
*
* @param inFile the path to the filesystem file to be indexed in the vector.
* @param name (optional) user-defined path to be used inside archives.
* @param followSymlinks (optional) whether to follow symbolic links or not.
*/
void indexFile( const tstring& inFile, const tstring& name = {}, bool followSymlinks = true );
/**
* @brief Indexes the given buffer, using the given name as a path when compressed in archives.
*
* @param inBuffer the buffer containing the file to be indexed in the vector.
* @param name user-defined path to be used inside archives.
*/
void indexBuffer( const std::vector< byte_t >& inBuffer, const tstring& name );
/**
* @brief Indexes the given standard input stream, using the given name as a path when compressed in archives.
*
* @param inStream the standard input stream of the file to be indexed in the vector.
* @param name user-defined path to be used inside archives.
*/
void indexStream( std::istream& inStream, const tstring& name );
/**
* @return the size of the items vector.
*/
BIT7Z_NODISCARD auto size() const -> std::size_t;
/**
* @param index the index of the desired item in the vector.
* @return a constant reference to the GenericInputItem at the given index.
*/
auto operator[]( GenericInputItemVector::size_type index ) const -> const GenericInputItem&;
/**
* @return an iterator to the first element of the vector; if the vector is empty,
* the returned iterator will be equal to the end() iterator.
*/
BIT7Z_NODISCARD auto begin() const noexcept -> GenericInputItemVector::const_iterator;
/**
* @return an iterator to the element following the last element of the vector;
* this element acts as a placeholder: attempting to access it results in undefined behavior.
*/
BIT7Z_NODISCARD auto end() const noexcept -> GenericInputItemVector::const_iterator;
/**
* @return an iterator to the first element of the vector; if the vector is empty,
* the returned iterator will be equal to the end() iterator.
*/
BIT7Z_NODISCARD auto cbegin() const noexcept -> GenericInputItemVector::const_iterator;
/**
* @return an iterator to the element following the last element of the vector;
* this element acts as a placeholder: attempting to access it results in undefined behavior.
*/
BIT7Z_NODISCARD auto cend() const noexcept -> GenericInputItemVector::const_iterator;
~BitItemsVector();
private:
GenericInputItemVector mItems;
void indexItem( const FilesystemItem& item, IndexingOptions options );
};
} // namespace bit7z
#endif //BITITEMSVECTOR_HPP

View file

@ -0,0 +1,27 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITMEMCOMPRESSOR_HPP
#define BITMEMCOMPRESSOR_HPP
#include "bitcompressor.hpp"
namespace bit7z {
/**
* @brief The BitMemCompressor alias allows compressing memory buffers.
* The compressed archives can be saved to the filesystem, standard streams, or memory buffers.
*
* It let decide various properties of the produced archive, such as the password
* protection and the compression level desired.
*/
using BitMemCompressor BIT7Z_MAYBE_UNUSED = BitCompressor< const std::vector< byte_t >& >;
} // namespace bit7z
#endif // BITMEMCOMPRESSOR_HPP

View file

@ -0,0 +1,24 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITMEMEXTRACTOR_HPP
#define BITMEMEXTRACTOR_HPP
#include "bitextractor.hpp"
namespace bit7z {
/**
* @brief The BitMemExtractor alias allows extracting the content of in-memory archives.
*/
using BitMemExtractor BIT7Z_MAYBE_UNUSED = BitExtractor< const std::vector< byte_t >& >;
} // namespace bit7z
#endif // BITMEMEXTRACTOR_HPP

View file

@ -0,0 +1,368 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITOUTPUTARCHIVE_HPP
#define BITOUTPUTARCHIVE_HPP
#include <istream>
#include <set>
#include "bitabstractarchivecreator.hpp"
#include "bititemsvector.hpp"
#include "bitexception.hpp" //for FailedFiles
#include "bitpropvariant.hpp"
//! @cond IGNORE_BLOCK_IN_DOXYGEN
struct ISequentialInStream;
template< typename T >
class CMyComPtr;
//! @endcond
namespace bit7z {
using std::istream;
using DeletedItems = std::set< uint32_t >;
/* General note: I tried my best to explain how indices work here, but it is a bit complex. */
/* We introduce a strong index type to differentiate between indices in the output
* archive (uint32_t, as used by the UpdateCallback), and the corresponding indexes
* in the input archive (InputIndex). In this way, we avoid implicit conversions
* between the two kinds of indices.
*
* UpdateCallback uses indices in the range [0, BitOutputArchive::itemsCount() - 1]
*
* Now, if the user doesn't delete any item in the input archive, itemsCount()
* is just equal to <n° of items in the input archive> + <n° of newly added items>.
* In this case, an InputIndex value is just equal to the index used by UpdateCallback.
*
* On the contrary, if the user wants to delete an item in the input archive, the value
* of an InputIndex may differ from the corresponding UpdateCallback's index.
*
* Note: given an InputIndex i:
* if i < mInputArchiveItemsCount, the item is old (old item in the input archive);
* if i >= mInputArchiveItemsCount, the item is new (added by the user); */
enum class InputIndex : std::uint32_t {};
class UpdateCallback;
/**
* @brief The BitOutputArchive class, given a creator object, allows creating new archives.
*/
class BitOutputArchive {
public:
/**
* @brief Constructs a BitOutputArchive object for a completely new archive.
*
* @param creator the reference to the BitAbstractArchiveCreator object containing all the settings to
* be used for creating the new archive.
*/
explicit BitOutputArchive( const BitAbstractArchiveCreator& creator );
/**
* @brief Constructs a BitOutputArchive object, opening an (optional) input file archive.
*
* If a non-empty input file path is passed, the corresponding archive will be opened and
* used as a base for the creation of the new archive. Otherwise, the class will behave
* as if it is creating a completely new archive.
*
* @param creator the reference to the BitAbstractArchiveCreator object containing all the settings to
* 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,
ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitOutputArchive object, opening an input file archive from the given buffer.
*
* If a non-empty input buffer is passed, the archive file it contains will be opened and
* used as a base for the creation of the new archive. Otherwise, the class will behave
* as if it is creating a completely new archive.
*
* @param creator the reference to the BitAbstractArchiveCreator object containing all the settings to
* 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 buffer_t& inBuffer,
ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitOutputArchive object, reading an input file archive from the given std::istream.
*
* @param creator the reference to the BitAbstractArchiveCreator object containing all the settings to
* 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,
ArchiveStartOffset startOffset = ArchiveStartOffset::None );
BitOutputArchive( const BitOutputArchive& ) = delete;
BitOutputArchive( BitOutputArchive&& ) = delete;
auto operator=( const BitOutputArchive& ) -> BitOutputArchive& = delete;
auto operator=( BitOutputArchive&& ) -> BitOutputArchive& = delete;
/**
* @brief Adds all the items that can be found by indexing the given vector of filesystem paths.
*
* @param inPaths the vector of filesystem paths.
*/
void addItems( const std::vector< tstring >& inPaths );
/**
* @brief Adds all the items that can be found by indexing the keys of the given map of filesystem paths;
* the corresponding mapped values are the user-defined paths wanted inside the output archive.
*
* @param inPaths map of filesystem paths with the corresponding user-defined path desired inside the
* output archive.
*/
void addItems( const std::map< tstring, tstring >& inPaths );
/**
* @brief Adds the given file path, with an optional user-defined path to be used in the output archive.
*
* @note If a directory path is given, a BitException is thrown.
*
* @param inFile the path to the filesystem file to be added to the output archive.
* @param name (optional) user-defined path to be used inside the output archive.
*/
void addFile( const tstring& inFile, const tstring& name = {} );
/**
* @brief Adds the given buffer file, using the given name as a path when compressed in the output archive.
*
* @param inBuffer the buffer containing the file to be added to the output archive.
* @param name user-defined path to be used inside the output archive.
*/
void addFile( const std::vector< byte_t >& inBuffer, const tstring& name );
/**
* @brief Adds the given standard input stream, using the given name as a path when compressed
* in the output archive.
*
* @param inStream the input stream to be added.
* @param name the name of the file inside the output archive.
*/
void addFile( std::istream& inStream, const tstring& name );
/**
* @brief Adds all the files in the given vector of filesystem paths.
*
* @note Paths to directories are ignored.
*
* @param inFiles the vector of paths to files.
*/
void addFiles( const std::vector< tstring >& inFiles );
/**
* @brief Adds all the files inside the given directory path that match the given wildcard filter.
*
* @param inDir the directory where to search for files to be added to the output archive.
* @param filter the wildcard filter to be used for searching the files.
* @param recursive recursively search the files in the given directory and all of its subdirectories.
*/
void addFiles( const tstring& inDir, const tstring& filter, bool recursive );
/**
* @brief Adds all the files inside the given directory path that match the given wildcard filter.
*
* @param inDir the directory where to search for files to be added to the output archive.
* @param filter (optional) the wildcard filter to be used for searching the files.
* @param recursive (optional) recursively search the files in the given directory
* and all of its subdirectories.
* @param policy (optional) the filtering policy to be applied to the matched items.
*/
void addFiles( const tstring& inDir,
const tstring& filter = BIT7Z_STRING( "*" ),
FilterPolicy policy = FilterPolicy::Include,
bool recursive = true );
/**
* @brief Adds the given directory path and all its content.
*
* @param inDir the path of the directory to be added to the archive.
*/
void addDirectory( const tstring& inDir );
/**
* @brief Adds the contents of the given directory path.
*
* This function iterates through the specified directory and adds its contents
* based on the provided wildcard filter. Optionally, the operation can be
* recursive, meaning it will include subdirectories and their contents.
*
* @param inDir the directory where to search for files to be added to the output archive.
* @param filter the wildcard filter to be used for searching the files.
* @param recursive recursively search the files in the given directory and all of its subdirectories.
*/
void addDirectoryContents( const tstring& inDir, const tstring& filter, bool recursive );
/**
* @brief Adds the contents of the given directory path.
*
* This function iterates through the specified directory and adds its contents
* based on the provided wildcard filter and policy. Optionally, the operation can be
* recursive, meaning it will include subdirectories and their contents.
*
* @param inDir the directory where to search for files to be added to the output archive.
* @param filter (optional) the wildcard filter to be used for searching the files.
* @param recursive (optional) recursively search the files in the given directory
* and all of its subdirectories.
* @param policy (optional) the filtering policy to be applied to the matched items.
*/
void addDirectoryContents( const tstring& inDir,
const tstring& filter = BIT7Z_STRING( "*" ),
FilterPolicy policy = FilterPolicy::Include,
bool recursive = true );
/**
* @brief Compresses all the items added to this object to the specified archive file path.
*
* @note If this object was created by passing an input archive file path, and this latter is the same as
* the outFile path parameter, the file will be updated.
*
* @param outFile the output archive file path.
*/
void compressTo( const tstring& outFile );
/**
* @brief Compresses all the items added to this object to the specified buffer.
*
* @param outBuffer the output buffer.
*/
void compressTo( std::vector< byte_t >& outBuffer );
/**
* @brief Compresses all the items added to this object to the specified buffer.
*
* @param outStream the output standard stream.
*/
void compressTo( std::ostream& outStream );
/**
* @return the total number of items added to the output archive object.
*/
auto itemsCount() const -> uint32_t;
/**
* @return a constant reference to the BitAbstractArchiveHandler object containing the
* settings for writing the output archive.
*/
auto handler() const noexcept -> const BitAbstractArchiveHandler&;
/**
* @return a constant reference to the BitAbstractArchiveHandler object containing the
* settings for writing the output archive.
*/
auto creator() const noexcept -> const BitAbstractArchiveCreator&;
/**
* @brief Default destructor.
*/
virtual ~BitOutputArchive() = default;
protected:
virtual auto itemProperty( InputIndex index, BitProperty property ) const -> BitPropVariant;
virtual auto itemStream( InputIndex index, ISequentialInStream** inStream ) const -> HRESULT;
virtual auto hasNewData( uint32_t index ) const noexcept -> bool;
virtual auto hasNewProperties( uint32_t index ) const noexcept -> bool;
auto itemInputIndex( uint32_t newIndex ) const noexcept -> InputIndex;
auto outputItemProperty( uint32_t index, BitProperty property ) const -> BitPropVariant;
auto outputItemStream( uint32_t index, ISequentialInStream** inStream ) const -> HRESULT;
auto indexInArchive( uint32_t index ) const noexcept -> uint32_t;
inline auto inputArchive() const -> BitInputArchive* {
return mInputArchive.get();
}
inline void setInputArchive( std::unique_ptr< BitInputArchive >&& inputArchive ) {
mInputArchive = std::move( inputArchive );
}
inline auto inputArchiveItemsCount() const -> uint32_t {
return mInputArchiveItemsCount;
}
inline void setDeletedIndex( uint32_t index ) {
mDeletedItems.insert( index );
}
inline auto isDeletedIndex( uint32_t index ) const -> bool {
return mDeletedItems.find( index ) != mDeletedItems.cend();
}
inline auto hasDeletedIndexes() const -> bool {
return !mDeletedItems.empty();
}
inline auto hasNewItems() const -> bool {
return mNewItemsVector.size() > 0;
}
friend class UpdateCallback;
private:
const BitAbstractArchiveCreator& mArchiveCreator;
unique_ptr< BitInputArchive > mInputArchive;
uint32_t mInputArchiveItemsCount;
BitItemsVector mNewItemsVector;
DeletedItems mDeletedItems;
mutable FailedFiles mFailedFiles;
/* mInputIndices:
* - Position i = index in range [0, itemsCount() - 1] used by UpdateCallback.
* - Value at position i = corresponding index in the input archive (type InputIndex).
*
* If there are some deleted items, then i != mInputIndices[i]
* (at least for values of i greater than the index of the first deleted item).
*
* Otherwise, if there are no deleted items, the vector is empty, and itemInputIndex(i)
* will return InputIndex with value i.
*
* This vector is either empty, or it has size equal to itemsCount() (thanks to updateInputIndices()). */
std::vector< InputIndex > mInputIndices;
auto initOutArchive() const -> CMyComPtr< IOutArchive >;
auto initOutFileStream( const fs::path& outArchive, bool updatingArchive ) const -> CMyComPtr< IOutStream >;
BitOutputArchive( const BitAbstractArchiveCreator& creator,
const fs::path& inArc,
ArchiveStartOffset archiveStart );
void compressToFile( const fs::path& outFile, UpdateCallback* updateCallback );
void compressOut( IOutArchive* outArc, IOutStream* outStream, UpdateCallback* updateCallback );
void setArchiveProperties( IOutArchive* outArchive ) const;
void updateInputIndices();
};
} // namespace bit7z
#endif //BITOUTPUTARCHIVE_HPP

View file

@ -0,0 +1,461 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITPROPVARIANT_HPP
#define BITPROPVARIANT_HPP
#include <chrono>
#include <cstdint>
#include "bitdefines.hpp"
#include "bittypes.hpp"
#include "bitwindows.hpp"
namespace bit7z {
/**
* @brief A type representing a time point measured using the system clock.
*/
using time_type = std::chrono::time_point< std::chrono::system_clock >;
/**
* @brief The BitProperty enum represents the archive/item properties that 7-zip can read or write.
*/
enum struct BitProperty : PROPID {
NoProperty = 0, ///<
MainSubfile, ///<
HandlerItemIndex, ///<
Path, ///<
Name, ///<
Extension, ///<
IsDir, ///<
Size, ///<
PackSize, ///<
Attrib, ///<
CTime, ///<
ATime, ///<
MTime, ///<
Solid, ///<
Commented, ///<
Encrypted, ///<
SplitBefore, ///<
SplitAfter, ///<
DictionarySize, ///<
CRC, ///<
Type, ///<
IsAnti, ///<
Method, ///<
HostOS, ///<
FileSystem, ///<
User, ///<
Group, ///<
Block, ///<
Comment, ///<
Position, ///<
Prefix, ///<
NumSubDirs, ///<
NumSubFiles, ///<
UnpackVer, ///<
Volume, ///<
IsVolume, ///<
Offset, ///<
Links, ///<
NumBlocks, ///<
NumVolumes, ///<
TimeType, ///<
Bit64, ///<
BigEndian, ///<
Cpu, ///<
PhySize, ///<
HeadersSize, ///<
Checksum, ///<
Characts, ///<
Va, ///<
Id, ///<
ShortName, ///<
CreatorApp, ///<
SectorSize, ///<
PosixAttrib, ///<
SymLink, ///<
Error, ///<
TotalSize, ///<
FreeSpace, ///<
ClusterSize, ///<
VolumeName, ///<
LocalName, ///<
Provider, ///<
NtSecure, ///<
IsAltStream, ///<
IsAux, ///<
IsDeleted, ///<
IsTree, ///<
Sha1, ///<
Sha256, ///<
ErrorType, ///<
NumErrors, ///<
ErrorFlags, ///<
WarningFlags, ///<
Warning, ///<
NumStreams, ///<
NumAltStreams, ///<
AltStreamsSize, ///<
VirtualSize, ///<
UnpackSize, ///<
TotalPhySize, ///<
VolumeIndex, ///<
SubType, ///<
ShortComment, ///<
CodePage, ///<
IsNotArcType, ///<
PhySizeCantBeDetected, ///<
ZerosTailIsAllowed, ///<
TailSize, ///<
EmbeddedStubSize, ///<
NtReparse, ///<
HardLink, ///<
INode, ///<
StreamId, ///<
ReadOnly, ///<
OutName, ///<
CopyLink ///<
};
/**
* @brief The BitPropVariantType enum represents the possible types that a BitPropVariant can store.
*/
enum struct BitPropVariantType : uint32_t {
Empty, ///< Empty BitPropVariant type
Bool, ///< Boolean BitPropVariant type
String, ///< String BitPropVariant type
UInt8, ///< 8-bit unsigned int BitPropVariant type
UInt16, ///< 16-bit unsigned int BitPropVariant type
UInt32, ///< 32-bit unsigned int BitPropVariant type
UInt64, ///< 64-bit unsigned int BitPropVariant type
Int8, ///< 8-bit signed int BitPropVariant type
Int16, ///< 16-bit signed int BitPropVariant type
Int32, ///< 32-bit signed int BitPropVariant type
Int64, ///< 64-bit signed int BitPropVariant type
FileTime ///< FILETIME BitPropVariant type
};
/**
* @brief The BitPropVariant struct is a light extension to the WinAPI PROPVARIANT struct providing useful getters.
*/
struct BitPropVariant final : public PROPVARIANT {
/**
* @brief Constructs an empty BitPropVariant object.
*/
BitPropVariant();
/**
* @brief Copy constructs this BitPropVariant from another one.
*
* @param other the variant to be copied.
*/
BitPropVariant( const BitPropVariant& other );
/**
* @brief Move constructs this BitPropVariant from another one.
*
* @param other the variant to be moved.
*/
BitPropVariant( BitPropVariant&& other ) noexcept;
/**
* @brief Constructs a boolean BitPropVariant
*
* @param value the bool value of the BitPropVariant
*/
explicit BitPropVariant( bool value ) noexcept;
/**
* @brief Constructs a string BitPropVariant from a null-terminated C wide string
*
* @param value the null-terminated C wide string value of the BitPropVariant
*/
explicit BitPropVariant( const wchar_t* value );
/**
* @brief Constructs a string BitPropVariant from a wstring
*
* @param value the wstring value of the BitPropVariant
*/
explicit BitPropVariant( const std::wstring& value );
/**
* @brief Constructs an 8-bit unsigned integer BitPropVariant
*
* @param value the uint8_t value of the BitPropVariant
*/
explicit BitPropVariant( uint8_t value ) noexcept;
/**
* @brief Constructs a 16-bit unsigned integer BitPropVariant
*
* @param value the uint16_t value of the BitPropVariant
*/
explicit BitPropVariant( uint16_t value ) noexcept;
/**
* @brief Constructs a 32-bit unsigned integer BitPropVariant
*
* @param value the uint32_t value of the BitPropVariant
*/
explicit BitPropVariant( uint32_t value ) noexcept;
/**
* @brief Constructs a 64-bit unsigned integer BitPropVariant
*
* @param value the uint64_t value of the BitPropVariant
*/
explicit BitPropVariant( uint64_t value ) noexcept;
/**
* @brief Constructs an 8-bit integer BitPropVariant
*
* @param value the int8_t value of the BitPropVariant
*/
explicit BitPropVariant( int8_t value ) noexcept;
/**
* @brief Constructs a 16-bit integer BitPropVariant
*
* @param value the int16_t value of the BitPropVariant
*/
explicit BitPropVariant( int16_t value ) noexcept;
/**
* @brief Constructs a 32-bit integer BitPropVariant
*
* @param value the int32_t value of the BitPropVariant
*/
explicit BitPropVariant( int32_t value ) noexcept;
/**
* @brief Constructs a 64-bit integer BitPropVariant
*
* @param value the int64_t value of the BitPropVariant
*/
explicit BitPropVariant( int64_t value ) noexcept;
/**
* @brief Constructs a FILETIME BitPropVariant
*
* @param value the FILETIME value of the BitPropVariant
*/
explicit BitPropVariant( FILETIME value ) noexcept;
/**
* @brief BitPropVariant destructor.
*
* @note This is not virtual to maintain the same memory layout of the base struct!
*/
~BitPropVariant();
/**
* @brief Copy assignment operator.
*
* @param other the variant to be copied.
*
* @return a reference to *this object (with the copied values from other).
*/
auto operator=( const BitPropVariant& other ) -> BitPropVariant&;
/**
* @brief Move assignment operator.
*
* @param other the variant to be moved.
*
* @return a reference to *this object (with the moved values from other).
*/
auto operator=( BitPropVariant&& other ) noexcept -> BitPropVariant&;
/**
* @brief Assignment operator
*
* @note this will work only for T types for which a BitPropVariant constructor is defined!
*
* @param value the value to be assigned to the object
*
* @return a reference to *this object having the value as new variant value
*/
template< typename T >
auto operator=( const T& value ) noexcept( std::is_integral< T >::value ) -> BitPropVariant& {
*this = BitPropVariant{ value };
return *this;
}
/**
* @return the boolean value of this variant
* (it throws an exception if the variant is not a boolean value).
*/
BIT7Z_NODISCARD auto getBool() const -> bool;
/**
* @return the string value of this variant
* (it throws an exception if the variant is not a string).
*/
BIT7Z_NODISCARD auto getString() const -> tstring;
/**
* @return the native string value of this variant
* (it throws an exception if the variant is not a string).
*/
BIT7Z_NODISCARD auto getNativeString() const -> native_string;
/**
* @return the 8-bit unsigned integer value of this variant
* (it throws an exception if the variant is not an 8-bit unsigned integer).
*/
BIT7Z_NODISCARD auto getUInt8() const -> uint8_t;
/**
* @return the 16-bit unsigned integer value of this variant
* (it throws an exception if the variant is not an 8 or 16-bit unsigned integer).
*/
BIT7Z_NODISCARD auto getUInt16() const -> uint16_t;
/**
* @return the 32-bit unsigned integer value of this variant
* (it throws an exception if the variant is not an 8, 16 or 32-bit unsigned integer).
*/
BIT7Z_NODISCARD auto getUInt32() const -> uint32_t;
/**
* @return the 64-bit unsigned integer value of this variant
* (it throws an exception if the variant is not an 8, 16, 32 or 64-bit unsigned integer).
*/
BIT7Z_NODISCARD auto getUInt64() const -> uint64_t;
/**
* @return the 8-bit integer value of this variant
* (it throws an exception if the variant is not an 8-bit integer).
*/
BIT7Z_NODISCARD auto getInt8() const -> int8_t;
/**
* @return the 16-bit integer value of this variant
* (it throws an exception if the variant is not an 8 or 16-bit integer).
*/
BIT7Z_NODISCARD auto getInt16() const -> int16_t;
/**
* @return the 32-bit integer value of this variant
* (it throws an exception if the variant is not an 8, 16 or 32-bit integer).
*/
BIT7Z_NODISCARD auto getInt32() const -> int32_t;
/**
* @return the 64-bit integer value of this variant
* (it throws an exception if the variant is not an 8, 16, 32 or 64-bit integer).
*/
BIT7Z_NODISCARD auto getInt64() const -> int64_t;
/**
* @return the FILETIME value of this variant
* (it throws an exception if the variant is not a filetime).
*/
BIT7Z_NODISCARD auto getFileTime() const -> FILETIME;
/**
* @return the FILETIME value of this variant converted to std::time_point
* (it throws an exception if the variant is not a filetime).
*/
BIT7Z_NODISCARD auto getTimePoint() const -> time_type;
/**
* @return the value of this variant converted from any supported type to std::wstring.
*/
BIT7Z_NODISCARD auto toString() const -> tstring;
/**
* @return a boolean value indicating whether the variant is empty.
*/
BIT7Z_NODISCARD auto isEmpty() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is a boolean value.
*/
BIT7Z_NODISCARD auto isBool() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is a string.
*/
BIT7Z_NODISCARD auto isString() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8-bit unsigned integer.
*/
BIT7Z_NODISCARD auto isUInt8() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8 or 16-bit unsigned integer.
*/
BIT7Z_NODISCARD auto isUInt16() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8, 16 or 32-bit unsigned integer.
*/
BIT7Z_NODISCARD auto isUInt32() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8, 16, 32 or 64-bit unsigned integer.
*/
BIT7Z_NODISCARD auto isUInt64() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8-bit integer.
*/
BIT7Z_NODISCARD auto isInt8() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8 or 16-bit integer.
*/
BIT7Z_NODISCARD auto isInt16() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8, 16 or 32-bit integer.
*/
BIT7Z_NODISCARD auto isInt32() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8, 16, 32 or 64-bit integer.
*/
BIT7Z_NODISCARD auto isInt64() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is a FILETIME structure.
*/
BIT7Z_NODISCARD auto isFileTime() const noexcept -> bool;
/**
* @return the BitPropVariantType of this variant.
*/
BIT7Z_NODISCARD auto type() const -> BitPropVariantType;
/**
* @brief Clears the current value of the variant object
*/
void clear() noexcept;
private:
void internalClear() noexcept;
friend auto operator==( const BitPropVariant& lhs, const BitPropVariant& rhs ) noexcept -> bool;
friend auto operator!=( const BitPropVariant& lhs, const BitPropVariant& rhs ) noexcept -> bool;
};
auto operator==( const BitPropVariant& lhs, const BitPropVariant& rhs ) noexcept -> bool;
auto operator!=( const BitPropVariant& lhs, const BitPropVariant& rhs ) noexcept -> bool;
} // namespace bit7z
#endif // BITPROPVARIANT_HPP

View file

@ -0,0 +1,28 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITSTREAMCOMPRESSOR_HPP
#define BITSTREAMCOMPRESSOR_HPP
#include "bitcompressor.hpp"
namespace bit7z {
/**
* @brief The BitStreamCompressor alias allows compressing data from standard input streams.
* The compressed archives can be saved to the filesystem, standard streams, or memory buffers.
*
* It let decide various properties of the produced archive, such as the password
* protection and the compression level desired.
*/
using BitStreamCompressor BIT7Z_MAYBE_UNUSED = BitCompressor< std::istream& >;
} // namespace bit7z
#endif // BITSTREAMCOMPRESSOR_HPP

View file

@ -0,0 +1,24 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITSTREAMEXTRACTOR_HPP
#define BITSTREAMEXTRACTOR_HPP
#include "bitextractor.hpp"
namespace bit7z {
/**
* @brief The BitStreamExtractor alias allows extracting the content of in-memory archives.
*/
using BitStreamExtractor BIT7Z_MAYBE_UNUSED = BitExtractor< std::istream& >;
} // namespace bit7z
#endif // BITSTREAMEXTRACTOR_HPP

View file

@ -0,0 +1,130 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITTYPES_HPP
#define BITTYPES_HPP
#include <string>
#include <vector>
// Must be included here since the user might have manually enabled a BIT7Z_* compilation option
// by uncommenting the corresponding macro define in bitdefines.hpp.
#include "bitdefines.hpp"
#ifdef BIT7Z_REGEX_MATCHING
#include <regex>
#endif
namespace bit7z {
/**
* @brief A type representing a byte.
*/
#ifdef BIT7Z_USE_STD_BYTE
#if __cpp_lib_byte
using byte_t = std::byte;
#else
enum class byte_t : unsigned char {}; //same as std::byte_t
#endif
#else
using byte_t = unsigned char;
#endif
/** @cond */
using buffer_t = std::vector< byte_t >;
using index_t = std::ptrdiff_t; //like gsl::index (https://github.com/microsoft/GSL)
template< class Char >
struct StringTraits;
template<>
struct StringTraits< char > {
template< class T >
static inline auto convertToString( T value ) -> std::string {
return std::to_string( value );
}
};
template<>
struct StringTraits< wchar_t > {
template< class T >
static inline auto convertToString( T value ) -> std::wstring {
return std::to_wstring( value );
}
};
/** @endcond */
/**
* Native string type of the system.
* @note On Windows, it is an alias of `std::wstring`.
*/
#ifdef _WIN32
using native_string = std::wstring;
#define BIT7Z_NATIVE_STRING_( str ) L##str
#define BIT7Z_NATIVE_STRING( str ) BIT7Z_NATIVE_STRING_( str )
#else
using native_string = std::string;
#define BIT7Z_NATIVE_STRING( str ) str
#endif
using native_char = native_string::value_type;
/**
* @note On Windows, if the `BIT7Z_USE_NATIVE_STRING` option is enabled, `tchar` is an alias of `wchar_t`.
*/
#if defined( BIT7Z_USE_NATIVE_STRING ) && defined( _WIN32 ) // Windows with native strings
using tchar = wchar_t;
#define BIT7Z_STRING( str ) BIT7Z_NATIVE_STRING_( str )
#else // Unix, and Windows with non-native strings
using tchar = char;
#define BIT7Z_STRING( str ) str
#endif
/**
* @note On Windows, if the `BIT7Z_USE_NATIVE_STRING` option is enabled, `tstring` is an alias for std::wstring.
* Otherwise, it is an alias for std::string (default).
*/
using tstring = std::basic_string< tchar >;
#ifdef BIT7Z_REGEX_MATCHING
/**
* @note On Windows, if the `BIT7Z_USE_NATIVE_STRING` option is enabled, `tregex` is an alias for std::wregex.
* Otherwise, it is an alias for std::regex (default).
*/
using tregex = std::basic_regex< tchar >;
#endif
template< typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type >
inline auto to_tstring( T arg ) -> std::basic_string< tchar > {
return StringTraits< tchar >::convertToString( arg );
}
/**
* Converts a native string to a tstring.
*
* @note On Linux or on Windows when BIT7Z_USE_NATIVE_STRING is used,
* both native_string and tstring are aliases of the same string type;
* in this case, no conversion is performed, and a const reference to the original string is returned.
*
* @param str The native string to be converted.
*
* @return the converted tstring.
*/
#if defined( _WIN32 ) && !defined( BIT7Z_USE_NATIVE_STRING )
auto to_tstring( const native_string& str ) -> tstring;
#else
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

View file

@ -0,0 +1,159 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITWINDOWS_HPP
#define BITWINDOWS_HPP
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#include <propidl.h>
#else
/* We don't have the "Windows.h" header on Unix systems, so in theory, we could use the "MyWindows.h" of p7zip/7-zip.
* However, some of bit7z's public API headers need some Win32 API structs like PROPVARIANT and GUID.
* Hence, it would result in the leak of p7zip/7-zip headers, making bit7z's clients dependent on them.
* Also, (publicly) forward declaring them and then (internally) using the "MyWindows.h" is impossible:
* the two different declarations would conflict, making the compilation fail.
*
* To avoid all these issues, we define the required Win32 API structs, constants, and type aliases,
* with the same definitions in the MyWindows.h header.
* We will use only this header and avoid including "MyWindows.h" or similar headers (e.g., StdAfx.h). */
#include <cerrno>
#include <cstdint>
#include <cstddef>
// Avoiding accidentally including p7zip's MyWindows.h, so that its inclusion is not needed in client code!
#ifndef __MYWINDOWS_H
#define __MYWINDOWS_H // NOLINT
#endif
// Avoiding accidentally including 7-zip's MyWindows.h, so that its inclusion is not needed in client code!
#ifndef __MY_WINDOWS_H
#define __MY_WINDOWS_H // NOLINT
#endif
// Avoiding accidentally including 7-zip's MyWindows.h, so that its inclusion is not needed in client code!
#ifndef ZIP7_INC_MY_WINDOWS_H // 7-zip 23.01+
#define ZIP7_INC_MY_WINDOWS_H
#endif
using std::size_t;
#define WINAPI
namespace bit7z {
// Win32 type aliases
using FARPROC = void*;
using HMODULE = void*;
using HRESULT = int;
using OLECHAR = wchar_t;
using BSTR = OLECHAR*;
using VARIANT_BOOL = short;
using VARTYPE = unsigned short;
using WORD = unsigned short;
using DWORD = unsigned int;
using ULONG = unsigned int;
using PROPID = ULONG;
// Error codes constants can be useful for bit7z's clients on Unix (since they don't have the Windows.h header).
#ifndef S_OK // Silencing cppcheck warning on E_NOTIMPL, probably a bug of cppcheck.
// Win32 HRESULT error codes.
constexpr auto S_OK = static_cast< HRESULT >( 0x00000000L );
constexpr auto S_FALSE = static_cast< HRESULT >( 0x00000001L );
constexpr auto E_NOTIMPL = static_cast< HRESULT >( 0x80004001L );
constexpr auto E_NOINTERFACE = static_cast< HRESULT >( 0x80004002L );
constexpr auto E_ABORT = static_cast< HRESULT >( 0x80004004L );
constexpr auto E_FAIL = static_cast< HRESULT >( 0x80004005L );
constexpr auto STG_E_INVALIDFUNCTION = static_cast< HRESULT >( 0x80030001L );
constexpr auto E_OUTOFMEMORY = static_cast< HRESULT >( 0x8007000EL );
constexpr auto E_INVALIDARG = static_cast< HRESULT >( 0x80070057L );
#endif
#ifndef ERROR_ALREADY_EXISTS
// Win32 error codes (defined by both p7zip and 7-zip as equivalent to POSIX error codes).
constexpr auto ERROR_ALREADY_EXISTS = EEXIST;
constexpr auto ERROR_DISK_FULL = ENOSPC;
constexpr auto ERROR_FILE_EXISTS = EEXIST;
constexpr auto ERROR_FILE_NOT_FOUND = ENOENT;
constexpr auto ERROR_INVALID_PARAMETER = EINVAL;
constexpr auto ERROR_INVALID_FUNCTION = EINVAL;
constexpr auto ERROR_INVALID_HANDLE = EBADF;
constexpr auto ERROR_OPEN_FAILED = EIO;
constexpr auto ERROR_PATH_NOT_FOUND = ENOENT;
constexpr auto ERROR_SEEK = EIO;
constexpr auto ERROR_READ_FAULT = EIO;
constexpr auto ERROR_WRITE_FAULT = EIO;
// Win32 error codes (defined by p7zip with the same values as in Windows API).
constexpr auto ERROR_NO_MORE_FILES = 0x100018;
constexpr auto ERROR_DIRECTORY = 267;
#endif
#ifndef CP_UTF8
// Win32 codepages
constexpr auto CP_UTF8 = 65001u;
#endif
// Win32 structs.
struct FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
};
struct LARGE_INTEGER {
int64_t QuadPart;
};
struct ULARGE_INTEGER {
uint64_t QuadPart;
};
struct PROPVARIANT {
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union {
#if defined( __arm__ ) || defined( __aarch64__ )
signed char cVal;
#else
char cVal;
#endif
unsigned char bVal;
short iVal;
unsigned short uiVal;
int lVal;
unsigned int ulVal;
int intVal;
unsigned int uintVal;
LARGE_INTEGER hVal;
ULARGE_INTEGER uhVal;
VARIANT_BOOL boolVal;
int scode;
FILETIME filetime;
BSTR bstrVal;
};
};
} // namespace bit7z
#endif
#endif //BITWINDOWS_HPP

View file

@ -3650,6 +3650,11 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
</ProjectReference>
</ItemDefinitionGroup>
<ItemGroup>
<Library Include="..\Windows64Media\7z.dll">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
<FileType>Document</FileType>
</Library>
<None Include="ClassDiagram.cd" />
<Xml Include="Durango\manifest.xml">
<FileType>XML</FileType>
@ -5822,6 +5827,39 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|ARM64EC'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Win32'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bit7z.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bit7zlibrary.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitabstractarchivecreator.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitabstractarchivehandler.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitabstractarchiveopener.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchiveeditor.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchiveitem.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchiveiteminfo.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchiveitemoffset.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchivereader.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchivewriter.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitcompressionlevel.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitcompressionmethod.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitcompressor.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitdefines.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\biterror.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitexception.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitextractor.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitfilecompressor.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitfileextractor.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitformat.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitfs.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitgenericitem.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitinputarchive.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bititemsvector.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitmemcompressor.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitmemextractor.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitoutputarchive.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitpropvariant.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitstreamcompressor.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitstreamextractor.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bittypes.hpp" />
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitwindows.hpp" />
<ClInclude Include="Common\Network\GameNetworkManager.h" />
<ClInclude Include="Common\Network\NetworkPlayerInterface.h" />
<ClInclude Include="Common\Network\PlatformNetworkManagerInterface.h" />
@ -43593,6 +43631,12 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
<ClCompile Include="ZombieRenderer.cpp" />
</ItemGroup>
<ItemGroup>
<Library Include="Common\libs\bit7z\lib\x64\Debug\bit7z.lib">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
</Library>
<Library Include="Common\libs\bit7z\lib\x64\Release\bit7z.lib">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
</Library>
<Library Include="Durango\4JLibs\libs\4J_Input.lib">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64EC'">true</ExcludedFromBuild>
@ -48710,9 +48754,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
<IsWinMDFile>true</IsWinMDFile>
</Reference>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Durango\Autogenerated.appxmanifest" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />

View file

@ -732,6 +732,24 @@
<Filter Include="Common\Source Files\Filesystem">
<UniqueIdentifier>{c79fd64d-7529-4da4-b5f3-2541e084932b}</UniqueIdentifier>
</Filter>
<Filter Include="Common\Source Files\libs">
<UniqueIdentifier>{280237d6-cf3a-418c-990d-30c98fe24dae}</UniqueIdentifier>
</Filter>
<Filter Include="Common\Source Files\libs\bit7z">
<UniqueIdentifier>{c05c44be-8378-4b7a-b3b6-25980dd2e212}</UniqueIdentifier>
</Filter>
<Filter Include="Common\Source Files\libs\bit7z\lib">
<UniqueIdentifier>{d47a8022-a3e9-4ce4-8176-4779d6e9512d}</UniqueIdentifier>
</Filter>
<Filter Include="Common\Source Files\libs\bit7z\include">
<UniqueIdentifier>{4ed3fe84-3f44-4ec9-97f4-258c9b41fab7}</UniqueIdentifier>
</Filter>
<Filter Include="Common\Source Files\libs\bit7z\lib\Debug">
<UniqueIdentifier>{3c65b1f9-fa53-4956-9e9f-f43bd0ba8a6d}</UniqueIdentifier>
</Filter>
<Filter Include="Common\Source Files\libs\bit7z\lib\Release">
<UniqueIdentifier>{66652ea1-d6b0-403d-800b-0609c3691785}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
@ -3790,6 +3808,105 @@
<ClInclude Include="Common\Audio\stb_vorbis.h">
<Filter>Common\Source Files\Audio</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bit7z.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bit7zlibrary.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitabstractarchivecreator.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitabstractarchivehandler.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitabstractarchiveopener.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchiveeditor.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchiveitem.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchiveiteminfo.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchiveitemoffset.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchivereader.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitarchivewriter.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitcompressionlevel.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitcompressionmethod.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitcompressor.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitdefines.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\biterror.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitexception.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitextractor.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitfilecompressor.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitfileextractor.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitformat.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitfs.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitgenericitem.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitinputarchive.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bititemsvector.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitmemcompressor.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitmemextractor.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitoutputarchive.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitpropvariant.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitstreamcompressor.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitstreamextractor.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bittypes.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
<ClInclude Include="Common\libs\bit7z\include\bit7z\bitwindows.hpp">
<Filter>Common\Source Files\libs\bit7z\include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -6176,6 +6293,13 @@
<Library Include="Xbox\4JLibs\libs\4J_XTMS_r.lib">
<Filter>Xbox\4JLibs\libs</Filter>
</Library>
<Library Include="Common\libs\bit7z\lib\x64\Debug\bit7z.lib">
<Filter>Common\Source Files\libs\bit7z\lib\Debug</Filter>
</Library>
<Library Include="Common\libs\bit7z\lib\x64\Release\bit7z.lib">
<Filter>Common\Source Files\libs\bit7z\lib\Release</Filter>
</Library>
<Library Include="..\Windows64Media\7z.dll" />
<!-- <Library Include="PSVita\4JLibs\libs\libSceNpToolkit_rtti.a">
<Filter>PSVita\4JLibs\libs</Filter>
</Library>
@ -6310,7 +6434,4 @@
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Durango\Autogenerated.appxmanifest" />
</ItemGroup>
</Project>

Binary file not shown.