summaryrefslogtreecommitdiffstats
path: root/range_dec.cc
diff options
context:
space:
mode:
Diffstat (limited to 'range_dec.cc')
-rw-r--r--range_dec.cc58
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 )
{