include/util/compress/stream.hpp

Go to the documentation of this file.
00001 #ifndef UTIL_COMPRESS__STREAM__HPP
00002 #define UTIL_COMPRESS__STREAM__HPP
00003 
00004 /*  $Id: stream.hpp 149145 2009-01-07 19:24:11Z ivanov $
00005  * ===========================================================================
00006  *
00007  *                            PUBLIC DOMAIN NOTICE
00008  *               National Center for Biotechnology Information
00009  *
00010  *  This software/database is a "United States Government Work" under the
00011  *  terms of the United States Copyright Act.  It was written as part of
00012  *  the author's official duties as a United States Government employee and
00013  *  thus cannot be copyrighted.  This software/database is freely available
00014  *  to the public for use. The National Library of Medicine and the U.S.
00015  *  Government have not placed any restriction on its use or reproduction.
00016  *
00017  *  Although all reasonable efforts have been taken to ensure the accuracy
00018  *  and reliability of the software and data, the NLM and the U.S.
00019  *  Government do not and cannot warrant the performance or results that
00020  *  may be obtained by using this software or data. The NLM and the U.S.
00021  *  Government disclaim all warranties, express or implied, including
00022  *  warranties of performance, merchantability or fitness for any particular
00023  *  purpose.
00024  *
00025  *  Please cite the author in any work or product based on this material.
00026  *
00027  * ===========================================================================
00028  *
00029  * Author:  Vladimir Ivanov
00030  *
00031  * File Description:  CCompression based C++ I/O streams
00032  *
00033  */
00034 
00035 #include <util/compress/compress.hpp>
00036 
00037 
00038 /** @addtogroup CompressionStreams
00039  *
00040  * @{
00041  */
00042 
00043 
00044 BEGIN_NCBI_SCOPE
00045 
00046 
00047 //////////////////////////////////////////////////////////////////////////////
00048 //
00049 // CCompression based stream classes
00050 //
00051 //////////////////////////////////////////////////////////////////////////////
00052 //
00053 // All CCompression based streams uses a "stream processors" that works as
00054 // adapters between current stream's I/O interface and a some other stream,
00055 // specified in the constructor. Any stream processor can implement either
00056 // compression or decompression.
00057 
00058 // On reading from stream, data will be readed from underlying stream,
00059 // processed by "read stream processor", and next processed data will be
00060 // carried to called process.
00061 // Also, all data written into CCompression[IO]Stream stream will be processed
00062 // using "write stream processor" and further written into underlying stream. 
00063 // 
00064 // Note:
00065 //   Notice that generally the input/output stream you pass to
00066 //   CCompression[IO]Stream class constructor must be in binary mode, because
00067 //   the compressed data always is binary (decompressed data also can be
00068 //   binary) and the conversions which happen in text mode will corrupt it.
00069 //
00070 // Note:
00071 //   CCompression[IO]Stream class objects must be finalized after use.
00072 //   At least one IO operation should be accompleshed before finalization.
00073 //   Only after finalization all data put into stream will be processed
00074 //   for sure. By default finalization called in the class destructor, however
00075 //   it can be done in any time by call Finalize(). After finalization you
00076 //   can only read from the stream (if it is derived from istream).
00077 //   If you don't read that some data can be lost. 
00078 //
00079 // Note:
00080 //   There is one special aspect of CCompression[I]OStream class. Basically
00081 //   the compression algorithms works on blocks of data. They waits until
00082 //   a block is full and then compresses it. As long as you only feed data
00083 //   to the stream without flushing it this works normally. If you flush
00084 //   the stream, you force a premature end of the data block. This will cause
00085 //   a worse compression factor. You should avoid flushing a output buffer.
00086 //
00087 //   Accordingly, the using input stream with compression usualy have worse
00088 //   compression than output stream with compression. Because a stream needs
00089 //   to flush data from compressor very often. Increasing compressor buffer
00090 //   size can to amend this situation.
00091 //
00092 
00093 
00094 // Forward declaration
00095 class CCompressionStreamProcessor;
00096 
00097 
00098 //////////////////////////////////////////////////////////////////////////////
00099 //
00100 // CCompressionStream - base stream class
00101 //
00102 
00103 class  CCompressionStream : virtual public CNcbiIos
00104 {
00105 public:
00106     /// Stream processing direction.
00107     enum EDirection {
00108         eRead,                      ///< Reading from stream
00109         eWrite,                     ///< Writing into stream
00110         eReadWrite                  ///< eRead + eWrite
00111     };
00112 
00113     /// Which of the objects (passed in the constructor) should be
00114     /// deleted on this object's destruction.
00115     /// NOTE:  if the reader and writer are in fact one object, it will
00116     ///        not be deleted twice.
00117     enum EOwnership {
00118         fOwnStream = (1<<1),        ///< Delete the underlying I/O stream.
00119         fOwnReader = (1<<2),        ///< Delete the reader.
00120         fOwnWriter = (1<<3),        ///< Delete the writer.
00121         fOwnProcessor = fOwnReader + fOwnWriter,
00122         fOwnAll       = fOwnStream + fOwnProcessor
00123     };
00124     typedef int TOwnership;         ///< Bitwise OR of EOwnership.
00125 
00126     /// Constructor
00127     ///
00128     /// If read/write stream processor is 0 (NULL), that read/write operations
00129     /// on this stream will be unsuccessful.
00130     CCompressionStream(CNcbiIos&                    stream,
00131                        CCompressionStreamProcessor* read_sp,
00132                        CCompressionStreamProcessor* write_sp,
00133                        TOwnership                   ownership = 0);
00134     /// Destructor
00135     virtual ~CCompressionStream(void);
00136 
00137     /// Finalize stream's compression/decompression process for read/write.
00138     /// This function just calls a streambuf Finalize().
00139     virtual void Finalize(CCompressionStream::EDirection dir =
00140                           CCompressionStream::eReadWrite);
00141 
00142 protected:
00143     /// Get status of last compression/decompression stream operation.
00144     CCompressionProcessor::EStatus x_GetStatus(CCompressionStream::EDirection dir);
00145     /// Get error code and description of last compressor/decompressor stream operation.
00146     /// Return TRUE if information obtained successfully.
00147     bool x_GetError(CCompressionStream::EDirection dir,
00148                     int& status, string& description);
00149     /// Return number of processed bytes.
00150     unsigned long x_GetProcessedSize(CCompressionStream::EDirection dir);
00151     /// Return number of output bytes.
00152     unsigned long x_GetOutputSize(CCompressionStream::EDirection dir);
00153 
00154 protected:
00155     CNcbiIos*                    m_Stream;    ///< Underlying stream.
00156     CCompressionStreambuf*       m_StreamBuf; ///< Stream buffer.
00157     CCompressionStreamProcessor* m_Reader;    ///< Read processor.
00158     CCompressionStreamProcessor* m_Writer;    ///< Write processor.
00159     TOwnership                   m_Ownership; ///< Bitwise OR of EOwnership.
00160 };
00161 
00162 
00163 
00164 //////////////////////////////////////////////////////////////////////////////
00165 //
00166 // CCompressionStreamProcessor class
00167 //
00168 // Container class for storing a stream's processor read/write info.
00169 //
00170 
00171 class  CCompressionStreamProcessor 
00172 {
00173 public:
00174     /// If to delete the used compression processor in the destructor.
00175     enum EDeleteProcessor {
00176         eDelete,            ///< Do     delete processor object.
00177         eNoDelete           ///< Do not delete processor object.
00178     };
00179 
00180     /// Stream processor state.
00181     enum EState {
00182         eActive,            ///< Processor ready to read/write.
00183         eFinalize,          ///< Finalize() already done, but End() not yet.
00184         eDone               ///< End() done, processor cannot process data.
00185     };
00186 
00187     /// Constructor.
00188     CCompressionStreamProcessor(
00189         CCompressionProcessor* processor,
00190         EDeleteProcessor       need_delete  = eNoDelete,
00191         streamsize             in_bufsize   = kCompressionDefaultBufSize,
00192         streamsize             out_bufsize  = kCompressionDefaultBufSize
00193     );
00194 
00195     /// Destructor.
00196     virtual ~CCompressionStreamProcessor(void);
00197 
00198     /// (Re)Initialize stream processor.
00199     void Init(void);
00200 
00201 private:
00202     CCompressionProcessor* m_Processor;   ///< (De)compression processor.
00203     CT_CHAR_TYPE*          m_InBuf;       ///< Buffer of unprocessed data.
00204     streamsize             m_InBufSize;   ///< Unprocessed data buffer size.
00205     CT_CHAR_TYPE*          m_OutBuf;      ///< Buffer of processed data.
00206     streamsize             m_OutBufSize;  ///< Processed data buffer size.
00207     CT_CHAR_TYPE*          m_Begin;       ///< Begin and end of the pre/post
00208     CT_CHAR_TYPE*          m_End;         ///< processed data in the buffer.
00209     EDeleteProcessor       m_NeedDelete;  ///< m_Processor auto-deleting flag.
00210     CCompressionProcessor::EStatus
00211                            m_LastStatus;  ///< Last compressor status.
00212     EState                 m_State;       ///< Stream processor state.
00213 
00214     // Friend classes
00215     friend class CCompressionStream;
00216     friend class CCompressionStreambuf;
00217 };
00218 
00219 
00220 
00221 //////////////////////////////////////////////////////////////////////////////
00222 //
00223 // I/O stream classes
00224 //
00225 
00226 class  CCompressionIStream : public istream,
00227                                               public CCompressionStream
00228 {
00229 public:
00230     CCompressionIStream(CNcbiIos&                    stream,
00231                         CCompressionStreamProcessor* stream_processor,
00232                         TOwnership                   ownership = 0)
00233         : istream(0),
00234           CCompressionStream(stream, stream_processor, 0, ownership)
00235     {}
00236     
00237     /// Get status of last compression/decompression stream operation.
00238     CCompressionProcessor::EStatus GetStatus(void) {
00239         return CCompressionStream::x_GetStatus(eRead);
00240     }
00241     /// Get error code and description of last compressor/decompressor stream operation.
00242     /// Return TRUE if information obtained successfully.
00243     bool GetError(int& status, string& description) {
00244         return CCompressionStream::x_GetError(eRead, status, description);
00245     }
00246     /// Return number of processed bytes.
00247     unsigned long GetProcessedSize(void) {
00248         return CCompressionStream::x_GetProcessedSize(eRead);
00249     };
00250     /// Return number of output bytes.
00251     unsigned long GetOutputSize(void) {
00252         return CCompressionStream::x_GetOutputSize(eRead);
00253     };
00254     /// Test if no stream operation has failed
00255     DECLARE_OPERATOR_BOOL((void *)this != 0);
00256 };
00257 
00258 
00259 class  CCompressionOStream : public ostream,
00260                                               public CCompressionStream
00261 {
00262 public:
00263     CCompressionOStream(CNcbiIos&                    stream,
00264                         CCompressionStreamProcessor* stream_processor,
00265                         TOwnership                   ownership = 0)
00266         : ostream(0),
00267           CCompressionStream(stream, 0, stream_processor, ownership)
00268     {}
00269 
00270     /// Get status of last compression/decompression stream operation.
00271     CCompressionProcessor::EStatus GetStatus(void) {
00272         return CCompressionStream::x_GetStatus(eWrite);
00273     }
00274     /// Get error code and description of last compressor/decompressor stream operation.
00275     /// Return TRUE if information obtained successfully.
00276     bool GetError(int& status, string& description) {
00277         return CCompressionStream::x_GetError(eWrite, status, description);
00278     }
00279     /// Return number of processed bytes.
00280     unsigned long GetProcessedSize(void) {
00281         return CCompressionStream::x_GetProcessedSize(eWrite);
00282     };
00283     /// Return number of output bytes.
00284     unsigned long GetOutputSize(void) {
00285         return CCompressionStream::x_GetOutputSize(eWrite);
00286     };
00287     /// Test if no stream operation has failed
00288     DECLARE_OPERATOR_BOOL((void *)this != 0);
00289 };
00290 
00291 
00292 class  CCompressionIOStream : public iostream,
00293                                                public CCompressionStream
00294 {
00295 public:
00296     CCompressionIOStream(CNcbiIos&                    stream,
00297                          CCompressionStreamProcessor* read_sp,
00298                          CCompressionStreamProcessor* write_sp,
00299                          TOwnership                   ownership = 0)
00300         : iostream(0),
00301           CCompressionStream(stream, read_sp, write_sp, ownership)
00302     { }
00303 
00304     /// Get status of last compression/decompression stream operation.
00305     CCompressionProcessor::EStatus
00306     GetStatus(CCompressionStream::EDirection dir) {
00307         return CCompressionStream::x_GetStatus(dir);
00308     }
00309     /// Get error code and description of last compressor/decompressor stream operation.
00310     /// Return TRUE if information obtained successfully.
00311     bool GetError(CCompressionStream::EDirection dir,
00312                   int& status, string& description) {
00313         return CCompressionStream::x_GetError(dir, status, description);
00314     }
00315     /// Return number of processed bytes.
00316     unsigned long GetProcessedSize(CCompressionStream::EDirection dir) {
00317         return CCompressionStream::x_GetProcessedSize(dir);
00318     };
00319     /// Return number of output bytes.
00320     unsigned long GetOutputSize(CCompressionStream::EDirection dir) {
00321         return CCompressionStream::x_GetOutputSize(dir);
00322     };
00323     /// Test if no stream operation has failed
00324     DECLARE_OPERATOR_BOOL((void *)this != 0);
00325 };
00326 
00327 
00328 END_NCBI_SCOPE
00329 
00330 
00331 /* @} */
00332 
00333 #endif  /* UTIL_COMPRESS__STREAM__HPP */
00334 
00335 

Generated on Sun Dec 6 22:15:53 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Mon Dec 07 16:20:49 2009 by modify_doxy.py rev. 173732