📄 bzip2.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: bzip2.cpp,v $ * PRODUCTION Revision 1000.2 2004/06/01 19:40:54 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9 * PRODUCTION * =========================================================================== *//* $Id: bzip2.cpp,v 1000.2 2004/06/01 19:40:54 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Authors: Vladimir Ivanov * * File Description: BZip2 Compression API * */#include <ncbi_pch.hpp>#include <util/compress/bzip2.hpp>BEGIN_NCBI_SCOPE////////////////////////////////////////////////////////////////////////////////// CBZip2Compression//CBZip2Compression::CBZip2Compression(ELevel level, int verbosity, int work_factor, int small_decompress) : CCompression(level), m_Verbosity(verbosity), m_WorkFactor(work_factor), m_SmallDecompress(small_decompress){ // Initialize the compressor stream structure memset(&m_Stream, 0, sizeof(m_Stream)); return;}CBZip2Compression::~CBZip2Compression(void){ return;}CCompression::ELevel CBZip2Compression::GetLevel(void) const{ CCompression::ELevel level = CCompression::GetLevel(); // BZip2 do not support a zero compression level -- make conversion if ( level == eLevel_NoCompression) { return eLevel_Lowest; } return level;}bool CBZip2Compression::CompressBuffer( const void* src_buf, unsigned int src_len, void* dst_buf, unsigned int dst_size, /* out */ unsigned int* dst_len){ // Check parameters if ( !src_buf || !src_len ) { *dst_len = 0; SetError(BZ_OK); return true; } if ( !dst_buf || !dst_len ) { SetError(BZ_PARAM_ERROR, "bad argument"); ERR_POST(FormatErrorMessage("CBZip2Compression::CompressBuffer")); return false; } // Destination buffer size *dst_len = dst_size; // Compress buffer int errcode = BZ2_bzBuffToBuffCompress((char*)dst_buf, dst_len, (char*)src_buf, src_len, GetLevel(), 0, 0 ); SetError(errcode, GetBZip2ErrorDescription(errcode)); if ( errcode != BZ_OK) { ERR_POST(FormatErrorMessage("CBZip2Compression::CompressBuffer")); return false; } return true;}bool CBZip2Compression::DecompressBuffer( const void* src_buf, unsigned int src_len, void* dst_buf, unsigned int dst_size, /* out */ unsigned int* dst_len){ // Check parameters if ( !src_buf || !src_len ) { *dst_len = 0; SetError(BZ_OK); return true; } if ( !dst_buf || !dst_len ) { SetError(BZ_PARAM_ERROR, "bad argument"); return false; } // Destination buffer size *dst_len = dst_size; // Decompress buffer int errcode = BZ2_bzBuffToBuffDecompress((char*)dst_buf, dst_len, (char*)src_buf, src_len, 0, 0 ); SetError(errcode, GetBZip2ErrorDescription(errcode)); if ( errcode != BZ_OK ) { ERR_POST(FormatErrorMessage("CBZip2Compression::DecompressBuffer")); return false; } return true;}bool CBZip2Compression::CompressFile(const string& src_file, const string& dst_file, size_t buf_size){ CBZip2CompressionFile cf(dst_file, CCompressionFile::eMode_Write, GetLevel(), m_Verbosity, m_WorkFactor, m_SmallDecompress); if ( CCompression::x_CompressFile(src_file, cf, buf_size) ) { return cf.Close(); } // Save error info int errcode = cf.GetErrorCode(); string errmsg = cf.GetErrorDescription(); // Close file cf.Close(); // Restore previous error info SetError(errcode, errmsg.c_str()); return false;}bool CBZip2Compression::DecompressFile(const string& src_file, const string& dst_file, size_t buf_size){ CBZip2CompressionFile cf(src_file, CCompressionFile::eMode_Read, GetLevel(), m_Verbosity, m_WorkFactor, m_SmallDecompress); if ( CCompression::x_DecompressFile(cf, dst_file, buf_size) ) { return cf.Close(); } // Save error info int errcode = cf.GetErrorCode(); string errmsg = cf.GetErrorDescription(); // Close file cf.Close(); // Restore previous error info SetError(errcode, errmsg.c_str()); return false;}// Please, see a ftp://sources.redhat.com/pub/bzip2/docs/manual_3.html#SEC17// for detailed error descriptions.const char* CBZip2Compression::GetBZip2ErrorDescription(int errcode){ const int kErrorCount = 9; static const char* kErrorDesc[kErrorCount] = { "SEQUENCE_ERROR", "PARAM_ERROR", "MEM_ERROR", "DATA_ERROR", "DATA_ERROR_MAGIC", "IO_ERROR", "UNEXPECTED_EOF", "OUTBUFF_FULL", "CONFIG_ERROR" }; // errcode must be negative if ( errcode >= 0 || errcode < -kErrorCount ) { return 0; } return kErrorDesc[-errcode - 1];}string CBZip2Compression::FormatErrorMessage(string where, bool use_stream_data) const{ string str = "[" + where + "] " + GetErrorDescription(); if ( use_stream_data ) { str += "; error code = " + NStr::IntToString(GetErrorCode()) + ", number of processed bytes = " + NStr::UInt8ToString(((Uint8)m_Stream.total_in_hi32 << 32) + (Uint8)m_Stream.total_in_lo32); } return str + ".";}////////////////////////////////////////////////////////////////////////////////// CBZip2CompressionFile//CBZip2CompressionFile::CBZip2CompressionFile( const string& file_name, EMode mode, ELevel level, int verbosity, int work_factor, int small_decompress) : CBZip2Compression(level, verbosity, work_factor, small_decompress), m_FileStream(0){ if ( !Open(file_name, mode) ) { const string smode = (mode == eMode_Read) ? "reading" : "writing"; NCBI_THROW(CCompressionException, eCompressionFile, "[CBZip2CompressionFile] Cannot open file '" + file_name + "' for " + smode + "."); } return;}CBZip2CompressionFile::CBZip2CompressionFile( ELevel level, int verbosity, int work_factor, int small_decompress) : CBZip2Compression(level, verbosity, work_factor, small_decompress), m_FileStream(0), m_EOF(true){ return;}CBZip2CompressionFile::~CBZip2CompressionFile(void){ Close(); return;}bool CBZip2CompressionFile::Open(const string& file_name, EMode mode){ int errcode; if ( mode == eMode_Read ) { m_FileStream = fopen(file_name.c_str(), "rb"); m_File = BZ2_bzReadOpen (&errcode, m_FileStream, m_SmallDecompress, m_Verbosity, 0, 0); m_EOF = false; } else { m_FileStream = fopen(file_name.c_str(), "wb"); m_File = BZ2_bzWriteOpen(&errcode, m_FileStream, GetLevel(), m_Verbosity, m_WorkFactor); } m_Mode = mode; if ( errcode != BZ_OK ) { Close(); SetError(errcode, GetBZip2ErrorDescription(errcode)); ERR_POST(FormatErrorMessage("CBZip2CompressionFile::Open", false)); return false; }; SetError(BZ_OK); return true;} int CBZip2CompressionFile::Read(void* buf, int len){ if ( m_EOF ) { return 0; } int errcode; int nread = BZ2_bzRead(&errcode, m_File, buf, len); SetError(errcode, GetBZip2ErrorDescription(errcode)); if ( errcode != BZ_OK && errcode != BZ_STREAM_END ) { ERR_POST(FormatErrorMessage("CBZip2CompressionFile::Read", false)); return -1; }; if ( errcode == BZ_STREAM_END ) { m_EOF = true; }; return nread;}int CBZip2CompressionFile::Write(const void* buf, int len){ int errcode; BZ2_bzWrite(&errcode, m_File, const_cast<void*>(buf), len);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -