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
1.4.6
Modified on Mon Dec 07 16:20:49 2009 by modify_doxy.py rev. 173732