📄 zlib.cpp
字号:
// Open file m_File = gzopen(file_name.c_str(), open_mode.c_str()); m_Mode = mode; if ( !m_File ) { int err = errno; Close(); if ( err == 0 ) { SetError(Z_MEM_ERROR, zError(Z_MEM_ERROR)); } else { SetError(Z_MEM_ERROR, strerror(errno)); } ERR_POST(FormatErrorMessage("CZipCompressionFile::Open", false)); return false; }; SetError(Z_OK); return true;} int CZipCompressionFile::Read(void* buf, int len){ int nread = gzread(m_File, buf, len); if ( nread == -1 ) { int err_code; const char* err_msg = gzerror(m_File, &err_code); SetError(err_code, err_msg); ERR_POST(FormatErrorMessage("CZipCompressionFile::Read", false)); return -1; } SetError(Z_OK); return nread;}int CZipCompressionFile::Write(const void* buf, int len){ // Redefine standart behaviour for case of writing zero bytes if (len == 0) { return true; } int nwrite = gzwrite(m_File, const_cast<void* const>(buf), len); if ( nwrite <= 0 ) { int err_code; const char* err_msg = gzerror(m_File, &err_code); SetError(err_code, err_msg); ERR_POST(FormatErrorMessage("CZipCompressionFile::Write", false)); return -1; } SetError(Z_OK); return nwrite; }bool CZipCompressionFile::Close(void){ if ( m_File ) { int errcode = gzclose(m_File); m_File = 0; if ( errcode != Z_OK) { int err_code; const char* err_msg = gzerror(m_File, &err_code); SetError(errcode, err_msg); ERR_POST(FormatErrorMessage("CZipCompressionFile::Close", false)); return false; } } SetError(Z_OK); return true;}////////////////////////////////////////////////////////////////////////////////// CZipCompressor//CZipCompressor::CZipCompressor(ELevel level, int window_bits, int mem_level, int strategy, TFlags flags) : CZipCompression(level, window_bits, mem_level, strategy), m_CRC32(0), m_NeedWriteHeader(true){ SetFlags(flags);}CZipCompressor::~CZipCompressor(){}CCompressionProcessor::EStatus CZipCompressor::Init(void){ // Initialize members Reset(); SetBusy(); m_CRC32 = 0; m_NeedWriteHeader = true; m_Cache.erase(); m_Cache.reserve(kMaxCacheSize); // Initialize the compressor stream structure memset(&m_Stream, 0, sizeof(m_Stream)); // Create a compressor stream int errcode = deflateInit2(&m_Stream, GetLevel(), Z_DEFLATED, F_ISSET(fWriteGZipFormat) ? -m_WindowBits : m_WindowBits, m_MemLevel, m_Strategy); SetError(errcode, zError(errcode)); if ( errcode == Z_OK ) { return eStatus_Success; } ERR_POST(FormatErrorMessage("CZipCompressor::Init")); return eStatus_Error;}CCompressionProcessor::EStatus CZipCompressor::Process( const char* in_buf, unsigned long in_len, char* out_buf, unsigned long out_size, /* out */ unsigned long* in_avail, /* out */ unsigned long* out_avail){ unsigned long header_len = 0; // Write gzip file header if ( F_ISSET(fWriteGZipFormat) && m_NeedWriteHeader ) { header_len = s_WriteGZipHeader(out_buf, out_size); if (!header_len) { ERR_POST("CZipCompressor::Process: Cannot write gzip header"); return eStatus_Error; } m_NeedWriteHeader = false; } m_Stream.next_in = (unsigned char*)const_cast<char*>(in_buf); m_Stream.avail_in = in_len; m_Stream.next_out = (unsigned char*)out_buf + header_len; m_Stream.avail_out = out_size - header_len; int errcode = deflate(&m_Stream, Z_NO_FLUSH); SetError(errcode, zError(errcode)); *in_avail = m_Stream.avail_in; *out_avail = out_size - m_Stream.avail_out; IncreaseProcessedSize(in_len - *in_avail); IncreaseOutputSize(*out_avail); // If we writing in gzip file format if ( F_ISSET(fWriteGZipFormat) ) { // Update the CRC32 for processed data m_CRC32 = crc32(m_CRC32, (unsigned char*)in_buf, in_len - *in_avail); } if ( errcode == Z_OK ) { return eStatus_Success; } ERR_POST(FormatErrorMessage("CZipCompressor::Process")); return eStatus_Error;}CCompressionProcessor::EStatus CZipCompressor::Flush( char* out_buf, unsigned long out_size, /* out */ unsigned long* out_avail){ if ( !out_size ) { return eStatus_Overflow; } m_Stream.next_in = 0; m_Stream.avail_in = 0; m_Stream.next_out = (unsigned char*)out_buf; m_Stream.avail_out = out_size; int errcode = deflate(&m_Stream, Z_SYNC_FLUSH); SetError(errcode, zError(errcode)); *out_avail = out_size - m_Stream.avail_out; IncreaseOutputSize(*out_avail); if ( errcode == Z_OK || errcode == Z_BUF_ERROR ) { if ( m_Stream.avail_out == 0) { return eStatus_Overflow; } return eStatus_Success; } ERR_POST(FormatErrorMessage("CZipCompressor::Flush")); return eStatus_Error;}CCompressionProcessor::EStatus CZipCompressor::Finish( char* out_buf, unsigned long out_size, /* out */ unsigned long* out_avail){ if ( !out_size ) { return eStatus_Overflow; } m_Stream.next_in = 0; m_Stream.avail_in = 0; m_Stream.next_out = (unsigned char*)out_buf; m_Stream.avail_out = out_size; int errcode = deflate(&m_Stream, Z_FINISH); SetError(errcode, zError(errcode)); *out_avail = out_size - m_Stream.avail_out; IncreaseOutputSize(*out_avail); switch (errcode) { case Z_OK: return eStatus_Overflow; case Z_STREAM_END: // Write .gz file footer if ( F_ISSET(fWriteGZipFormat) ) { unsigned int footer_len = s_WriteGZipFooter(out_buf + *out_avail, m_Stream.avail_out, GetProcessedSize(), m_CRC32); if ( !footer_len ) { ERR_POST("CZipCompressor::Finish: Cannot write gzip footer"); return eStatus_Overflow; } *out_avail += footer_len; } return eStatus_EndOfData; } ERR_POST(FormatErrorMessage("CZipCompressor::Finish")); return eStatus_Error;}CCompressionProcessor::EStatus CZipCompressor::End(void){ int errcode = deflateEnd(&m_Stream); SetError(errcode, zError(errcode)); SetBusy(false); if ( errcode == Z_OK ) { return eStatus_Success; } ERR_POST(FormatErrorMessage("CZipCompressor::End")); return eStatus_Error;}////////////////////////////////////////////////////////////////////////////////// CZipDecompressor//CZipDecompressor::CZipDecompressor(int window_bits, TFlags flags) : CZipCompression(eLevel_Default, window_bits, 0, 0), m_NeedCheckHeader(true){ SetFlags(flags);}CZipDecompressor::~CZipDecompressor(){}CCompressionProcessor::EStatus CZipDecompressor::Init(void){ // Initialize members Reset(); SetBusy(); m_NeedCheckHeader = true; m_Cache.erase(); m_Cache.reserve(kMaxCacheSize); // Initialize the compressor stream structure memset(&m_Stream, 0, sizeof(m_Stream)); // Create a compressor stream int errcode = inflateInit2(&m_Stream, m_WindowBits); SetError(errcode, zError(errcode)); if ( errcode == Z_OK ) { return eStatus_Success; } ERR_POST(FormatErrorMessage("CZipDecompressor::Init")); return eStatus_Error;}CCompressionProcessor::EStatus CZipDecompressor::Process( const char* in_buf, unsigned long in_len, char* out_buf, unsigned long out_size, /* out */ unsigned long* in_avail, /* out */ unsigned long* out_avail){ if ( !out_size ) { return eStatus_Overflow; } m_Stream.next_in = (unsigned char*)const_cast<char*>(in_buf); m_Stream.avail_in = in_len; m_Stream.next_out = (unsigned char*)out_buf; m_Stream.avail_out = out_size; bool from_cache = false; unsigned long avail_adj = in_len; unsigned long old_avail_in = 0; // Check file header if ( F_ISSET(fCheckFileHeader) ) { unsigned int header_len = 0; if ( m_NeedCheckHeader ) { if (in_buf && m_Cache.size() < kMaxCacheSize) { unsigned long n = min(kMaxCacheSize - m_Cache.size(), in_len); m_Cache.append(in_buf, n); avail_adj -= n; if (m_Cache.size() < kMaxCacheSize) { // Data block is very small and was cached. *in_avail = 0; *out_avail = 0; return eStatus_Success; } } // Check gzip header in the buffer header_len = s_CheckGZipHeader(m_Cache.c_str(), m_Cache.size()); _ASSERT(header_len < kMaxCacheSize); // If gzip header found, skip it if ( header_len ) { m_Cache.erase(0, header_len); int errcode = inflateInit2(&m_Stream, header_len ? -MAX_WBITS : m_WindowBits); SetError(errcode, zError(errcode)); if ( errcode != Z_OK ) { return eStatus_Error; } } // Already skipped or we don't have header here if (header_len || in_buf) { m_NeedCheckHeader = false; } } // Have some cached unprocessed data if ( m_Cache.size() ) { m_Stream.next_in = (unsigned char*)(m_Cache.c_str()); m_Stream.avail_in = m_Cache.size(); m_Stream.next_out = (unsigned char*)out_buf; m_Stream.avail_out = out_size; from_cache = true; old_avail_in = m_Stream.avail_in; } } int errcode = inflate(&m_Stream, Z_SYNC_FLUSH); SetError(errcode, zError(errcode)); if ( from_cache ) { m_Cache.erase(0, old_avail_in - m_Stream.avail_in); *in_avail = avail_adj; IncreaseProcessedSize(old_avail_in - m_Stream.avail_in); } else { *in_avail = m_Stream.avail_in; IncreaseProcessedSize(in_len - *in_avail); } *out_avail = out_size - m_Stream.avail_out; IncreaseOutputSize(*out_avail); switch (errcode) { case Z_OK: return eStatus_Success; case Z_STREAM_END: return eStatus_EndOfData; } ERR_POST(FormatErrorMessage("CZipDecompressor::Process")); return eStatus_Error;}CCompressionProcessor::EStatus CZipDecompressor::Flush( char* out_buf, unsigned long out_size, unsigned long* out_avail){ // Process cached data if (F_ISSET(fCheckFileHeader) && m_Cache.size()) { unsigned long in_avail; return Process(0, 0, out_buf, out_size, &in_avail, out_avail); } return eStatus_Success;}CCompressionProcessor::EStatus CZipDecompressor::Finish( char* out_buf, unsigned long out_size, unsigned long* out_avail){ // Process cached data if (F_ISSET(fCheckFileHeader) && m_Cache.size()) { unsigned long in_avail; return Process(0, 0, out_buf, out_size, &in_avail, out_avail); } return eStatus_Success;}CCompressionProcessor::EStatus CZipDecompressor::End(void){ int errcode = inflateEnd(&m_Stream); SetBusy(false); if ( errcode == Z_OK ) { return eStatus_Success; } ERR_POST(FormatErrorMessage("CZipDecompressor::End")); return eStatus_Error;}END_NCBI_SCOPE/* * =========================================================================== * $Log: zlib.cpp,v $ * Revision 1000.3 2004/06/03 17:11:39 gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.14 * * Revision 1.14 2004/06/02 16:14:12 ivanov * Fixed processed bytes counting in the CZipDecompressor::Process() * * Revision 1.13 2004/05/17 21:07:25 gorelenk * Added include of PCH ncbi_pch.hpp * * Revision 1.12 2004/05/10 19:25:09 ucko * +<stdio.h> for sprintf() * * Revision 1.11 2004/05/10 13:06:45 ucko * Default OS_CODE to the Unix value (0x03). * * Revision 1.10 2004/05/10 12:57:03 ivanov * Removed #include <zutil.h> * * Revision 1.9 2004/05/10 11:56:08 ivanov * Added gzip file format support * * Revision 1.8 2004/04/19 14:17:15 ivanov * Added gzip file format support into stream decompressor * * Revision 1.7 2004/04/01 14:14:03 lavr * Spell "occurred", "occurrence", and "occurring" * * Revision 1.6 2003/07/15 15:46:31 ivanov * Improved error diagnostics. Save status codes and it's description after * each compression operation, and ERR_POST it if error occurred. * * Revision 1.5 2003/07/10 16:30:30 ivanov * Implemented CompressFile/DecompressFile functions. * Added ability to skip a gzip file headers into DecompressBuffer(). * * Revision 1.4 2003/06/17 15:43:58 ivanov * Minor cosmetics and comments changes * * Revision 1.3 2003/06/03 20:09:16 ivanov * The Compression API redesign. Added some new classes, rewritten old. * * Revision 1.2 2003/04/15 16:49:33 ivanov * Added processing zlib return code Z_BUF_ERROR to DeflateFlush() * * Revision 1.1 2003/04/07 20:21:35 ivanov * Initial revision * * =========================================================================== */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -