Disk ARchive  2.4.2
compressor.hpp
Go to the documentation of this file.
00001 /*********************************************************************/
00002 // dar - disk archive - a backup/restoration program
00003 // Copyright (C) 2002-2052 Denis Corbin
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 //
00019 // to contact the author : http://dar.linux.free.fr/email.html
00020 /*********************************************************************/
00021 // $Id: compressor.hpp,v 1.26 2011/04/17 13:12:29 edrusb Rel $
00022 //
00023 /*********************************************************************/
00027 
00028 #ifndef COMPRESSOR_HPP
00029 #define COMPRESSOR_HPP
00030 
00031 #include "../my_config.h"
00032 
00033 #include "infinint.hpp"
00034 #include "generic_file.hpp"
00035 #include "integers.hpp"
00036 #include "wrapperlib.hpp"
00037 
00038 namespace libdar
00039 {
00040 
00042 
00045     enum compression
00046     {
00047         none = 'n',  
00048         gzip = 'z',  
00049         bzip2 = 'y', 
00050         lzo = 'l'    
00051     };
00052 
00055 
00056     extern compression char2compression(char a);
00057     extern char compression2char(compression c);
00058     extern std::string compression2string(compression c);
00059     extern compression string2compression(const std::string & a); // throw Erange if an unknown string is given
00060 
00062     class compressor : public generic_file
00063     {
00064     public :
00065         compressor(compression algo, generic_file & compressed_side, U_I compression_level = 9);
00066             // compressed_side is not owned by the object and will remains
00067             // after the objet destruction
00068         compressor(compression algo, generic_file *compressed_side, U_I compression_level = 9);
00069             // compressed_side is owned by the object and will be
00070             // deleted a destructor time
00071         ~compressor();
00072 
00073         void flush_write(); // flush all data to compressed_side, and reset the compressor
00074             // for that additional write can be uncompresssed starting at this point.
00075         void flush_read(); // reset decompression engine to be able to read the next block of compressed data
00076             // if not called, furthur read return EOF
00077         void clean_read(); // discard any byte buffered and not yet returned by read()
00078         void clean_write(); // discard any byte buffered and not yet wrote to compressed_side;
00079 
00080         compression get_algo() const { return current_algo; };
00081 
00083 
00088         void change_algo(compression new_algo, U_I new_compression_level);
00089 
00090 
00092 
00093         void change_algo(compression new_algo)
00094         {
00095             change_algo(new_algo, current_level);
00096         };
00097 
00098             // inherited from generic file
00099         bool skip(const infinint & pos) { flush_write(); flush_read(); clean_read(); return compressed->skip(pos); };
00100         bool skip_to_eof()  { flush_write(); flush_read(); clean_read(); return compressed->skip_to_eof(); };
00101         bool skip_relative(S_I x) { flush_write(); flush_read(); clean_read(); return compressed->skip_relative(x); };
00102         infinint get_position() { return compressed->get_position(); };
00103 
00104     protected :
00105         U_I inherited_read(char *a, U_I size) { return (this->*read_ptr)(a, size); };
00106         void inherited_write(const char *a, U_I size) { (this->*write_ptr)(a, size); };
00107         void inherited_sync_write() { flush_write(); };
00108         void inherited_terminate() { local_terminate(); };
00109     private :
00110         struct xfer
00111         {
00112             wrapperlib wrap;
00113             char *buffer;
00114             U_I size;
00115 
00116             xfer(U_I sz, wrapperlib_mode mode);
00117             ~xfer();
00118         };
00119 
00120         struct lzo_block_header
00121         {
00122             char type;             //< let the possibility to extend this architecture (for now type is fixed)
00123             infinint size;         //< size of the following compressed block of data
00124 
00125             void dump(generic_file & f);
00126             void set_from(generic_file & f);
00127         };
00128 
00129 
00130         xfer *compr, *decompr;     //< datastructure for bzip2 an gzip compression
00131 
00132         char *lzo_read_buffer;     //< stores clear data (uncompressed) read from the compressed generic_file
00133         char *lzo_write_buffer;    //< stores the clear data to be compressed and written to the compressed generic_file
00134         U_I lzo_read_size;         //< number of available bytes in the read buffer for lzo decompression
00135         U_I lzo_write_size;        //< number of available bytes to compress and next place where to add more data in the wite buffer
00136         U_I lzo_read_start;        //< location of the next byte to read out from the read buffer
00137         bool lzo_write_flushed;    //< whether write flushing has been done
00138         bool lzo_read_reached_eof; //< whether reading reached end of file and the lzo engine has to be reset to uncompress further data
00139         char *lzo_compressed;      //< compressed data just read or about to be written
00140         char *lzo_wrkmem;          //< work memory for LZO library
00141 
00142         generic_file *compressed;
00143         bool compressed_owner;
00144         compression current_algo;
00145         U_I current_level;
00146 
00147         void init(compression algo, generic_file *compressed_side, U_I compression_level);
00148         void local_terminate();
00149         U_I (compressor::*read_ptr) (char *a, U_I size);
00150         U_I none_read(char *a, U_I size);
00151         U_I gzip_read(char *a, U_I size);
00152             // U_I zip_read(char *a, U_I size);
00153             // U_I bzip2_read(char *a, U_I size); // using gzip_read, same code thanks to wrapperlib
00154         U_I lzo_read(char *a, U_I size);
00155 
00156         void (compressor::*write_ptr) (const char *a, U_I size);
00157         void none_write(const char *a, U_I size);
00158         void gzip_write(const char *a, U_I size);
00159             // void zip_write(char *a, U_I size);
00160             // void bzip2_write(char *a, U_I size); // using gzip_write, same code thanks to wrapperlib
00161         void lzo_write(const char *a, U_I size);
00162 
00163         void lzo_compress_buffer_and_write();
00164         void lzo_read_and_uncompress_to_buffer();
00165     };
00166 
00168 
00169 } // end of namespace
00170 
00171 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines