From 13fb363716db67e078458d1cef7892155bb6432b Mon Sep 17 00:00:00 2001 From: Oz Date: Sat, 7 Jan 2023 11:19:00 +0100 Subject: [PATCH] Improve handling of paths in internal code --- include/bit7z/bitoutputarchive.hpp | 4 +-- src/bitoutputarchive.cpp | 48 ++++++++++++++------------ src/internal/cfileoutstream.cpp | 22 +++++++----- src/internal/cfileoutstream.hpp | 6 ++-- src/internal/cmultivolumeoutstream.cpp | 13 ++++--- src/internal/cmultivolumeoutstream.hpp | 6 ++-- src/internal/cvolumeoutstream.cpp | 9 ++--- src/internal/cvolumeoutstream.hpp | 6 +--- 8 files changed, 59 insertions(+), 55 deletions(-) diff --git a/include/bit7z/bitoutputarchive.hpp b/include/bit7z/bitoutputarchive.hpp index a1ae8a6b..089961d4 100644 --- a/include/bit7z/bitoutputarchive.hpp +++ b/include/bit7z/bitoutputarchive.hpp @@ -281,9 +281,9 @@ class BitOutputArchive { CMyComPtr< IOutArchive > initOutArchive() const; - CMyComPtr< IOutStream > initOutFileStream( const tstring& out_archive, bool updating_archive ) const; + CMyComPtr< IOutStream > initOutFileStream( const fs::path& out_archive, bool updating_archive ) const; - void compressToFile( const tstring& out_file, UpdateCallback* update_callback ); + void compressToFile( const fs::path& out_file, UpdateCallback* update_callback ); void compressOut( IOutArchive* out_arc, IOutStream* out_stream, diff --git a/src/bitoutputarchive.cpp b/src/bitoutputarchive.cpp index 4cf8f005..0f8529be 100644 --- a/src/bitoutputarchive.cpp +++ b/src/bitoutputarchive.cpp @@ -113,24 +113,6 @@ void BitOutputArchive::addDirectory( const tstring& in_dir ) { mNewItemsVector.indexDirectory( in_dir, BIT7Z_STRING( "" ), options ); } -void BitOutputArchive::compressTo( const tstring& out_file ) { - std::error_code error; - if ( fs::exists( out_file, error ) ) { - const OverwriteMode overwrite_mode = mArchiveCreator.overwriteMode(); - if ( overwrite_mode == OverwriteMode::Skip ) { // Skipping if the output file already exists - return; - } - if ( overwrite_mode == OverwriteMode::Overwrite && !fs::remove( out_file, error ) ) { - throw BitException( "Failed to delete the old archive file", error, out_file ); - } - // Note: if overwrite_mode is OverwriteMode::None, an exception will be thrown by the CFileOutStream constructor - // called by the initOutFileStream function. - } - - auto update_callback = bit7z::make_com< UpdateCallback >( *this ); - compressToFile( out_file, update_callback ); -} - CMyComPtr< IOutArchive > BitOutputArchive::initOutArchive() const { CMyComPtr< IOutArchive > new_arc; if ( mInputArchive == nullptr ) { @@ -144,7 +126,7 @@ CMyComPtr< IOutArchive > BitOutputArchive::initOutArchive() const { return new_arc; } -CMyComPtr< IOutStream > BitOutputArchive::initOutFileStream( const tstring& out_archive, +CMyComPtr< IOutStream > BitOutputArchive::initOutFileStream( const fs::path& out_archive, bool updating_archive ) const { if ( mArchiveCreator.volumeSize() > 0 ) { return bit7z::make_com< CMultiVolumeOutStream, IOutStream >( mArchiveCreator.volumeSize(), out_archive ); @@ -165,7 +147,7 @@ void BitOutputArchive::compressOut( IOutArchive* out_arc, for ( const auto& new_item : mNewItemsVector ) { auto updated_item = mInputArchive->find( new_item->inArchivePath().string< tchar >() ); if ( updated_item != mInputArchive->cend() ) { - mDeletedItems.insert( updated_item->index() ); + setDeletedIndex( updated_item->index() ); } } } @@ -182,7 +164,7 @@ void BitOutputArchive::compressOut( IOutArchive* out_arc, } } -void BitOutputArchive::compressToFile( const tstring& out_file, UpdateCallback* update_callback ) { +void BitOutputArchive::compressToFile( const fs::path& out_file, UpdateCallback* update_callback ) { // Note: if mInputArchive != nullptr, new_arc will actually point to the same IInArchive object used by the old_arc // (see initUpdatableArchive function of BitInputArchive)! const bool updating_archive = mInputArchive != nullptr && mInputArchive->archivePath() == out_file; @@ -213,13 +195,33 @@ void BitOutputArchive::compressToFile( const tstring& out_file, UpdateCallback* //remove the old file and rename the temporary file (move file with overwriting) std::error_code error; - fs::rename( out_file + BIT7Z_STRING( ".tmp" ), out_file, error ); + fs::path tmp_file = out_file; + tmp_file += ".tmp"; + fs::rename( tmp_file, out_file, error ); if ( error ) { - throw BitException( "Failed to overwrite the old archive file", error, out_file ); + throw BitException( "Failed to overwrite the old archive file", error, out_file.string< tchar >() ); } } } +void BitOutputArchive::compressTo( const tstring& out_file ) { + std::error_code error; + if ( fs::exists( out_file, error ) ) { + const OverwriteMode overwrite_mode = mArchiveCreator.overwriteMode(); + if ( overwrite_mode == OverwriteMode::Skip ) { // Skipping if the output file already exists + return; + } + if ( overwrite_mode == OverwriteMode::Overwrite && !fs::remove( out_file, error ) ) { + throw BitException( "Failed to delete the old archive file", error, out_file ); + } + // Note: if overwrite_mode is OverwriteMode::None, an exception will be thrown by the CFileOutStream constructor + // called by the initOutFileStream function. + } + + auto update_callback = bit7z::make_com< UpdateCallback >( *this ); + compressToFile( out_file, update_callback ); +} + void BitOutputArchive::compressTo( std::vector< byte_t >& out_buffer ) { if ( !out_buffer.empty() ) { const OverwriteMode overwrite_mode = mArchiveCreator.overwriteMode(); diff --git a/src/internal/cfileoutstream.cpp b/src/internal/cfileoutstream.cpp index 684397a4..72aaa237 100644 --- a/src/internal/cfileoutstream.cpp +++ b/src/internal/cfileoutstream.cpp @@ -10,33 +10,35 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +#include + #include "internal/cfileoutstream.hpp" #include "bitexception.hpp" using namespace bit7z; -CFileOutStream::CFileOutStream( const fs::path& filePath, bool createAlways ) - : CStdOutStream( mFileStream ), mFilePath{ filePath }, mBuffer{} { +CFileOutStream::CFileOutStream( fs::path filePath, bool createAlways ) + : CStdOutStream( mFileStream ), mFilePath{ std::move( filePath ) }, mBuffer{} { std::error_code error; - if ( !createAlways && fs::exists( filePath, error ) ) { + if ( !createAlways && fs::exists( mFilePath, error ) ) { if ( !error ) { // the call to fs::exists succeeded, but the filePath exists, and this is an error! error = std::make_error_code( std::errc::file_exists ); } - throw BitException( "Failed to create the output file", error, filePath.string< tchar >() ); + throw BitException( "Failed to create the output file", error, mFilePath.string< tchar >() ); } - mFileStream.open( filePath, std::ios::binary | std::ios::trunc ); + mFileStream.open( mFilePath, std::ios::binary | std::ios::trunc ); if ( mFileStream.fail() ) { throw BitException( "Failed to open the output file", make_hresult_code( HRESULT_FROM_WIN32( ERROR_OPEN_FAILED ) ), - filePath.string< tchar >() ); + mFilePath.string< tchar >() ); } mFileStream.rdbuf()->pubsetbuf( mBuffer.data(), buffer_size ); } -bool CFileOutStream::fail() { +bool CFileOutStream::fail() const { return mFileStream.fail(); } @@ -45,4 +47,8 @@ STDMETHODIMP CFileOutStream::SetSize( UInt64 newSize ) { std::error_code error; fs::resize_file( mFilePath, newSize, error ); return error ? E_FAIL : S_OK; -} \ No newline at end of file +} + +const fs::path& CFileOutStream::path() const { + return mFilePath; +} diff --git a/src/internal/cfileoutstream.hpp b/src/internal/cfileoutstream.hpp index 9de4fb14..3fdb7189 100644 --- a/src/internal/cfileoutstream.hpp +++ b/src/internal/cfileoutstream.hpp @@ -20,9 +20,11 @@ namespace bit7z { class CFileOutStream : public CStdOutStream { public: - explicit CFileOutStream( const fs::path& filePath, bool createAlways = false ); + explicit CFileOutStream( fs::path filePath, bool createAlways = false ); - BIT7Z_NODISCARD bool fail(); + BIT7Z_NODISCARD const fs::path& path() const; + + BIT7Z_NODISCARD bool fail() const; BIT7Z_STDMETHOD( SetSize, UInt64 newSize ); diff --git a/src/internal/cmultivolumeoutstream.cpp b/src/internal/cmultivolumeoutstream.cpp index 2fa69d10..942c27c8 100644 --- a/src/internal/cmultivolumeoutstream.cpp +++ b/src/internal/cmultivolumeoutstream.cpp @@ -10,6 +10,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +#include + #include "internal/cmultivolumeoutstream.hpp" #include "bitexception.hpp" @@ -17,9 +19,9 @@ using namespace bit7z; -CMultiVolumeOutStream::CMultiVolumeOutStream( uint64_t volSize, const tstring& archiveName ) +CMultiVolumeOutStream::CMultiVolumeOutStream( uint64_t volSize, fs::path archiveName ) : mMaxVolumeSize( volSize ), - mVolumePrefix( archiveName + BIT7Z_STRING( "." ) ), + mVolumePrefix( std::move( archiveName ) ), mCurrentVolumeIndex( 0 ), mCurrentVolumeOffset( 0 ), mAbsoluteOffset( 0 ), @@ -40,10 +42,11 @@ STDMETHODIMP CMultiVolumeOutStream::Write( const void* data, UInt32 size, UInt32 /* The current volume stream still doesn't exist, so we need to create it. */ tstring name = to_tstring( static_cast< uint64_t >( mCurrentVolumeIndex ) + 1 ); name.insert( 0, 3 - name.length(), L'0' ); - name.insert( 0, mVolumePrefix ); + fs::path volume_path = mVolumePrefix; + volume_path += BIT7Z_STRING( "." ) + name; try { - mVolumes.emplace_back( make_com< CVolumeOutStream >( name ) ); + mVolumes.emplace_back( make_com< CVolumeOutStream >( volume_path ) ); } catch ( const BitException& ex ) { return ex.nativeCode(); } @@ -70,7 +73,7 @@ STDMETHODIMP CMultiVolumeOutStream::Write( const void* data, UInt32 size, UInt32 mAbsoluteOffset += writtenSize; if ( mAbsoluteOffset > mFullSize ) { - /* We wrote beyond the old known full size of output archive, updating it. */ + /* We wrote beyond the old known full size of the output archive, updating it. */ mFullSize = mAbsoluteOffset; } diff --git a/src/internal/cmultivolumeoutstream.hpp b/src/internal/cmultivolumeoutstream.hpp index dae72a5f..b89e406f 100644 --- a/src/internal/cmultivolumeoutstream.hpp +++ b/src/internal/cmultivolumeoutstream.hpp @@ -31,7 +31,7 @@ class CMultiVolumeOutStream final : public IOutStream, public CMyUnknownImp { uint64_t mMaxVolumeSize; // Common name prefix of every volume. - tstring mVolumePrefix; + fs::path mVolumePrefix; // The current volume stream on which we are working. size_t mCurrentVolumeIndex; @@ -39,7 +39,7 @@ class CMultiVolumeOutStream final : public IOutStream, public CMyUnknownImp { // Offset from the beginning of the current volume stream (i.e., the one at mCurrentVolumeIndex). uint64_t mCurrentVolumeOffset; - // Offset from the beginning of the full output archive. + // Offset from the beginning of the whole output archive. uint64_t mAbsoluteOffset; // Total size of the output archive (sum of the volumes' sizes). @@ -48,7 +48,7 @@ class CMultiVolumeOutStream final : public IOutStream, public CMyUnknownImp { vector > mVolumes; public: - CMultiVolumeOutStream( uint64_t volSize, const tstring& archiveName ); + CMultiVolumeOutStream( uint64_t volSize, fs::path archiveName ); CMultiVolumeOutStream( const CMultiVolumeOutStream& ) = delete; diff --git a/src/internal/cvolumeoutstream.cpp b/src/internal/cvolumeoutstream.cpp index d70d45d2..0789140d 100644 --- a/src/internal/cvolumeoutstream.cpp +++ b/src/internal/cvolumeoutstream.cpp @@ -12,11 +12,10 @@ #include "internal/cvolumeoutstream.hpp" -using bit7z::tstring; using bit7z::CVolumeOutStream; -CVolumeOutStream::CVolumeOutStream( const tstring& volumeName ) - : CFileOutStream( volumeName ), mPath{ volumeName }, mCurrentOffset{ 0 }, mCurrentSize{ 0 } {} +CVolumeOutStream::CVolumeOutStream( const fs::path& volumeName ) + : CFileOutStream( volumeName ), mCurrentOffset{ 0 }, mCurrentSize{ 0 } {} COM_DECLSPEC_NOTHROW STDMETHODIMP CVolumeOutStream::Seek( Int64 offset, UInt32 seekOrigin, UInt64* newPosition ) { @@ -63,7 +62,3 @@ uint64_t CVolumeOutStream::currentSize() const { void CVolumeOutStream::setCurrentSize( uint64_t currentSize ) { mCurrentSize = currentSize; } - -fs::path CVolumeOutStream::path() const { - return mPath; -} diff --git a/src/internal/cvolumeoutstream.hpp b/src/internal/cvolumeoutstream.hpp index 06a44c74..5434e00d 100644 --- a/src/internal/cvolumeoutstream.hpp +++ b/src/internal/cvolumeoutstream.hpp @@ -16,9 +16,7 @@ namespace bit7z { class CVolumeOutStream final : public CFileOutStream { public: - explicit CVolumeOutStream( const tstring& volumeName ); - - BIT7Z_NODISCARD fs::path path() const; + explicit CVolumeOutStream( const fs::path& volumeName ); BIT7Z_NODISCARD uint64_t currentOffset() const; @@ -34,8 +32,6 @@ class CVolumeOutStream final : public CFileOutStream { BIT7Z_STDMETHOD( SetSize, UInt64 newSize ); private: - fs::path mPath; - uint64_t mCurrentOffset; uint64_t mCurrentSize;