Disk ARchive  2.5.2
Full featured and portable backup and archiving tool
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     xz = 'x'     
00050     };
00051 
00054 
00055     extern compression char2compression(char a);
00056     extern char compression2char(compression c);
00057     extern std::string compression2string(compression c);
00058     extern compression string2compression(const std::string & a); // throw Erange if an unknown string is given
00059 
00061     class compressor : public generic_file
00062     {
00063     public :
00064         compressor(compression algo, generic_file & compressed_side, U_I compression_level = 9);
00065             // compressed_side is not owned by the object and will remains
00066             // after the objet destruction
00067         compressor(compression algo, generic_file *compressed_side, U_I compression_level = 9);
00068             // compressed_side is owned by the object and will be
00069             // deleted a destructor time
00070         ~compressor();
00071 
00072         compression get_algo() const { return current_algo; };
00073 
00074     void suspend_compression();
00075     void resume_compression();
00076     bool is_compression_suspended() const { return suspended; };
00077 
00078 
00079             // inherited from generic file
00080     bool skippable(skippability direction, const infinint & amount) { return compressed->skippable(direction, amount); };
00081         bool skip(const infinint & pos) { compr_flush_write(); compr_flush_read(); clean_read(); return compressed->skip(pos); };
00082         bool skip_to_eof()  { compr_flush_write(); compr_flush_read(); clean_read(); return compressed->skip_to_eof(); };
00083         bool skip_relative(S_I x) { compr_flush_write(); compr_flush_read(); clean_read(); return compressed->skip_relative(x); };
00084         infinint get_position() const { return compressed->get_position(); };
00085 
00086     protected :
00087     void inherited_read_ahead(const infinint & amount) { compressed->read_ahead(amount); };
00088         U_I inherited_read(char *a, U_I size) { return (this->*read_ptr)(a, size); };
00089         void inherited_write(const char *a, U_I size) { (this->*write_ptr)(a, size); };
00090     void inherited_sync_write() { compr_flush_write(); };
00091     void inherited_flush_read() { compr_flush_read(); clean_read(); };
00092     void inherited_terminate() { local_terminate(); };
00093 
00094     private :
00095         struct xfer : public on_pool
00096         {
00097             wrapperlib wrap;
00098             char *buffer;
00099             U_I size;
00100 
00101             xfer(U_I sz, wrapperlib_mode mode);
00102             ~xfer();
00103         };
00104 
00105     struct lzo_block_header
00106     {
00107         char type;             //< let the possibility to extend this architecture (for now type is fixed)
00108         infinint size;         //< size of the following compressed block of data
00109 
00110         void dump(generic_file & f);
00111         void set_from(generic_file & f);
00112     };
00113 
00114 
00115         xfer *compr, *decompr;     //< datastructure for bzip2 an gzip compression
00116 
00117     char *lzo_read_buffer;     //< stores clear data (uncompressed) read from the compressed generic_file
00118     char *lzo_write_buffer;    //< stores the clear data to be compressed and written to the compressed generic_file
00119     U_I lzo_read_size;         //< number of available bytes in the read buffer for lzo decompression
00120     U_I lzo_write_size;        //< number of available bytes to compress and next place where to add more data in the wite buffer
00121     U_I lzo_read_start;        //< location of the next byte to read out from the read buffer
00122     bool lzo_write_flushed;    //< whether write flushing has been done
00123     bool lzo_read_reached_eof; //< whether reading reached end of file and the lzo engine has to be reset to uncompress further data
00124     char *lzo_compressed;      //< compressed data just read or about to be written
00125     char *lzo_wrkmem;          //< work memory for LZO library
00126 
00127         generic_file *compressed;
00128         bool compressed_owner;
00129         compression current_algo;
00130     bool suspended;
00131     compression suspended_compr;
00132     U_I current_level;
00133 
00134         void init(compression algo, generic_file *compressed_side, U_I compression_level);
00135         void local_terminate();
00136         U_I (compressor::*read_ptr) (char *a, U_I size);
00137         U_I none_read(char *a, U_I size);
00138         U_I gzip_read(char *a, U_I size);
00139             // U_I zip_read(char *a, U_I size);
00140             // U_I bzip2_read(char *a, U_I size); // using gzip_read, same code thanks to wrapperlib
00141     U_I lzo_read(char *a, U_I size);
00142 
00143         void (compressor::*write_ptr) (const char *a, U_I size);
00144         void none_write(const char *a, U_I size);
00145         void gzip_write(const char *a, U_I size);
00146             // void zip_write(char *a, U_I size);
00147             // void bzip2_write(char *a, U_I size); // using gzip_write, same code thanks to wrapperlib
00148     void lzo_write(const char *a, U_I size);
00149 
00150     void lzo_compress_buffer_and_write();
00151     void lzo_read_and_uncompress_to_buffer();
00152 
00154 
00159         void change_algo(compression new_algo, U_I new_compression_level);
00160 
00161 
00163 
00164         void change_algo(compression new_algo)
00165     { change_algo(new_algo, current_level); };
00166 
00167 
00168         void compr_flush_write(); // flush all data to compressed_side, and reset the compressor
00169             // for that additional write can be uncompresssed starting at this point.
00170         void compr_flush_read(); // reset decompression engine to be able to read the next block of compressed data
00171             // if not called, furthur read return EOF
00172         void clean_read(); // discard any byte buffered and not yet returned by read()
00173         void clean_write(); // discard any byte buffered and not yet wrote to compressed_side;
00174     };
00175 
00177 
00178 } // end of namespace
00179 
00180 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines