compress.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:15k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: compress.hpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:39:20  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef UTIL_COMPRESS__COMPRESS__HPP
  10. #define UTIL_COMPRESS__COMPRESS__HPP
  11. /*  $Id: compress.hpp,v 1000.2 2004/06/01 19:39:20 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software/database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software/database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Author:  Vladimir Ivanov
  37.  *
  38.  * File Description:  The Compression API
  39.  *
  40.  */
  41. #include <corelib/ncbistd.hpp>
  42. /** @addtogroup Compression
  43.  *
  44.  * @{
  45.  */
  46. BEGIN_NCBI_SCOPE
  47. // Default compression I/O stream buffer size
  48. const streamsize kCompressionDefaultBufSize = 16*1024;
  49. /////////////////////////////////////////////////////////////////////////////
  50. //
  51. // CCompressionException
  52. //
  53. //  Exceptions generated by CCompresson and derived classes
  54. //
  55. class NCBI_XUTIL_EXPORT CCompressionException : public CCoreException
  56. {
  57. public:
  58.     enum EErrCode {
  59.         eCompression,      // Compression/decompression error
  60.         eCompressionFile   // Compression/decompression file error
  61.     };
  62.     virtual const char* GetErrCodeString(void) const
  63.     {
  64.         switch (GetErrCode()) {
  65.         case eCompression     : return "eCompression";
  66.         case eCompressionFile : return "eCompressionFile";
  67.         default               : return CException::GetErrCodeString();
  68.         }
  69.     }
  70.     NCBI_EXCEPTION_DEFAULT(CCompressionException,CCoreException);
  71. };
  72. // Forward declaration
  73. class CCompressionFile;
  74. class CCompressionStreambuf;
  75. //////////////////////////////////////////////////////////////////////////////
  76. //
  77. // CCompression -- abstract base class
  78. //
  79. class NCBI_XUTIL_EXPORT CCompression
  80. {
  81. public:
  82.     // Compression level.
  83.     // It is in range [0..9]. Increase of level might mean better compression
  84.     // and usualy greater time of compression. Usualy 1 gives best speed,
  85.     // 9 gives best compression, 0 gives no compression at all.
  86.     // eDefault value requests a compromise between speed and compression
  87.     // (according to developers of the corresponding compression algorithm).
  88.     enum ELevel {
  89.         eLevel_Default       = -1,  // default
  90.         eLevel_NoCompression =  0,  // just store data
  91.         eLevel_Lowest        =  1,
  92.         eLevel_VeryLow       =  2,
  93.         eLevel_Low           =  3,
  94.         eLevel_MediumLow     =  4,
  95.         eLevel_Medium        =  5,
  96.         eLevel_MediumHigh    =  6,
  97.         eLevel_High          =  7,
  98.         eLevel_VeryHigh      =  8,
  99.         eLevel_Best          =  9
  100.     };
  101.     // Compression flags. The flag selection depends from realization.
  102.     typedef int TFlags;
  103.     // 'ctors
  104.     CCompression(ELevel level = eLevel_Default);
  105.     virtual ~CCompression(void);
  106.     // Get/set compression level.
  107.     // NOTE 1:  Changing compression level after compression has begun will
  108.     //          be ignored.
  109.     // NOTE 2:  If the level is not supported by the underlying algorithm,
  110.     //          then it will be translated to the nearest supported value.
  111.     void SetLevel(ELevel level);
  112.     virtual ELevel GetLevel(void) const;
  113.     // Return the default compression level for current compression algorithm
  114.     virtual ELevel GetDefaultLevel(void) const = 0;
  115.     // Get compressor's internal status/error code and description
  116.     // for the last operation.
  117.     int    GetErrorCode(void) const;
  118.     string GetErrorDescription(void) const;
  119.     // Get/set flags
  120.     TFlags GetFlags(void) const;
  121.     void SetFlags(TFlags flags);
  122.     //
  123.     // Utility functions 
  124.     //
  125.     // (De)compress the source buffer into the destination buffer.
  126.     // Return TRUE on success, FALSE on error.
  127.     // The compressor error code can be acquired via GetLastError() call.
  128.     // Notice that altogether the total size of the destination buffer must
  129.     // be little more then size of the source buffer. 
  130.     virtual bool CompressBuffer(
  131.         const void* src_buf, unsigned int  src_len,
  132.         void*       dst_buf, unsigned int  dst_size,
  133.         /* out */            unsigned int* dst_len
  134.     ) = 0;
  135.     virtual bool DecompressBuffer(
  136.         const void* src_buf, unsigned int  src_len,
  137.         void*       dst_buf, unsigned int  dst_size,
  138.         /* out */            unsigned int* dst_len
  139.     ) = 0;
  140.     
  141.     // (De)compress file "src_file" and put result to file "dst_file".
  142.     // Return TRUE on success, FALSE on error.
  143.     virtual bool CompressFile(
  144.         const string&     src_file,
  145.         const string&     dst_file,
  146.         size_t            buf_size = kCompressionDefaultBufSize
  147.     ) = 0;
  148.     virtual bool DecompressFile(
  149.         const string&     src_file,
  150.         const string&     dst_file, 
  151.         size_t            buf_size = kCompressionDefaultBufSize
  152.     ) = 0;
  153. protected:
  154.     // Set last compressor's action error/status code and description
  155.     void SetError(int status, const char* description = 0);
  156. protected:
  157.     // Universal file compression/decompression functions.
  158.     // Return TRUE on success, FALSE on error.
  159.     virtual bool x_CompressFile(
  160.         const string&     src_file,
  161.         CCompressionFile& dst_file,
  162.         size_t            buf_size = kCompressionDefaultBufSize
  163.     );
  164.     virtual bool x_DecompressFile(
  165.         CCompressionFile& src_file,
  166.         const string&     dst_file,
  167.         size_t            buf_size = kCompressionDefaultBufSize
  168.     );
  169. private:
  170.     ELevel  m_Level;      // Compression level
  171.     int     m_ErrorCode;  // Last compressor action error/status
  172.     string  m_ErrorMsg;   // Last compressor action error message
  173.     TFlags  m_Flags;      // Bitwise OR of flags
  174.  
  175.     // Friend classes
  176.     friend class CCompressionStreambuf;
  177. };
  178. //////////////////////////////////////////////////////////////////////////////
  179. //
  180. // CCompressionFile -- abstract base class
  181. //
  182. // Class for support work with compressed files.
  183. // Assumed that file on hard disk is always compressed and data in memory
  184. // is uncompressed. 
  185. //
  186. class NCBI_XUTIL_EXPORT CCompressionFile
  187. {
  188. public:
  189.     // Compression file hadler
  190.     typedef void* TFile;
  191.     // File open mode
  192.     enum EMode {
  193.         eMode_Read,   // for reading from compressed file
  194.         eMode_Write   // for writing compressed data to file
  195.     };
  196.     // 'ctors
  197.     CCompressionFile(void);
  198.     //CCompressionFile(const string& path, EMode mode) = 0; 
  199.     virtual ~CCompressionFile(void);
  200.     // Opens a compressed file for reading or writing.
  201.     // Return NULL if error has been occurred.
  202.     virtual bool Open(const string& path, EMode mode) = 0; 
  203.     // Read up to "len" uncompressed bytes from the compressed file "file"
  204.     // into the buffer "buf". Return the number of bytes actually read
  205.     // (0 for end of file, -1 for error)
  206.     virtual int Read(void* buf, int len) = 0;
  207.     // Writes the given number of uncompressed bytes into the compressed file.
  208.     // Return the number of bytes actually written or -1 for error.
  209.     virtual int Write(const void* buf, int len) = 0;
  210.     // Flushes all pending output if necessary, closes the compressed file.
  211.     // Return TRUE on success, FALSE on error.
  212.     virtual bool Close(void) = 0;
  213. protected:
  214.     TFile  m_File;   // File handler
  215.     EMode  m_Mode;   // File open mode
  216. };
  217. //////////////////////////////////////////////////////////////////////////////
  218. //
  219. // CCompressionProcessor -- abstract base class
  220. //
  221. // Contains a functions for service a compression/decompression session.
  222. //
  223. class NCBI_XUTIL_EXPORT CCompressionProcessor
  224. {
  225. public:
  226.     // Type of the result of all basic functions
  227.     enum EStatus {
  228.         // Everything is fine, no errors occurred
  229.         eStatus_Success,
  230.         // Special case of eStatus_Success.
  231.         // Logical end of (compressed) stream is detected, no errors occurred.
  232.         // All subsequent inquiries about data processing should be ignored.
  233.         eStatus_EndOfData,
  234.         // Error has occurred. The error code can be acquired by GetLastError.
  235.         eStatus_Error,
  236.         // Output buffer overflow - not enough output space.
  237.         // Buffer must be emptied and the last action repeated.
  238.         eStatus_Overflow
  239.     };
  240.     // 'ctors
  241.     CCompressionProcessor(void);
  242.     virtual ~CCompressionProcessor(void);
  243.     // Return compressor's busy flag. If returns value is true that
  244.     // the current compression object already have being use in other
  245.     // compression session.
  246.     bool IsBusy(void) const;
  247.     // Return number of processed/output bytes.
  248.     unsigned long GetProcessedSize(void);
  249.     unsigned long GetOutputSize(void);
  250. protected:
  251.     // Initialize the internal stream state for compression/decompression.
  252.     // It does not perform any compression, this will be done by Process().
  253.     virtual EStatus Init(void) = 0;
  254.     // Compress/decompress as much data as possible, and stops when the input
  255.     // buffer becomes empty or the output buffer becomes full. It may
  256.     // introduce some output latency (reading input without producing any
  257.     // output).
  258.     virtual EStatus Process
  259.     (const char*    in_buf,      // [in]  input buffer 
  260.      unsigned long  in_len,      // [in]  input data length
  261.      char*          out_buf,     // [in]  output buffer
  262.      unsigned long  out_size,    // [in]  output buffer size
  263.      unsigned long* in_avail,    // [out] count unproc.bytes in input buffer
  264.      unsigned long* out_avail    // [out] count bytes putted into out buffer
  265.      ) = 0;
  266.     // Flush compressed/decompressed data from the output buffer. 
  267.     // Flushing may degrade compression for some compression algorithms
  268.     // and so it should be used only when necessary.
  269.     virtual EStatus Flush
  270.     (char*          out_buf,     // [in]  output buffer
  271.      unsigned long  out_size,    // [in]  output buffer size
  272.      unsigned long* out_avail    // [out] count bytes putted into out buffer
  273.      ) = 0;
  274.     // Finish the compression/decompression process.
  275.     // Process pending input, flush pending output.
  276.     // This function slightly like to Flush(), but it must be called only
  277.     // at the end of compression process before End().
  278.     virtual EStatus Finish
  279.     (char*          out_buf,     // [in]  output buffer
  280.      unsigned long  out_size,    // [in]  output buffer size
  281.      unsigned long* out_avail    // [out] count bytes putted into out buffer
  282.      ) = 0;
  283.     // Free all dynamically allocated data structures.
  284.     // This function discards any unprocessed input and does not flush
  285.     // any pending output.
  286.     virtual EStatus End(void) = 0;
  287. protected:
  288.     // Reset internal state
  289.     void Reset(void);
  290.     // Set/unset compressor busy flag
  291.     void SetBusy(bool busy = true);
  292.     // Increase number of processed/output bytes.
  293.     void IncreaseProcessedSize(unsigned long n_bytes);
  294.     void IncreaseOutputSize(unsigned long n_bytes);
  295. private:
  296.     unsigned long m_ProcessedSize; //< The number of processed bytes
  297.     unsigned long m_OutputSize;    //< The number of output bytes
  298.     bool          m_Busy;          //< Is true if compressor is ready to begin
  299.                                    //< next session
  300.     // Friend classes
  301.     friend class CCompressionStream;
  302.     friend class CCompressionStreambuf;
  303. };
  304. /* @} */
  305. //
  306. // Inline functions
  307. //
  308. inline
  309. void CCompression::SetLevel(ELevel level)
  310. {
  311.     m_Level = level;
  312. }
  313. inline
  314. int CCompression::GetErrorCode(void) const
  315. {
  316.     return m_ErrorCode;
  317. }
  318. inline
  319. string CCompression::GetErrorDescription(void) const
  320. {
  321.     return m_ErrorMsg;
  322. }
  323. inline
  324. void CCompression::SetError(int errcode, const char* description)
  325. {
  326.     m_ErrorCode = errcode;
  327.     m_ErrorMsg  = description ? description : kEmptyStr;
  328. }
  329. inline
  330. CCompression::TFlags CCompression::GetFlags(void) const
  331. {
  332.     return m_Flags;
  333. }
  334. inline
  335. void CCompression::SetFlags(TFlags flags)
  336. {
  337.     m_Flags = flags;
  338. }
  339. inline
  340. void CCompressionProcessor::Reset(void)
  341. {
  342.     m_ProcessedSize  = 0;
  343.     m_OutputSize     = 0;
  344.     m_Busy           = false;
  345. }
  346. inline
  347. bool CCompressionProcessor::IsBusy(void) const
  348. {
  349.     return m_Busy;
  350. }
  351. inline
  352. void CCompressionProcessor::SetBusy(bool busy)
  353. {
  354.     if ( busy  &&  m_Busy ) {
  355.         NCBI_THROW(CCompressionException, eCompression,
  356.                    "CCompression::SetBusy(): The compressor is busy now");
  357.     }
  358.     m_Busy = busy;
  359. }
  360. inline
  361. void CCompressionProcessor::IncreaseProcessedSize(unsigned long n_bytes)
  362. {
  363.     if (n_bytes > 0) {
  364.         m_ProcessedSize += n_bytes;
  365.     }
  366. }
  367. inline
  368. void CCompressionProcessor::IncreaseOutputSize(unsigned long n_bytes)
  369. {
  370.     if (n_bytes > 0) {
  371.         m_OutputSize += n_bytes;
  372.     }
  373. }
  374. inline
  375. unsigned long CCompressionProcessor::GetProcessedSize(void)
  376. {
  377.     return m_ProcessedSize;
  378. }
  379. inline
  380. unsigned long CCompressionProcessor::GetOutputSize(void)
  381. {
  382.     return m_OutputSize;
  383. }
  384. END_NCBI_SCOPE
  385. /*
  386.  * ===========================================================================
  387.  * $Log: compress.hpp,v $
  388.  * Revision 1000.2  2004/06/01 19:39:20  gouriano
  389.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  390.  *
  391.  * Revision 1.8  2004/05/10 11:56:24  ivanov
  392.  * Added gzip file format support
  393.  *
  394.  * Revision 1.7  2004/04/01 14:14:02  lavr
  395.  * Spell "occurred", "occurrence", and "occurring"
  396.  *
  397.  * Revision 1.6  2003/07/15 15:50:00  ivanov
  398.  * Improved error diagnostics. Renamed GetLastError() -> GetErrorCode().
  399.  * Added GetErrorDescription(). Added second parameter for SetError().
  400.  * Added new status value - eStatus_EndOfData.
  401.  *
  402.  * Revision 1.5  2003/07/10 16:19:25  ivanov
  403.  * Added kCompressionDefaultBufSize definition from stream.hpp.
  404.  * Added auxiliary file compression/decompression functions.
  405.  *
  406.  * Revision 1.4  2003/06/03 20:09:54  ivanov
  407.  * The Compression API redesign. Added some new classes, rewritten old.
  408.  *
  409.  * Revision 1.3  2003/04/11 19:57:25  ivanov
  410.  * Move streambuf.hpp from 'include/...' to 'src/...'
  411.  *
  412.  * Revision 1.2  2003/04/08 20:48:51  ivanov
  413.  * Added class-key declaration for friend classes in the CCompression
  414.  *
  415.  * Revision 1.1  2003/04/07 20:42:11  ivanov
  416.  * Initial revision
  417.  *
  418.  * ===========================================================================
  419.  */
  420. #endif  /* UTIL_COMPRESS__COMPRESS__HPP */