Skip to content

Commit

Permalink
Add basic support to renaming of archived items (BitArchiveEditor)
Browse files Browse the repository at this point in the history
Lots of refactoring of the internal classes are still needed.
Close issue #43.
  • Loading branch information
rikyoz committed Jan 3, 2021
1 parent 9a31c91 commit 51d229e
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ set( HEADERS
${PROJECT_SOURCE_DIR}/include/bit7z.hpp
${PROJECT_SOURCE_DIR}/include/bit7zlibrary.hpp
${PROJECT_SOURCE_DIR}/include/bitarchivecreator.hpp
${PROJECT_SOURCE_DIR}/include/bitarchiveeditor.hpp
${PROJECT_SOURCE_DIR}/include/bitarchivehandler.hpp
${PROJECT_SOURCE_DIR}/include/bitarchiveinfo.hpp
${PROJECT_SOURCE_DIR}/include/bitarchiveitem.hpp
Expand Down Expand Up @@ -66,6 +67,7 @@ set( HEADERS
set( SOURCES
${PROJECT_SOURCE_DIR}/src/bit7zlibrary.cpp
${PROJECT_SOURCE_DIR}/src/bitarchivecreator.cpp
${PROJECT_SOURCE_DIR}/src/bitarchiveeditor.cpp
${PROJECT_SOURCE_DIR}/src/bitarchivehandler.cpp
${PROJECT_SOURCE_DIR}/src/bitarchiveinfo.cpp
${PROJECT_SOURCE_DIR}/src/bitarchiveitem.cpp
Expand Down
2 changes: 1 addition & 1 deletion include/bitarchivecreator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ namespace bit7z {

protected:
const BitInOutFormat& mFormat;
bool mUpdateMode;

BitArchiveCreator( const Bit7zLibrary& lib,
const BitInOutFormat& format,
Expand Down Expand Up @@ -220,7 +221,6 @@ namespace bit7z {
uint32_t mWordSize;
bool mCryptHeaders;
bool mSolidMode;
bool mUpdateMode;
uint64_t mVolumeSize;
uint32_t mThreadsCount;
};
Expand Down
50 changes: 50 additions & 0 deletions include/bitarchiveeditor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 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 DLLs.
* Copyright (c) 2014-2020 Riccardo Ostani - All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* Bit7z is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with bit7z; if not, see https://www.gnu.org/licenses/.
*/

#ifndef BITARCHIVEEDITOR_HPP
#define BITARCHIVEEDITOR_HPP

#include "../include/bitarchivecreator.hpp"
#include "../include/bittypes.hpp"

namespace bit7z {
using std::vector;

class BitArchiveEditor : public BitArchiveCreator {
public:
BitArchiveEditor( const Bit7zLibrary& lib,
const tstring& in_file,
const BitInOutFormat& format,
const tstring& password = TSTRING( "" ) );

void renameItem( unsigned index, const tstring& new_name );

void renameItem( const tstring& old_name, const tstring& new_name );

void applyChanges();

private:
unique_ptr< BitInputArchive > mInputArchive;
RenamedItems mRenameMap;
};
}

#endif //BITARCHIVEEDITOR_HPP
3 changes: 3 additions & 0 deletions include/bittypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#define BITTYPES_HPP

#include <string>
#include <unordered_map>

#ifdef BIT7Z_REGEX_MATCHING
#include <regex>
Expand Down Expand Up @@ -58,5 +59,7 @@ namespace bit7z {
#define HRESULT_CODE(hr) ((hr) & 0xFFFF)
#define COM_DECLSPEC_NOTHROW
#endif

using RenamedItems = std::unordered_map< unsigned int, tstring >;
}
#endif // BITTYPES_HPP
3 changes: 3 additions & 0 deletions include/updatecallback.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ namespace bit7z {

void setOldArc( const BitInputArchive* old_arc );

void setRenamedItems( RenamedItems renamed_items );

HRESULT Finalize();

// IProgress from IArchiveUpdateCallback2
Expand Down Expand Up @@ -81,6 +83,7 @@ namespace bit7z {
protected:
const BitInputArchive* mOldArc;
uint32_t mOldArcItemsCount;
unique_ptr< const RenamedItems > mRenamedItems;

bool mAskPassword;
bool mNeedBeClosed;
Expand Down
2 changes: 1 addition & 1 deletion src/bitarchivecreator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,13 @@ BitArchiveCreator::BitArchiveCreator( const Bit7zLibrary& lib,
tstring password ) :
BitArchiveHandler( lib, std::move( password ) ),
mFormat( format ),
mUpdateMode( false ),
mCompressionLevel( BitCompressionLevel::NORMAL ),
mCompressionMethod( format.defaultMethod() ),
mDictionarySize( 0 ),
mWordSize( 0 ),
mCryptHeaders( false ),
mSolidMode( false ),
mUpdateMode( false ),
mVolumeSize( 0 ),
mThreadsCount( 0 ) {}

Expand Down
63 changes: 63 additions & 0 deletions src/bitarchiveeditor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* bit7z - A C++ static library to interface with the 7-zip DLLs.
* Copyright (c) 2014-2020 Riccardo Ostani - All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* Bit7z is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with bit7z; if not, see https://www.gnu.org/licenses/.
*/

#include "../include/bitexception.hpp"
#include "../include/bitarchiveeditor.hpp"

#include "../include/fileupdatecallback.hpp"

using bit7z::BitArchiveEditor;
using bit7z::BitException;
using bit7z::BitInFormat;

BitArchiveEditor::BitArchiveEditor( const Bit7zLibrary& lib,
const tstring& in_file,
const BitInOutFormat& format,
const tstring& password )
: BitArchiveCreator( lib, format, password ),
mInputArchive( std::make_unique<BitInputArchive>( *this, in_file ) ) {
mUpdateMode = true;
}

void BitArchiveEditor::renameItem( unsigned index, const tstring& new_name ) {
if ( index >= mInputArchive->itemsCount() ) {
throw BitException( "Invalid index " + std::to_string(index), std::make_error_code( std::errc::invalid_argument ) );
}
mRenameMap[ index ] = new_name;
}

void BitArchiveEditor::renameItem( const tstring& old_name, const tstring& new_name ) {
for ( const auto& archiveItem : *mInputArchive ) {
if ( archiveItem.name() == old_name ) {
mRenameMap[ archiveItem.index() ] = new_name;
return;
}
}
throw BitException("Could not find the file in the archive",
std::make_error_code( std::errc::no_such_file_or_directory ), { old_name } );
}

void BitArchiveEditor::applyChanges() {
auto archive_path = mInputArchive->getArchivePath();
mInputArchive.reset();
CMyComPtr< UpdateCallback > update_callback = new FileUpdateCallback( *this, {} );
update_callback->setRenamedItems( std::move( mRenameMap ) );
BitArchiveCreator::compressToFile( archive_path, update_callback );
mRenameMap.clear();
mInputArchive = std::make_unique<BitInputArchive>( *this, archive_path );
}
26 changes: 20 additions & 6 deletions src/updatecallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@
using namespace bit7z;

UpdateCallback::UpdateCallback( const BitArchiveCreator& creator )
: Callback( creator ),
mOldArc( nullptr ),
mOldArcItemsCount( 0 ),
mAskPassword( false ),
mNeedBeClosed( false ) {}
: Callback{ creator },
mOldArc{ nullptr },
mOldArcItemsCount{ 0 },
mRenamedItems{ nullptr },
mAskPassword{ false },
mNeedBeClosed{ false } {}

UpdateCallback::~UpdateCallback() {
Finalize();
Expand All @@ -43,6 +44,10 @@ void UpdateCallback::setOldArc( const BitInputArchive* old_arc ) {
}
}

void UpdateCallback::setRenamedItems( RenamedItems renamed_items ) {
mRenamedItems = std::make_unique< const RenamedItems >( std::move( renamed_items ) );
}

HRESULT UpdateCallback::Finalize() {
if ( mNeedBeClosed ) {
mNeedBeClosed = false;
Expand Down Expand Up @@ -81,7 +86,15 @@ STDMETHODIMP UpdateCallback::GetProperty( UInt32 index, PROPID propID, PROPVARIA
if ( propID == kpidIsAnti ) {
prop = false;
} else if ( index < mOldArcItemsCount ) {
if ( mRenamedItems != nullptr && propID == kpidPath ) {
auto res = mRenamedItems->find( index );
if ( res != mRenamedItems->end() ) {
prop = WIDEN( res->second );
}
}
if ( prop.isEmpty() ) { //Not renamed
prop = mOldArc->getItemProperty( index, static_cast< BitProperty >( propID ) );
}
} else {
prop = getNewItemProperty( index, propID );
}
Expand Down Expand Up @@ -118,12 +131,13 @@ STDMETHODIMP UpdateCallback::GetUpdateItemInfo( UInt32 index,
UInt32* indexInArchive ) {

bool isOldItem = index < mOldArcItemsCount;
bool isRenamedItem = mRenamedItems != nullptr && mRenamedItems->find( index ) != mRenamedItems->end();

if ( newData != nullptr ) {
*newData = isOldItem ? 0 : 1; //= true;
}
if ( newProperties != nullptr ) {
*newProperties = isOldItem ? 0 : 1; //= true;
*newProperties = isOldItem && !isRenamedItem ? 0 : 1; //= true;
}
if ( indexInArchive != nullptr ) {
*indexInArchive = isOldItem ? index : static_cast< uint32_t >( -1 );
Expand Down

0 comments on commit 51d229e

Please sign in to comment.