diff options
Diffstat (limited to 'merge.cc')
-rw-r--r-- | merge.cc | 86 |
1 files changed, 43 insertions, 43 deletions
@@ -140,25 +140,23 @@ bool diff_member( const long long mpos, const long long msize, continue; std::vector< Block > bv; long long partial_pos = 0; - const char * const filename1 = filenames[i1].c_str(); - const char * const filename2 = filenames[i2].c_str(); const int fd1 = infd_vector[i1], fd2 = infd_vector[i2]; int begin = -1; // begin of block. -1 means no block bool prev_equal = true; - if( !safe_seek( fd1, mpos, filename1 ) || - !safe_seek( fd2, mpos, filename2 ) ) { error = true; break; } + if( !safe_seek( fd1, mpos, filenames[i1] ) || + !safe_seek( fd2, mpos, filenames[i2] ) ) { error = true; break; } while( partial_pos < msize ) { const int size = std::min( (long long)buffer_size, msize - partial_pos ); const int rd = readblock( fd1, buffer1, size ); if( rd != size && errno ) - { show_file_error( filename1, read_error_msg, errno ); + { show_file_error( filenames[i1].c_str(), read_error_msg, errno ); error = true; break; } if( rd > 0 ) { if( readblock( fd2, buffer2, rd ) != rd ) - { show_file_error( filename2, read_error_msg, errno ); + { show_file_error( filenames[i2].c_str(), read_error_msg, errno ); error = true; break; } for( int i = 0; i < rd; ++i ) { @@ -285,21 +283,20 @@ int open_input_files( const std::vector< std::string > & filenames, for( int i = 0; i < files; ++i ) { - const char * const filename = filenames[i].c_str(); const int infd = infd_vector[i]; bool error = false; for( long j = 0; j < lzip_index.members(); ++j ) { const long long mpos = lzip_index.mblock( j ).pos(); const long long msize = lzip_index.mblock( j ).size(); - if( !safe_seek( infd, mpos, filename ) ) return 1; + if( !safe_seek( infd, mpos, filenames[i] ) ) return 1; if( test_member_from_file( infd, msize ) != 0 ) { error = true; break; } } if( !error ) { if( verbosity >= 1 ) std::printf( "Input file '%s' has no errors. Recovery is not needed.\n", - filename ); + filenames[i].c_str() ); return 0; } } @@ -365,10 +362,10 @@ bool try_merge_member2( const std::vector< std::string > & filenames, if( i1 == i2 || color_vector[i1] == color_vector[i2] || color_done( color_vector, i1 ) ) continue; for( int bi = 0; bi < blocks; ++bi ) - if( !safe_seek( infd_vector[i2], block_vector[bi].pos(), filenames[i2].c_str() ) || - !safe_seek( outfd, block_vector[bi].pos(), output_filename.c_str() ) || - !copy_file( infd_vector[i2], outfd, block_vector[bi].size() ) ) - cleanup_and_fail( 1 ); + if( !safe_seek( infd_vector[i2], block_vector[bi].pos(), filenames[i2] ) || + !safe_seek( outfd, block_vector[bi].pos(), output_filename ) || + !copy_file( infd_vector[i2], outfd, filenames[i2], output_filename, + block_vector[bi].size() ) ) cleanup_and_fail( 1 ); const int infd = infd_vector[i1]; const int var = ( i1 * ( files - 1 ) ) + i2 - ( i2 > i1 ) + 1; for( int bi = 0; bi + 1 < blocks; ++bi ) @@ -379,10 +376,11 @@ bool try_merge_member2( const std::vector< std::string > & filenames, var, variations, bi + 1, terminator ); std::fflush( stdout ); pending_newline = true; } - if( !safe_seek( infd, block_vector[bi].pos(), filenames[i1].c_str() ) || - !safe_seek( outfd, block_vector[bi].pos(), output_filename.c_str() ) || - !copy_file( infd, outfd, block_vector[bi].size() ) || - !safe_seek( outfd, mpos, output_filename.c_str() ) ) + if( !safe_seek( infd, block_vector[bi].pos(), filenames[i1] ) || + !safe_seek( outfd, block_vector[bi].pos(), output_filename ) || + !copy_file( infd, outfd, filenames[i1], output_filename, + block_vector[bi].size() ) || + !safe_seek( outfd, mpos, output_filename ) ) cleanup_and_fail( 1 ); long long failure_pos = 0; if( test_member_from_file( outfd, msize, &failure_pos ) == 0 ) @@ -421,8 +419,7 @@ bool try_merge_member( const std::vector< std::string > & filenames, if( verbosity >= 2 ) { long var = 0; - for( int i = 0; i < blocks; ++i ) - var = ( var * files ) + file_idx[i]; + for( int i = 0; i < blocks; ++i ) var = var * files + file_idx[i]; std::printf( " Trying variation %ld of %ld %c", var + 1, variations, terminator ); std::fflush( stdout ); pending_newline = true; @@ -430,14 +427,13 @@ bool try_merge_member( const std::vector< std::string > & filenames, while( bi < blocks ) { const int infd = infd_vector[file_idx[bi]]; - if( !safe_seek( infd, block_vector[bi].pos(), filenames[file_idx[bi]].c_str() ) || - !safe_seek( outfd, block_vector[bi].pos(), output_filename.c_str() ) || - !copy_file( infd, outfd, block_vector[bi].size() ) ) - cleanup_and_fail( 1 ); + if( !safe_seek( infd, block_vector[bi].pos(), filenames[file_idx[bi]] ) || + !safe_seek( outfd, block_vector[bi].pos(), output_filename ) || + !copy_file( infd, outfd, filenames[file_idx[bi]], output_filename, + block_vector[bi].size() ) ) cleanup_and_fail( 1 ); ++bi; } - if( !safe_seek( outfd, mpos, output_filename.c_str() ) ) - cleanup_and_fail( 1 ); + if( !safe_seek( outfd, mpos, output_filename ) ) cleanup_and_fail( 1 ); long long failure_pos = 0; if( test_member_from_file( outfd, msize, &failure_pos ) == 0 ) return true; while( bi > 0 && mpos + failure_pos < block_vector[bi-1].pos() ) --bi; @@ -473,12 +469,12 @@ bool try_merge_member1( const std::vector< std::string > & filenames, { if( i1 == i2 || color_vector[i1] == color_vector[i2] || color_done( color_vector, i1 ) ) continue; + if( !safe_seek( infd_vector[i1], pos, filenames[i1] ) || + !safe_seek( infd_vector[i2], pos, filenames[i2] ) || + !safe_seek( outfd, pos, output_filename ) || + !copy_file( infd_vector[i2], outfd, filenames[i2], output_filename, + size ) ) cleanup_and_fail( 1 ); const int infd = infd_vector[i1]; - if( !safe_seek( infd, pos, filenames[i1].c_str() ) || - !safe_seek( infd_vector[i2], pos, filenames[i2].c_str() ) || - !safe_seek( outfd, pos, output_filename.c_str() ) || - !copy_file( infd_vector[i2], outfd, size ) ) - cleanup_and_fail( 1 ); const int var = ( i1 * ( files - 1 ) ) + i2 - ( i2 > i1 ) + 1; for( long long i = 0; i + 1 < size; ++i ) { @@ -488,10 +484,10 @@ bool try_merge_member1( const std::vector< std::string > & filenames, var, variations, pos + i, terminator ); std::fflush( stdout ); pending_newline = true; } - if( !safe_seek( outfd, pos + i, output_filename.c_str() ) || + if( !safe_seek( outfd, pos + i, output_filename ) || readblock( infd, &byte, 1 ) != 1 || writeblock( outfd, &byte, 1 ) != 1 || - !safe_seek( outfd, mpos, output_filename.c_str() ) ) + !safe_seek( outfd, mpos, output_filename ) ) cleanup_and_fail( 1 ); long long failure_pos = 0; if( test_member_from_file( outfd, msize, &failure_pos ) == 0 ) @@ -508,11 +504,12 @@ bool try_merge_member1( const std::vector< std::string > & filenames, /* infd and outfd can refer to the same file if copying to a lower file position or if source and destination blocks don't overlap. max_size < 0 means no size limit. */ -bool copy_file( const int infd, const int outfd, const long long max_size ) +bool copy_file( const int infd, const int outfd, const std::string & iname, + const std::string & oname, const long long max_size ) { const int buffer_size = 65536; // remaining number of bytes to copy - long long rest = ( ( max_size >= 0 ) ? max_size : buffer_size ); + long long rest = (max_size >= 0) ? max_size : buffer_size; long long copied_size = 0; uint8_t * const buffer = new uint8_t[buffer_size]; bool error = false; @@ -523,20 +520,22 @@ bool copy_file( const int infd, const int outfd, const long long max_size ) if( max_size >= 0 ) rest -= size; const int rd = readblock( infd, buffer, size ); if( rd != size && errno ) - { show_error( read_error_msg, errno ); error = true; break; } + { show_file_error( printable_name( iname ), read_error_msg, errno ); + error = true; break; } if( rd > 0 ) { const int wr = writeblock( outfd, buffer, rd ); if( wr != rd ) - { show_error( "Error writing output file", errno ); - error = true; break; } + { show_file_error( printable_name( oname, false ), write_error_msg, + errno ); error = true; break; } copied_size += rd; } if( rd < size ) break; // EOF } delete[] buffer; if( !error && max_size >= 0 && copied_size != max_size ) - { show_error( "Input file ends unexpectedly." ); error = true; } + { show_file_error( printable_name( iname ), "Input file ends unexpectedly." ); + error = true; } return !error; } @@ -544,7 +543,7 @@ bool copy_file( const int infd, const int outfd, const long long max_size ) /* Return value: 0 = OK, 1 = bad msize, 2 = data error. 'failure_pos' is relative to the beginning of the member. */ int test_member_from_file( const int infd, const unsigned long long msize, - long long * const failure_posp ) + long long * const failure_posp, bool * const nonzerop ) { Range_decoder rdec( infd ); Lzip_header header; @@ -559,6 +558,7 @@ int test_member_from_file( const int infd, const unsigned long long msize, verbosity = -1; // suppress all messages done = decoder.decode_member() == 0; verbosity = saved_verbosity; // restore verbosity level + if( nonzerop ) *nonzerop = rdec.nonzero(); if( done && rdec.member_position() == msize ) return 0; } if( failure_posp ) *failure_posp = rdec.member_position(); @@ -578,15 +578,15 @@ int merge_files( const std::vector< std::string > & filenames, const int retval = open_input_files( filenames, infd_vector, cl_opts, lzip_index, &in_stats ); if( retval >= 0 ) return retval; - if( !safe_seek( infd_vector[0], 0, filenames[0].c_str() ) ) return 1; + if( !safe_seek( infd_vector[0], 0, filenames[0] ) ) return 1; const bool to_file = default_output_filename.size(); output_filename = to_file ? default_output_filename : insert_fixed( filenames[0] ); set_signal_handler(); if( !open_outstream( force, true, true, false, to_file ) ) return 1; - if( !copy_file( infd_vector[0], outfd ) ) // copy whole file - cleanup_and_fail( 1 ); + if( !copy_file( infd_vector[0], outfd, filenames[0], output_filename ) ) + cleanup_and_fail( 1 ); // copy whole file for( long j = 0; j < lzip_index.members(); ++j ) { @@ -597,7 +597,7 @@ int merge_files( const std::vector< std::string > & filenames, // different color means members are different std::vector< int > color_vector( files, 0 ); if( !diff_member( mpos, msize, filenames, infd_vector, block_vector, - color_vector ) || !safe_seek( outfd, mpos, output_filename.c_str() ) ) + color_vector ) || !safe_seek( outfd, mpos, output_filename ) ) cleanup_and_fail( 1 ); if( block_vector.empty() ) |