diff options
Diffstat (limited to 'range_dec.cc')
-rw-r--r-- | range_dec.cc | 84 |
1 files changed, 38 insertions, 46 deletions
diff --git a/range_dec.cc b/range_dec.cc index c6ccb7a..eeb542a 100644 --- a/range_dec.cc +++ b/range_dec.cc @@ -1,5 +1,5 @@ /* Lziprecover - Data recovery tool for the lzip format - Copyright (C) 2009-2015 Antonio Diaz Diaz. + Copyright (C) 2009-2016 Antonio Diaz Diaz. 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 @@ -36,50 +36,44 @@ namespace { -int decompress_member( const int infd, const int outfd, - const Pretty_print & pp, +int decompress_member( const int infd, const Pretty_print & pp, const unsigned long long mpos, const unsigned long long outskip, const unsigned long long outend ) { - try { - Range_decoder rdec( infd ); - File_header header; - rdec.read_data( header.data, File_header::size ); - if( rdec.finished() ) // End Of File - { pp( "File ends unexpectedly at member header." ); return 2; } - if( !verify_header( header, pp ) ) return 2; - const unsigned dictionary_size = header.dictionary_size(); - if( dictionary_size < min_dictionary_size || - dictionary_size > max_dictionary_size ) - { pp( "Invalid dictionary size in member header." ); return 2; } - - if( pp.verbosity() >= 2 ) { pp(); show_header( dictionary_size ); } - - LZ_decoder decoder( header, rdec, outfd, outskip, outend ); - const int result = decoder.decode_member( pp ); - if( result != 0 ) + Range_decoder rdec( infd ); + File_header header; + rdec.read_data( header.data, File_header::size ); + if( rdec.finished() ) // End Of File + { pp( "File ends unexpectedly at member header." ); return 2; } + if( !verify_header( header, pp ) ) return 2; + const unsigned dictionary_size = header.dictionary_size(); + if( !isvalid_ds( dictionary_size ) ) + { pp( "Invalid dictionary size in member header." ); return 2; } + + if( pp.verbosity() >= 2 ) { pp(); show_header( dictionary_size ); } + + LZ_decoder decoder( rdec, dictionary_size, outfd, outskip, outend ); + const int result = decoder.decode_member( pp ); + if( result != 0 ) + { + if( pp.verbosity() >= 0 && result <= 2 ) { - if( pp.verbosity() >= 0 && result <= 2 ) - { - pp(); - std::fprintf( stderr, "%s at pos %llu\n", ( result == 2 ) ? - "File ends unexpectedly" : "Decoder error", - mpos + rdec.member_position() ); - } - return 2; + pp(); + std::fprintf( stderr, "%s at pos %llu\n", ( result == 2 ) ? + "File ends unexpectedly" : "Decoder error", + mpos + rdec.member_position() ); } - if( pp.verbosity() >= 2 ) std::fputs( "done\n", stderr ); + return 2; } - catch( std::bad_alloc ) { pp( "Not enough memory." ); return 1; } - catch( Error e ) { pp(); show_error( e.msg, errno ); return 1; } + if( pp.verbosity() >= 2 ) std::fputs( "done\n", stderr ); return 0; } int list_file( const char * const input_filename, const Pretty_print & pp ) { - struct stat in_stats; + struct stat in_stats; // not used const int infd = open_instream( input_filename, &in_stats, true, true ); if( infd < 0 ) return 1; @@ -94,8 +88,8 @@ int list_file( const char * const input_filename, const Pretty_print & pp ) const unsigned long long file_size = file_index.file_end(); unsigned dictionary_size = 0; for( long i = 0; i < file_index.members(); ++i ) - if( dictionary_size < file_index.dictionary_size( i ) ) - dictionary_size = file_index.dictionary_size( i ); + dictionary_size = + std::max( dictionary_size, file_index.dictionary_size( i ) ); pp( 0, stdout ); show_header( dictionary_size, 1 ); if( data_size > 0 && file_size > 0 ) @@ -180,7 +174,7 @@ int list_files( const std::vector< std::string > & filenames, int range_decompress( const std::string & input_filename, - const std::string & output_filename, + const std::string & default_output_filename, Block range, const int verbosity, const bool force, const bool ignore, const bool to_stdout ) { @@ -209,12 +203,14 @@ int range_decompress( const std::string & input_filename, format_num( range.size() ) ); } - int outfd = -1; - if( to_stdout || output_filename.empty() ) + if( to_stdout || default_output_filename.empty() ) outfd = STDOUT_FILENO; else - { outfd = open_outstream_rw( output_filename, force ); - if( outfd < 0 ) return 1; } + { + output_filename = default_output_filename; + if( !open_outstream( force, false, false, false ) ) + { close( infd ); return 1; } + } int retval = 0; for( long i = 0; i < file_index.members(); ++i ) @@ -228,19 +224,15 @@ int range_decompress( const std::string & input_filename, const long long outend = std::min( db.size(), range.end() - db.pos() ); const long long mpos = file_index.mblock( i ).pos(); if( !safe_seek( infd, mpos ) ) { retval = 1; break; } - const int tmp = decompress_member( infd, outfd, pp, mpos, outskip, outend ); + const int tmp = decompress_member( infd, pp, mpos, outskip, outend ); if( tmp && ( tmp != 2 || !ignore ) ) - cleanup_and_fail( output_filename, outfd, tmp ); + cleanup_and_fail( tmp ); if( tmp > retval ) retval = tmp; pp.reset(); } } close( infd ); - if( close( outfd ) != 0 ) - { - show_error( "Error closing output file", errno ); - cleanup_and_fail( output_filename, -1, 1 ); - } + retval = std::max( retval, close_outstream( &in_stats ) ); if( verbosity >= 2 && retval == 0 ) std::fputs( "Byte range decompressed successfully.\n", stderr ); return retval; |