Skip to content

Commit

Permalink
Improve handling of paths in internal code
Browse files Browse the repository at this point in the history
  • Loading branch information
rikyoz committed Jan 7, 2023
1 parent 50b3cae commit 13fb363
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 55 deletions.
4 changes: 2 additions & 2 deletions include/bit7z/bitoutputarchive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
48 changes: 25 additions & 23 deletions src/bitoutputarchive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand All @@ -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 );
Expand All @@ -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() );
}
}
}
Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
22 changes: 14 additions & 8 deletions src/internal/cfileoutstream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,35 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

#include <utility>

#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();
}

Expand All @@ -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;
}
}

const fs::path& CFileOutStream::path() const {
return mFilePath;
}
6 changes: 4 additions & 2 deletions src/internal/cfileoutstream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );

Expand Down
13 changes: 8 additions & 5 deletions src/internal/cmultivolumeoutstream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

#include <utility>

#include "internal/cmultivolumeoutstream.hpp"

#include "bitexception.hpp"
#include "internal/util.hpp"

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 ),
Expand All @@ -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();
}
Expand All @@ -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;
}

Expand Down
6 changes: 3 additions & 3 deletions src/internal/cmultivolumeoutstream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ 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;

// 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).
Expand All @@ -48,7 +48,7 @@ class CMultiVolumeOutStream final : public IOutStream, public CMyUnknownImp {
vector <CMyComPtr< CVolumeOutStream >> mVolumes;

public:
CMultiVolumeOutStream( uint64_t volSize, const tstring& archiveName );
CMultiVolumeOutStream( uint64_t volSize, fs::path archiveName );

CMultiVolumeOutStream( const CMultiVolumeOutStream& ) = delete;

Expand Down
9 changes: 2 additions & 7 deletions src/internal/cvolumeoutstream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand Down Expand Up @@ -63,7 +62,3 @@ uint64_t CVolumeOutStream::currentSize() const {
void CVolumeOutStream::setCurrentSize( uint64_t currentSize ) {
mCurrentSize = currentSize;
}

fs::path CVolumeOutStream::path() const {
return mPath;
}
6 changes: 1 addition & 5 deletions src/internal/cvolumeoutstream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -34,8 +32,6 @@ class CVolumeOutStream final : public CFileOutStream {
BIT7Z_STDMETHOD( SetSize, UInt64 newSize );

private:
fs::path mPath;

uint64_t mCurrentOffset;

uint64_t mCurrentSize;
Expand Down

0 comments on commit 13fb363

Please sign in to comment.