⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zlib.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * =========================================================================== * PRODUCTION $Log: zlib.cpp,v $ * PRODUCTION Revision 1000.3  2004/06/03 17:11:39  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.14 * PRODUCTION * =========================================================================== *//*  $Id: zlib.cpp,v 1000.3 2004/06/03 17:11:39 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 *           Jean-loup Gailly, Mark Adler *           (used a part of zlib library code from files gzio.c, uncompr.c) * * File Description:  ZLib Compression API * * NOTE: The zlib documentation can be found here:  *           http://zlib.org,   *           http://www.gzip.org/zlib/manual.html */#include <ncbi_pch.hpp>#include <util/compress/zlib.hpp>#include <stdio.h>// Identify as Unix by default.#ifndef OS_CODE#define OS_CODE 0x03#endifBEGIN_NCBI_SCOPE// Macro to check bits#define F_ISSET(mask) ((GetFlags() & (mask)) == (mask))// Maximum size of memory buffer for data caching.const unsigned long kMaxCacheSize = 1024;////////////////////////////////////////////////////////////////////////////////// CZipCompression//CZipCompression::CZipCompression(ELevel level,  int window_bits,                                 int mem_level, int strategy)    : CCompression(level), m_WindowBits(window_bits), m_MemLevel(mem_level),      m_Strategy(strategy){    // Initialize the compressor stream structure    memset(&m_Stream, 0, sizeof(m_Stream));    return;}CZipCompression::~CZipCompression(){    return;}// gzip magic headerconst int gz_magic[2] = {0x1f, 0x8b};// gzip flag byte#define ASCII_FLAG   0x01 // bit 0 set: file probably ascii text#define HEAD_CRC     0x02 // bit 1 set: header CRC present#define EXTRA_FIELD  0x04 // bit 2 set: extra field present#define ORIG_NAME    0x08 // bit 3 set: original file name present#define COMMENT      0x10 // bit 4 set: file comment present#define RESERVED     0xE0 // bits 5..7: reserved/// Returns length of the .gz header if it exist or 0 otherwise.staticunsigned int s_CheckGZipHeader(const void* src_buf, unsigned int src_len){    unsigned char* buf = (unsigned char*)src_buf;    // .gz header cannot be less than 10 bytes    if (src_len < 10) {        return 0;    }    // Check the gzip magic header    if (buf[0] != gz_magic[0]  ||        buf[1] != gz_magic[1]) {        return 0;    }    int method = buf[2];    int flags  = buf[3];    if (method != Z_DEFLATED  ||  (flags & RESERVED) != 0) {        return 0;    }    // Header length:     // gz_magic (2) + methos (1) + flags (1) + time, xflags and OS code (6)    unsigned int header_len = 10;     // Skip the extra fields    if ((flags & EXTRA_FIELD) != 0) {        if (header_len + 2 > src_len) {            return 0;        }        unsigned int len = buf[header_len++];        len += ((unsigned int)buf[header_len++])<<8;        header_len += len;    }    // Skip the original file name    if ((flags & ORIG_NAME) != 0) {        while (header_len < src_len  &&  buf[header_len++] != 0);    }    // Skip the file comment    if ((flags & COMMENT) != 0) {        while (header_len < src_len  &&  buf[header_len++] != 0);    }    // Skip the header CRC    if ((flags & HEAD_CRC) != 0) {        header_len += 2;    }    if (header_len > src_len) {        return 0;    }    return header_len;}static size_t s_WriteGZipHeader(void* buf, unsigned int  buf_size){    // .gz header cannot be less than 10 bytes    if (buf_size < 10) {        return 0;    }    sprintf((char*)buf, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],            Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);    return 10;}static void s_StoreLong(unsigned char* buf, unsigned long value){    for (int i = 0; i < 4; i++) {        buf[i] = (unsigned char)(value & 0xff);        value >>= 8;    }}static size_t s_WriteGZipFooter(void*         buf,                                unsigned int  buf_size,                                unsigned long total,                                unsigned long crc){    // .gz footer is 8 bytes length    if (buf_size < 8) {        return 0;    }    s_StoreLong((unsigned char*)buf, crc);    s_StoreLong((unsigned char*)buf+4, total);    return 8;}bool CZipCompression::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(Z_OK);        return true;    }    if ( !dst_buf || !dst_len ) {        SetError(Z_STREAM_ERROR, "bad argument");        ERR_POST(FormatErrorMessage("CZipCompression::CompressBuffer"));        return false;    }    unsigned long header_len = 0;    int           errcode    = Z_OK;    z_stream      stream;        // Write gzip file header    if ( F_ISSET(fWriteGZipFormat) ) {        header_len = s_WriteGZipHeader(dst_buf, dst_size);        if (!header_len) {            ERR_POST(                "CZipCompression::CompressBuffer:  Cannot write gzip header");            return false;        }    }    stream.next_in  = (unsigned char*)src_buf;    stream.avail_in = src_len;#ifdef MAXSEG_64K    // Check for source > 64K on 16-bit machine:    if ( stream.avail_in != src_len ) {        SetError(Z_BUF_ERROR, zError(Z_BUF_ERROR));        ERR_POST(FormatErrorMessage("CZipCompression::CompressBuffer"));        return false;    }#endif    stream.next_out = (unsigned char*)dst_buf + header_len;    stream.avail_out = dst_size - header_len;    if ( stream.avail_out != dst_size - header_len ) {        SetError(Z_BUF_ERROR, zError(Z_BUF_ERROR));        ERR_POST(FormatErrorMessage("CZipCompression::CompressBuffer"));        return false;    }    stream.zalloc = (alloc_func)0;    stream.zfree  = (free_func)0;    stream.opaque = (voidpf)0;    errcode = deflateInit2(&stream, GetLevel(), Z_DEFLATED,                           header_len ? -MAX_WBITS : MAX_WBITS,                           DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);    if (errcode == Z_OK) {        errcode = deflate(&stream, Z_FINISH);        *dst_len = stream.total_out + header_len;        if (errcode == Z_STREAM_END) {            errcode = deflateEnd(&stream);        } else {            if ( errcode == Z_OK ) {                errcode = Z_BUF_ERROR;            }            deflateEnd(&stream);        }    }    SetError(errcode, zError(errcode));    if ( errcode != Z_OK ) {        ERR_POST(FormatErrorMessage("CZipCompression::CompressBuffer"));        return false;    }    // Write gzip file footer    if ( F_ISSET(fWriteGZipFormat) ) {        unsigned long crc = crc32(0L, (unsigned char*)src_buf, src_len);        unsigned int footer_len = s_WriteGZipFooter(            (char*)dst_buf + *dst_len, dst_size, src_len, crc);        if (!footer_len) {            ERR_POST(                "CZipCompression::CompressBuffer:  Cannot write gzip footer");            return false;        }        *dst_len += footer_len;    }    return true;}bool CZipCompression::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(Z_OK);        return true;    }    if ( !dst_buf || !dst_len ) {        SetError(Z_STREAM_ERROR, "bad argument");        ERR_POST(FormatErrorMessage("CZipCompression::DecompressBuffer"));        return false;    }    unsigned long header_len = 0;    int           errcode    = Z_OK;    z_stream      stream;        // Check file header    if ( F_ISSET(fCheckFileHeader) ) {        // Check gzip header in the buffer        header_len = s_CheckGZipHeader(src_buf, src_len);    }    stream.next_in  = (unsigned char*)src_buf + header_len;    stream.avail_in = src_len - header_len;    // Check for source > 64K on 16-bit machine:    if ( stream.avail_in != src_len - header_len ) {        SetError(Z_BUF_ERROR, zError(Z_BUF_ERROR));        ERR_POST(FormatErrorMessage("CZipCompression::DecompressBuffer"));        return false;    }    stream.next_out = (unsigned char*)dst_buf;    stream.avail_out = dst_size;    if ( stream.avail_out != dst_size ) {        SetError(Z_BUF_ERROR, zError(Z_BUF_ERROR));        ERR_POST(FormatErrorMessage("CZipCompression::DecompressBuffer"));        return false;    }    stream.zalloc = (alloc_func)0;    stream.zfree  = (free_func)0;    // "window bits" is passed < 0 to tell that there is no zlib header.    // Note that in this case inflate *requires* an extra "dummy" byte    // after the compressed stream in order to complete decompression and    // return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are    // present after the compressed stream.            errcode = inflateInit2(&stream, header_len ? -MAX_WBITS : MAX_WBITS);    if (errcode == Z_OK) {        errcode = inflate(&stream, Z_FINISH);        *dst_len = stream.total_out;        if (errcode == Z_STREAM_END) {            errcode = inflateEnd(&stream);        } else {            if ( errcode == Z_OK ) {                errcode = Z_BUF_ERROR;            }            inflateEnd(&stream);        }    }    SetError(errcode, zError(errcode));    if ( errcode != Z_OK ) {        ERR_POST(FormatErrorMessage("CZipCompression::DecompressBuffer"));        return false;    }    return true;}bool CZipCompression::CompressFile(const string& src_file,                                   const string& dst_file,                                   size_t        buf_size){    CZipCompressionFile cf(dst_file,                           CCompressionFile::eMode_Write, GetLevel(),                           m_WindowBits, m_MemLevel, m_Strategy);    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 CZipCompression::DecompressFile(const string& src_file,                                     const string& dst_file,                                     size_t        buf_size){    CZipCompressionFile cf(src_file,                           CCompressionFile::eMode_Read, GetLevel(),                           m_WindowBits, m_MemLevel, m_Strategy);    if ( CCompression::x_DecompressFile(cf, dst_file, buf_size) ) {        return cf.Close();    }    // Restore previous error info    int    errcode = cf.GetErrorCode();    string errmsg  = cf.GetErrorDescription();    // Restore previous error info    cf.Close();    // Restore previous error info    SetError(errcode, errmsg.c_str());    return false;}string CZipCompression::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::UIntToString(m_Stream.total_in);    }    return str + ".";}////////////////////////////////////////////////////////////////////////////////// CZipCompressionFile//CZipCompressionFile::CZipCompressionFile(    const string& file_name, EMode mode,    ELevel level, int window_bits, int mem_level, int strategy)    : CZipCompression(level, window_bits, mem_level, strategy){    if ( !Open(file_name, mode) ) {        const string smode = (mode == eMode_Read) ? "reading" : "writing";        NCBI_THROW(CCompressionException, eCompressionFile,                    "[CZipCompressionFile]  Cannot open file '" + file_name +                   "' for " + smode + ".");    }    return;}CZipCompressionFile::CZipCompressionFile(    ELevel level, int window_bits, int mem_level, int strategy)    : CZipCompression(level, window_bits, mem_level, strategy){    return;}CZipCompressionFile::~CZipCompressionFile(void){    Close();    return;}bool CZipCompressionFile::Open(const string& file_name, EMode mode){    string open_mode;    // Form a string file mode using template" <r/w>b<level><strategy>"    if ( mode == eMode_Read ) {        open_mode = "rb";    } else {        open_mode = "wb";        // Add comression level        open_mode += NStr::IntToString((long)GetLevel());        // Add strategy         switch (m_Strategy) {            case Z_FILTERED:                open_mode += "f";                break;            case Z_HUFFMAN_ONLY:                open_mode += "h";            default:                ; // Z_DEFAULT_STRATEGY        }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -