summaryrefslogtreecommitdiffstats
path: root/decoder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'decoder.cc')
-rw-r--r--decoder.cc289
1 files changed, 0 insertions, 289 deletions
diff --git a/decoder.cc b/decoder.cc
deleted file mode 100644
index 0d8d4d5..0000000
--- a/decoder.cc
+++ /dev/null
@@ -1,289 +0,0 @@
-/* Lzlib - A compression library for lzip files
- Copyright (C) 2009, 2010, 2011 Antonio Diaz Diaz.
-
- This library is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this library. If not, see <http://www.gnu.org/licenses/>.
-
- As a special exception, you may use this file as part of a free
- software library without restriction. Specifically, if other files
- instantiate templates or use macros or inline functions from this
- file, or you compile this file and link it with other files to
- produce an executable, this file does not by itself cause the
- resulting executable to be covered by the GNU General Public
- License. This exception does not however invalidate any other
- reasons why the executable file might be covered by the GNU General
- Public License.
-*/
-
-#define _FILE_OFFSET_BITS 64
-
-#include <algorithm>
-#include <cerrno>
-#include <cstdlib>
-#include <cstring>
-#include <stdint.h>
-
-#include "lzlib.h"
-#include "lzip.h"
-#include "decoder.h"
-
-
-namespace Lzlib {
-
-const CRC32 crc32;
-
-// Seeks a member header and updates `get'.
-// Returns true if it finds a valid header.
-bool Range_decoder::find_header() throw()
- {
- while( get != put )
- {
- if( buffer[get] == magic_string[0] )
- {
- int g = get;
- File_header header;
- for( int i = 0; i < File_header::size; ++i )
- {
- if( g == put ) return false; // not enough data
- header.data[i] = buffer[g];
- if( ++g >= buffer_size ) g = 0;
- }
- if( header.verify() ) return true;
- }
- if( ++get >= buffer_size ) get = 0;
- }
- return false;
- }
-
-
-// Returns true, fills `header', and updates `get' if `get' points to a
-// valid header.
-// Else returns false and leaves `get' unmodified.
-bool Range_decoder::read_header( File_header & header ) throw()
- {
- int g = get;
- for( int i = 0; i < File_header::size; ++i )
- {
- if( g == put ) return false; // not enough data
- header.data[i] = buffer[g];
- if( ++g >= buffer_size ) g = 0;
- }
- if( header.verify() )
- {
- get = g;
- member_pos = File_header::size;
- reload_pending = true;
- return true;
- }
- return false;
- }
-
-
-bool LZ_decoder::verify_trailer()
- {
- File_trailer trailer;
- const int trailer_size = File_trailer::size( member_version );
- const long long member_size = range_decoder.member_position() + trailer_size;
- bool error = false;
-
- for( int i = 0; i < trailer_size && !error; ++i )
- {
- if( !range_decoder.finished() )
- trailer.data[i] = range_decoder.get_byte();
- else
- {
- error = true;
- for( ; i < trailer_size; ++i ) trailer.data[i] = 0;
- }
- }
- if( member_version == 0 ) trailer.member_size( member_size );
- if( !range_decoder.code_is_zero() ) error = true;
- if( trailer.data_crc() != crc() ) error = true;
- if( trailer.data_size() != data_position() ) error = true;
- if( trailer.member_size() != member_size ) error = true;
- return !error;
- }
-
-
- // Return value: 0 = OK, 1 = decoder error, 2 = unexpected EOF,
- // 3 = trailer error, 4 = unknown marker found.
-int LZ_decoder::decode_member()
- {
- if( member_finished_ ) return 0;
- if( !range_decoder.try_reload() ) return 0;
- if( verify_trailer_pending )
- {
- if( range_decoder.available_bytes() < File_trailer::size( member_version ) &&
- !range_decoder.at_stream_end() )
- return 0;
- verify_trailer_pending = false;
- member_finished_ = true;
- if( verify_trailer() ) return 0; else return 3;
- }
- while( true )
- {
- if( range_decoder.finished() ) return 2;
- if( !range_decoder.enough_available_bytes() || !enough_free_bytes() )
- return 0;
- const int pos_state = data_position() & pos_state_mask;
- if( range_decoder.decode_bit( bm_match[state()][pos_state] ) == 0 )
- {
- const uint8_t prev_byte = get_prev_byte();
- if( state.is_char() )
- put_byte( literal_decoder.decode( range_decoder, prev_byte ) );
- else
- put_byte( literal_decoder.decode_matched( range_decoder, prev_byte,
- get_byte( rep0 ) ) );
- state.set_char();
- }
- else
- {
- int len;
- if( range_decoder.decode_bit( bm_rep[state()] ) == 1 )
- {
- len = 0;
- if( range_decoder.decode_bit( bm_rep0[state()] ) == 1 )
- {
- unsigned int distance;
- if( range_decoder.decode_bit( bm_rep1[state()] ) == 0 )
- distance = rep1;
- else
- {
- if( range_decoder.decode_bit( bm_rep2[state()] ) == 0 )
- distance = rep2;
- else { distance = rep3; rep3 = rep2; }
- rep2 = rep1;
- }
- rep1 = rep0;
- rep0 = distance;
- }
- else
- {
- if( range_decoder.decode_bit( bm_len[state()][pos_state] ) == 0 )
- { state.set_short_rep(); len = 1; }
- }
- if( len == 0 )
- {
- state.set_rep();
- len = min_match_len + rep_match_len_decoder.decode( range_decoder, pos_state );
- }
- }
- else
- {
- const unsigned int rep0_saved = rep0;
- len = min_match_len + len_decoder.decode( range_decoder, pos_state );
- const int dis_slot = range_decoder.decode_tree( bm_dis_slot[get_dis_state(len)], dis_slot_bits );
- if( dis_slot < start_dis_model ) rep0 = dis_slot;
- else
- {
- const int direct_bits = ( dis_slot >> 1 ) - 1;
- rep0 = ( 2 | ( dis_slot & 1 ) ) << direct_bits;
- if( dis_slot < end_dis_model )
- rep0 += range_decoder.decode_tree_reversed( bm_dis + rep0 - dis_slot, direct_bits );
- else
- {
- rep0 += range_decoder.decode( direct_bits - dis_align_bits ) << dis_align_bits;
- rep0 += range_decoder.decode_tree_reversed( bm_align, dis_align_bits );
- if( rep0 == 0xFFFFFFFFU ) // Marker found
- {
- rep0 = rep0_saved;
- range_decoder.normalize();
- if( len == min_match_len ) // End Of Stream marker
- {
- if( range_decoder.available_bytes() < File_trailer::size( member_version ) &&
- !range_decoder.at_stream_end() )
- { verify_trailer_pending = true; return 0; }
- member_finished_ = true;
- if( verify_trailer() ) return 0; else return 3;
- }
- if( len == min_match_len + 1 ) // Sync Flush marker
- {
- if( range_decoder.try_reload( true ) ) continue;
- else return 0;
- }
- return 4;
- }
- }
- }
- rep3 = rep2; rep2 = rep1; rep1 = rep0_saved;
- state.set_match();
- if( rep0 >= (unsigned int)dictionary_size ||
- ( rep0 >= (unsigned int)put && !partial_data_pos ) )
- return 1;
- }
- copy_block( rep0, len );
- }
- }
- }
-
-
-// Copies up to `out_size' bytes to `out_buffer' and updates `get'.
-// Returns the number of bytes copied.
-int Circular_buffer::read_data( uint8_t * const out_buffer, const int out_size ) throw()
- {
- if( out_size < 0 ) return 0;
- int size = 0;
- if( get > put )
- {
- size = std::min( buffer_size - get, out_size );
- if( size > 0 )
- {
- std::memcpy( out_buffer, buffer + get, size );
- get += size;
- if( get >= buffer_size ) get = 0;
- }
- }
- if( get < put )
- {
- const int size2 = std::min( put - get, out_size - size );
- if( size2 > 0 )
- {
- std::memcpy( out_buffer + size, buffer + get, size2 );
- get += size2;
- size += size2;
- }
- }
- return size;
- }
-
-
-// Copies up to `in_size' bytes from `in_buffer' and updates `put'.
-// Returns the number of bytes copied.
-int Circular_buffer::write_data( const uint8_t * const in_buffer, const int in_size ) throw()
- {
- if( in_size < 0 ) return 0;
- int size = 0;
- if( put >= get )
- {
- size = std::min( buffer_size - put - (get == 0), in_size );
- if( size > 0 )
- {
- std::memcpy( buffer + put, in_buffer, size );
- put += size;
- if( put >= buffer_size ) put = 0;
- }
- }
- if( put < get )
- {
- const int size2 = std::min( get - put - 1, in_size - size );
- if( size2 > 0 )
- {
- std::memcpy( buffer + put, in_buffer + size, size2 );
- put += size2;
- size += size2;
- }
- }
- return size;
- }
-
-} // end namespace Lzlib