diff options
Diffstat (limited to 'range_dec.cc')
-rw-r--r-- | range_dec.cc | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/range_dec.cc b/range_dec.cc index 5df48b2..2c6c342 100644 --- a/range_dec.cc +++ b/range_dec.cc @@ -1,5 +1,5 @@ /* Lziprecover - Data recovery tool for lzip files - Copyright (C) 2009, 2010, 2011, 2012, 2013 Antonio Diaz Diaz. + Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 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 @@ -35,6 +35,30 @@ namespace { +const char * format_num( unsigned long long num, + unsigned long long limit = -1ULL, + const int set_prefix = 0 ) + { + const char * const si_prefix[8] = + { "k", "M", "G", "T", "P", "E", "Z", "Y" }; + const char * const binary_prefix[8] = + { "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" }; + static bool si = true; + static char buf[32]; + + if( set_prefix ) si = ( set_prefix > 0 ); + const unsigned factor = ( si ? 1000 : 1024 ); + const char * const * prefix = ( si ? si_prefix : binary_prefix ); + const char * p = ""; + bool exact = ( num % factor == 0 ); + + for( int i = 0; i < 8 && ( num > limit || ( exact && num >= factor ) ); ++i ) + { num /= factor; if( num % factor != 0 ) exact = false; p = prefix[i]; } + snprintf( buf, sizeof buf, "%llu %s", num, p ); + return buf; + } + + // Returns the number of chars read, or 0 if error. // int parse_long_long( const char * const ptr, long long & value ) @@ -112,9 +136,9 @@ int decompress_member( const int infd, const int outfd, 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; } + { pp( "File ends unexpectedly at member header." ); return 2; } if( !header.verify_magic() ) - { pp( "Bad magic number (file not in lzip format)" ); return 2; } + { pp( "Bad magic number (file not in lzip format)." ); return 2; } if( !header.verify_version() ) { if( pp.verbosity() >= 0 ) @@ -125,7 +149,7 @@ int decompress_member( const int infd, const int outfd, } if( header.dictionary_size() < min_dictionary_size || header.dictionary_size() > max_dictionary_size ) - { pp( "Invalid dictionary size in member header" ); return 2; } + { pp( "Invalid dictionary size in member header." ); return 2; } if( pp.verbosity() >= 2 ) { pp(); show_header( header ); } @@ -137,27 +161,23 @@ int decompress_member( const int infd, const int outfd, { pp(); if( result == 2 ) - std::fprintf( stderr, "File ends unexpectedly at pos %llu\n", + std::fprintf( stderr, "File ends unexpectedly at pos %llu.\n", mpos + rdec.member_position() ); else - std::fprintf( stderr, "Decoder error at pos %llu\n", + std::fprintf( stderr, "Decoder error at pos %llu.\n", mpos + rdec.member_position() ); } return 2; } if( pp.verbosity() >= 2 ) std::fprintf( stderr, "done\n" ); } - catch( std::bad_alloc ) - { - pp( "Not enough memory. Find a machine with more memory" ); - return 1; - } + catch( std::bad_alloc ) { pp( "Not enough memory." ); return 1; } catch( Error e ) { pp(); show_error( e.msg, errno ); return 1; } return 0; } -int list_file( const std::string & input_filename, const Pretty_print & pp ) +int list_file( const char * const input_filename, const Pretty_print & pp ) { struct stat in_stats; const int infd = open_instream( input_filename, &in_stats, true, true ); @@ -166,7 +186,7 @@ int list_file( const std::string & input_filename, const Pretty_print & pp ) const File_index file_index( infd ); close( infd ); if( file_index.retval() != 0 ) - { show_error( file_index.error().c_str() ); return file_index.retval(); } + { pp( file_index.error().c_str() ); return file_index.retval(); } if( pp.verbosity() >= 0 ) { @@ -216,7 +236,7 @@ int list_files( const std::vector< std::string > & filenames, for( unsigned i = 0; i < filenames.size(); ++i ) { pp.set_name( filenames[i] ); - const int tmp = list_file( filenames[i], pp ); + const int tmp = list_file( filenames[i].c_str(), pp ); if( tmp > retval ) retval = tmp; } return retval; @@ -231,17 +251,18 @@ int range_decompress( const std::string & input_filename, Block range( 0, 0 ); parse_range( range_string.c_str(), range ); struct stat in_stats; - const int infd = open_instream( input_filename, &in_stats, true, true ); + const int infd = open_instream( input_filename.c_str(), &in_stats, true, true ); if( infd < 0 ) return 1; + Pretty_print pp( input_filename, verbosity ); const File_index file_index( infd ); if( file_index.retval() != 0 ) - { show_error( file_index.error().c_str() ); return file_index.retval(); } + { pp( file_index.error().c_str() ); return file_index.retval(); } if( range.end() > file_index.data_end() ) range.size( std::max( 0LL, file_index.data_end() - range.pos() ) ); if( range.size() <= 0 ) - { if( verbosity >= 1 ) show_error( "Nothing to do." ); return 0; } + { if( verbosity >= 1 ) pp( "Nothing to do." ); return 0; } if( verbosity >= 1 ) { @@ -254,13 +275,12 @@ int range_decompress( const std::string & input_filename, } int outfd = -1; - if( to_stdout || !output_filename.size() ) + if( to_stdout || output_filename.empty() ) outfd = STDOUT_FILENO; else { outfd = open_outstream_rw( output_filename, force ); if( outfd < 0 ) return 1; } - Pretty_print pp( input_filename, verbosity ); int retval = 0; for( int i = 0; i < file_index.members(); ++i ) { |