Merging upstream version 1.7.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
8bc0325467
commit
f6869e4fd3
20 changed files with 841 additions and 444 deletions
|
@ -1,6 +1,6 @@
|
|||
/* Plzip - Parallel compressor compatible with lzip
|
||||
Copyright (C) 2009 Laszlo Ersek.
|
||||
Copyright (C) 2009-2017 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2018 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
|
||||
|
@ -101,7 +101,7 @@ public:
|
|||
}
|
||||
|
||||
// make a packet with data received from splitter
|
||||
// if data == 0, move to next queue
|
||||
// if data == 0 (end of member token), move to next queue
|
||||
void receive_packet( uint8_t * const data, const int size )
|
||||
{
|
||||
Packet * const ipacket = new Packet( data, size );
|
||||
|
@ -237,9 +237,11 @@ int find_magic( const uint8_t * const buffer, const int pos, const int size )
|
|||
|
||||
struct Splitter_arg
|
||||
{
|
||||
unsigned long long cfile_size;
|
||||
Packet_courier * courier;
|
||||
const Pretty_print * pp;
|
||||
int infd;
|
||||
unsigned dictionary_size; // returned by splitter to main thread
|
||||
};
|
||||
|
||||
|
||||
|
@ -247,7 +249,7 @@ struct Splitter_arg
|
|||
// courier for packaging and distribution to workers.
|
||||
extern "C" void * dsplitter_s( void * arg )
|
||||
{
|
||||
const Splitter_arg & tmp = *(Splitter_arg *)arg;
|
||||
Splitter_arg & tmp = *(Splitter_arg *)arg;
|
||||
Packet_courier & courier = *tmp.courier;
|
||||
const Pretty_print & pp = *tmp.pp;
|
||||
const int infd = tmp.infd;
|
||||
|
@ -264,16 +266,18 @@ extern "C" void * dsplitter_s( void * arg )
|
|||
if( size != buffer_size && errno )
|
||||
{ pp(); show_error( "Read error", errno ); cleanup_and_fail(); }
|
||||
if( size + hsize < min_member_size )
|
||||
{ pp( "Input file is too short." ); cleanup_and_fail( 2 ); }
|
||||
{ show_file_error( pp.name(), "Input file is too short." );
|
||||
cleanup_and_fail( 2 ); }
|
||||
const File_header & header = *(File_header *)buffer;
|
||||
if( !header.verify_magic() )
|
||||
{ pp( bad_magic_msg ); cleanup_and_fail( 2 ); }
|
||||
{ show_file_error( pp.name(), bad_magic_msg ); cleanup_and_fail( 2 ); }
|
||||
if( !header.verify_version() )
|
||||
{ pp( bad_version( header.version() ) ); cleanup_and_fail( 2 ); }
|
||||
const unsigned dictionary_size = header.dictionary_size();
|
||||
if( !isvalid_ds( dictionary_size ) )
|
||||
tmp.dictionary_size = header.dictionary_size();
|
||||
if( !isvalid_ds( tmp.dictionary_size ) )
|
||||
{ pp( bad_dict_msg ); cleanup_and_fail( 2 ); }
|
||||
show_header( dictionary_size );
|
||||
if( verbosity >= 1 ) pp();
|
||||
show_progress( 0, tmp.cfile_size, &pp ); // init
|
||||
|
||||
unsigned long long partial_member_size = 0;
|
||||
while( true )
|
||||
|
@ -301,6 +305,7 @@ extern "C" void * dsplitter_s( void * arg )
|
|||
courier.receive_packet( 0, 0 ); // end of member token
|
||||
partial_member_size = 0;
|
||||
pos = newpos;
|
||||
show_progress( member_size );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -340,6 +345,7 @@ struct Worker_arg
|
|||
const Pretty_print * pp;
|
||||
int worker_id;
|
||||
bool ignore_trailing;
|
||||
bool loose_trailing;
|
||||
bool testing;
|
||||
};
|
||||
|
||||
|
@ -353,6 +359,7 @@ extern "C" void * dworker_s( void * arg )
|
|||
const Pretty_print & pp = *tmp.pp;
|
||||
const int worker_id = tmp.worker_id;
|
||||
const bool ignore_trailing = tmp.ignore_trailing;
|
||||
const bool loose_trailing = tmp.loose_trailing;
|
||||
const bool testing = tmp.testing;
|
||||
|
||||
uint8_t * new_data = new( std::nothrow ) uint8_t[max_packet_size];
|
||||
|
@ -387,12 +394,22 @@ extern "C" void * dworker_s( void * arg )
|
|||
max_packet_size - new_pos );
|
||||
if( rd < 0 )
|
||||
{
|
||||
if( LZ_decompress_errno( decoder ) == LZ_header_error )
|
||||
const enum LZ_Errno lz_errno = LZ_decompress_errno( decoder );
|
||||
if( lz_errno == LZ_header_error )
|
||||
{
|
||||
trailing_data_found = true;
|
||||
if( !ignore_trailing )
|
||||
{ pp( trailing_msg ); cleanup_and_fail( 2 ); }
|
||||
}
|
||||
else if( lz_errno == LZ_data_error &&
|
||||
LZ_decompress_member_position( decoder ) == 0 )
|
||||
{
|
||||
trailing_data_found = true;
|
||||
if( !loose_trailing )
|
||||
{ pp( corrupt_mm_msg ); cleanup_and_fail( 2 ); }
|
||||
else if( !ignore_trailing )
|
||||
{ pp( trailing_msg ); cleanup_and_fail( 2 ); }
|
||||
}
|
||||
else
|
||||
cleanup_and_fail( decompress_read_error( decoder, pp, worker_id ) );
|
||||
}
|
||||
|
@ -459,9 +476,10 @@ void muxer( Packet_courier & courier, const Pretty_print & pp, const int outfd )
|
|||
|
||||
// init the courier, then start the splitter and the workers and,
|
||||
// if not testing, call the muxer.
|
||||
int dec_stream( const int num_workers, const int infd, const int outfd,
|
||||
int dec_stream( const unsigned long long cfile_size,
|
||||
const int num_workers, const int infd, const int outfd,
|
||||
const Pretty_print & pp, const int debug_level,
|
||||
const bool ignore_trailing )
|
||||
const bool ignore_trailing, const bool loose_trailing )
|
||||
{
|
||||
const int in_slots_per_worker = 2;
|
||||
const int out_slots = 32;
|
||||
|
@ -472,6 +490,7 @@ int dec_stream( const int num_workers, const int infd, const int outfd,
|
|||
Packet_courier courier( num_workers, in_slots, out_slots );
|
||||
|
||||
Splitter_arg splitter_arg;
|
||||
splitter_arg.cfile_size = cfile_size;
|
||||
splitter_arg.courier = &courier;
|
||||
splitter_arg.pp = &pp;
|
||||
splitter_arg.infd = infd;
|
||||
|
@ -491,6 +510,7 @@ int dec_stream( const int num_workers, const int infd, const int outfd,
|
|||
worker_args[i].pp = &pp;
|
||||
worker_args[i].worker_id = i;
|
||||
worker_args[i].ignore_trailing = ignore_trailing;
|
||||
worker_args[i].loose_trailing = loose_trailing;
|
||||
worker_args[i].testing = ( outfd < 0 );
|
||||
errcode = pthread_create( &worker_threads[i], 0, dworker_s, &worker_args[i] );
|
||||
if( errcode )
|
||||
|
@ -512,15 +532,20 @@ int dec_stream( const int num_workers, const int infd, const int outfd,
|
|||
if( errcode )
|
||||
{ show_error( "Can't join splitter thread", errcode ); cleanup_and_fail(); }
|
||||
|
||||
if( verbosity >= 2 && out_size > 0 && in_size > 0 )
|
||||
std::fprintf( stderr, "%6.3f:1, %6.3f bits/byte, %5.2f%% saved. ",
|
||||
(double)out_size / in_size,
|
||||
( 8.0 * in_size ) / out_size,
|
||||
100.0 * ( 1.0 - ( (double)in_size / out_size ) ) );
|
||||
if( verbosity >= 4 )
|
||||
std::fprintf( stderr, "decompressed %9llu, compressed %9llu. ",
|
||||
out_size, in_size );
|
||||
|
||||
if( verbosity >= 2 )
|
||||
{
|
||||
if( verbosity >= 4 ) show_header( splitter_arg.dictionary_size );
|
||||
if( out_size == 0 || in_size == 0 )
|
||||
std::fputs( "no data compressed. ", stderr );
|
||||
else
|
||||
std::fprintf( stderr, "%6.3f:1, %5.2f%% ratio, %5.2f%% saved. ",
|
||||
(double)out_size / in_size,
|
||||
( 100.0 * in_size ) / out_size,
|
||||
100.0 - ( ( 100.0 * in_size ) / out_size ) );
|
||||
if( verbosity >= 3 )
|
||||
std::fprintf( stderr, "decompressed %9llu, compressed %8llu. ",
|
||||
out_size, in_size );
|
||||
}
|
||||
if( verbosity >= 1 ) std::fputs( (outfd < 0) ? "ok\n" : "done\n", stderr );
|
||||
|
||||
if( debug_level & 1 )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue