diff options
Diffstat (limited to 'decoder.cc')
-rw-r--r-- | decoder.cc | 51 |
1 files changed, 21 insertions, 30 deletions
@@ -74,7 +74,7 @@ bool Range_decoder::read_block() { stream_pos = readblock( infd, buffer, buffer_size ); if( stream_pos != buffer_size && errno ) throw Error( "Read error" ); - at_stream_end = ( stream_pos < buffer_size ); + at_stream_end = stream_pos < buffer_size; partial_member_pos += pos; pos = 0; show_dprogress(); @@ -90,7 +90,7 @@ void LZ_decoder::flush_data() const int size = pos - stream_pos; crc32.update_buf( crc_, buffer + stream_pos, size ); if( outfd >= 0 && writeblock( outfd, buffer + stream_pos, size ) != size ) - throw Error( "Write error" ); + throw Error( write_error_msg ); if( pos >= dictionary_size ) { partial_data_pos += pos; pos = 0; pos_wrapped = true; } stream_pos = pos; @@ -98,8 +98,7 @@ void LZ_decoder::flush_data() } -int LZ_decoder::check_trailer( const Pretty_print & pp, - const bool ignore_empty ) const +bool LZ_decoder::check_trailer( const Pretty_print & pp ) const { Lzip_trailer trailer; int size = rdec.read_data( trailer.data, trailer.size ); @@ -144,8 +143,7 @@ int LZ_decoder::check_trailer( const Pretty_print & pp, std::fprintf( stderr, "Member size mismatch; stored %llu (0x%llX), computed %llu (0x%llX)\n", tm_size, tm_size, member_size, member_size ); } } - if( error ) return 3; - if( !ignore_empty && data_size == 0 ) return 5; + if( error ) return false; if( verbosity >= 2 ) { if( verbosity >= 4 ) show_header( dictionary_size ); @@ -160,15 +158,14 @@ int LZ_decoder::check_trailer( const Pretty_print & pp, if( verbosity >= 3 ) std::fprintf( stderr, "%9llu out, %8llu in. ", data_size, member_size ); } - return 0; + return true; } /* Return value: 0 = OK, 1 = decoder error, 2 = unexpected EOF, 3 = trailer error, 4 = unknown marker found, - 5 = empty member found, 6 = marked member found. */ -int LZ_decoder::decode_member( const Cl_options & cl_opts, - const Pretty_print & pp ) + 5 = nonzero first LZMA byte found. */ +int LZ_decoder::decode_member( const Pretty_print & pp ) { Bit_model bm_literal[1<<literal_context_bits][0x300]; Bit_model bm_match[State::states][pos_states]; @@ -188,7 +185,7 @@ int LZ_decoder::decode_member( const Cl_options & cl_opts, unsigned rep3 = 0; State state; - if( !rdec.load( cl_opts.ignore_marking ) ) return 6; + if( !rdec.load() ) return 5; while( !rdec.finished() ) { const int pos_state = data_position() & pos_state_mask; @@ -232,39 +229,33 @@ int LZ_decoder::decode_member( const Cl_options & cl_opts, } else // match { + rep3 = rep2; rep2 = rep1; rep1 = rep0; len = rdec.decode_len( match_len_model, pos_state ); - unsigned distance = rdec.decode_tree6( bm_dis_slot[get_len_state(len)] ); - if( distance >= start_dis_model ) + rep0 = rdec.decode_tree6( bm_dis_slot[get_len_state(len)] ); + if( rep0 >= start_dis_model ) { - const unsigned dis_slot = distance; + const unsigned dis_slot = rep0; const int direct_bits = ( dis_slot >> 1 ) - 1; - distance = ( 2 | ( dis_slot & 1 ) ) << direct_bits; + rep0 = ( 2 | ( dis_slot & 1 ) ) << direct_bits; if( dis_slot < end_dis_model ) - distance += rdec.decode_tree_reversed( - bm_dis + ( distance - dis_slot ), direct_bits ); + rep0 += rdec.decode_tree_reversed( bm_dis + ( rep0 - dis_slot ), + direct_bits ); else { - distance += - rdec.decode( direct_bits - dis_align_bits ) << dis_align_bits; - distance += rdec.decode_tree_reversed4( bm_align ); - if( distance == 0xFFFFFFFFU ) // marker found + rep0 += rdec.decode( direct_bits - dis_align_bits ) << dis_align_bits; + rep0 += rdec.decode_tree_reversed4( bm_align ); + if( rep0 == 0xFFFFFFFFU ) // marker found { rdec.normalize(); flush_data(); if( len == min_match_len ) // End Of Stream marker - return check_trailer( pp, cl_opts.ignore_empty ); - if( len == min_match_len + 1 ) // Sync Flush marker - { rdec.load(); continue; } - if( verbosity >= 0 ) - { - pp(); - std::fprintf( stderr, "Unsupported marker code '%d'\n", len ); - } + { if( check_trailer( pp ) ) return 0; else return 3; } + if( verbosity >= 0 ) { pp(); + std::fprintf( stderr, "Unsupported marker code '%d'\n", len ); } return 4; } } } - rep3 = rep2; rep2 = rep1; rep1 = rep0; rep0 = distance; state.set_match(); if( rep0 >= dictionary_size || ( rep0 >= pos && !pos_wrapped ) ) { flush_data(); return 1; } |