Disk ARchive  2.4.12
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
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 
00025 
00026 #ifndef COMPRESSOR_HPP
00027 #define COMPRESSOR_HPP
00028 
00029 #include "../my_config.h"
00030 
00031 #include "infinint.hpp"
00032 #include "generic_file.hpp"
00033 #include "integers.hpp"
00034 #include "wrapperlib.hpp"
00035 
00036 namespace libdar
00037 {
00038 
00040 
00043     enum compression
00044     {
00045         none = 'n',  
00046         gzip = 'z',  
00047         bzip2 = 'y', 
00048         lzo = 'l'    
00049     };
00050 
00053 
00054     extern compression char2compression(char a);
00055     extern char compression2char(compression c);
00056     extern std::string compression2string(compression c);
00057     extern compression string2compression(const std::string & a); // throw Erange if an unknown string is given
00058 
00060     class compressor : public generic_file
00061     {
00062     public :
00063         compressor(compression algo, generic_file & compressed_side, U_I compression_level = 9);
00064             // compressed_side is not owned by the object and will remains
00065             // after the objet destruction
00066         compressor(compression algo, generic_file *compressed_side, U_I compression_level = 9);
00067             // compressed_side is owned by the object and will be
00068             // deleted a destructor time
00069         ~compressor();
00070 
00071         void flush_write(); // flush all data to compressed_side, and reset the compressor
00072             // for that additional write can be uncompresssed starting at this point.
00073         void flush_read(); // reset decompression engine to be able to read the next block of compressed data
00074             // if not called, furthur read return EOF
00075         void clean_read(); // discard any byte buffered and not yet returned by read()
00076         void clean_write(); // discard any byte buffered and not yet wrote to compressed_side;
00077 
00078         compression get_algo() const { return current_algo; };
00079 
00081 
00086         void change_algo(compression new_algo, U_I new_compression_level);
00087 
00088 
00090 
00091         void change_algo(compression new_algo)
00092         {
00093             change_algo(new_algo, current_level);
00094         };
00095 
00096             // inherited from generic file
00097         bool skip(const infinint & pos) { flush_write(); flush_read(); clean_read(); return compressed->skip(pos); };
00098         bool skip_to_eof()  { flush_write(); flush_read(); clean_read(); return compressed->skip_to_eof(); };
00099         bool skip_relative(S_I x) { flush_write(); flush_read(); clean_read(); return compressed->skip_relative(x); };
00100         infinint get_position() { return compressed->get_position(); };
00101 
00102     protected :
00103         U_I inherited_read(char *a, U_I size) { return (this->*read_ptr)(a, size); };
00104         void inherited_write(const char *a, U_I size) { (this->*write_ptr)(a, size); };
00105         void inherited_sync_write() { flush_write(); };
00106         void inherited_terminate() { local_terminate(); };
00107     private :
00108         struct xfer
00109         {
00110             wrapperlib wrap;
00111             char *buffer;
00112             U_I size;
00113 
00114             xfer(U_I sz, wrapperlib_mode mode);
00115             ~xfer();
00116         };
00117 
00118         struct lzo_block_header
00119         {
00120             char type;             //< let the possibility to extend this architecture (for now type is fixed)
00121             infinint size;         //< size of the following compressed block of data
00122 
00123             void dump(generic_file & f);
00124             void set_from(generic_file & f);
00125         };
00126 
00127 
00128         xfer *compr, *decompr;     //< datastructure for bzip2 an gzip compression
00129 
00130         char *lzo_read_buffer;     //< stores clear data (uncompressed) read from the compressed generic_file
00131         char *lzo_write_buffer;    //< stores the clear data to be compressed and written to the compressed generic_file
00132         U_I lzo_read_size;         //< number of available bytes in the read buffer for lzo decompression
00133         U_I lzo_write_size;        //< number of available bytes to compress and next place where to add more data in the wite buffer
00134         U_I lzo_read_start;        //< location of the next byte to read out from the read buffer
00135         bool lzo_write_flushed;    //< whether write flushing has been done
00136         bool lzo_read_reached_eof; //< whether reading reached end of file and the lzo engine has to be reset to uncompress further data
00137         char *lzo_compressed;      //< compressed data just read or about to be written
00138         char *lzo_wrkmem;          //< work memory for LZO library
00139 
00140         generic_file *compressed;
00141         bool compressed_owner;
00142         compression current_algo;
00143         U_I current_level;
00144 
00145         void init(compression algo, generic_file *compressed_side, U_I compression_level);
00146         void local_terminate();
00147         U_I (compressor::*read_ptr) (char *a, U_I size);
00148         U_I none_read(char *a, U_I size);
00149         U_I gzip_read(char *a, U_I size);
00150             // U_I zip_read(char *a, U_I size);
00151             // U_I bzip2_read(char *a, U_I size); // using gzip_read, same code thanks to wrapperlib
00152         U_I lzo_read(char *a, U_I size);
00153 
00154         void (compressor::*write_ptr) (const char *a, U_I size);
00155         void none_write(const char *a, U_I size);
00156         void gzip_write(const char *a, U_I size);
00157             // void zip_write(char *a, U_I size);
00158             // void bzip2_write(char *a, U_I size); // using gzip_write, same code thanks to wrapperlib
00159         void lzo_write(const char *a, U_I size);
00160 
00161         void lzo_compress_buffer_and_write();
00162         void lzo_read_and_uncompress_to_buffer();
00163     };
00164 
00166 
00167 } // end of namespace
00168 
00169 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines