mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-05-01 11:30:57 +00:00
369 lines
16 KiB
C++
369 lines
16 KiB
C++
/*
|
|
* 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
|