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

📄 streambuf.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * =========================================================================== * PRODUCTION $Log: streambuf.cpp,v $ * PRODUCTION Revision 1000.3  2004/06/03 17:11:36  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.12 * PRODUCTION * =========================================================================== *//*  $Id: streambuf.cpp,v 1000.3 2004/06/03 17:11:36 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:  CCompression based C++ streambuf * */#include <ncbi_pch.hpp>#include "streambuf.hpp"#include <util/compress/stream.hpp>#include <memory>BEGIN_NCBI_SCOPE#define CP CCompressionProcessor////////////////////////////////////////////////////////////////////////////////// CCompressionStreambuf//CCompressionStreambuf::CCompressionStreambuf(    CNcbiIos*                    stream,    CCompressionStreamProcessor* read_sp,    CCompressionStreamProcessor* write_sp)    :  m_Stream(stream), m_Reader(read_sp), m_Writer(write_sp), m_Buf(0){    // Check parameters    if ( !stream  ||           !((read_sp   &&  read_sp->m_Processor) ||           (write_sp  &&  write_sp->m_Processor))) {        return;    }    // Get buffers sizes    streamsize read_bufsize = 0, write_bufsize = 0;    if ( m_Reader ) {        read_bufsize = m_Reader->m_InBufSize + m_Reader->m_OutBufSize;    }    if ( m_Writer ) {        write_bufsize = m_Writer->m_InBufSize + m_Writer->m_OutBufSize;    }    // Allocate memory for all buffers at one time    auto_ptr<CT_CHAR_TYPE> bp(new CT_CHAR_TYPE[read_bufsize + write_bufsize]);    m_Buf = bp.get();    if ( !m_Buf ) {        return;    }    // Init processors and set the buffer pointers    if ( m_Reader ) {        m_Reader->m_InBuf  = m_Buf;        m_Reader->m_OutBuf = m_Buf + m_Reader->m_InBufSize;        m_Reader->m_Begin  = m_Reader->m_InBuf;        m_Reader->m_End    = m_Reader->m_InBuf;        // We wish to have underflow() called at the first read        setg(m_Reader->m_OutBuf, m_Reader->m_OutBuf, m_Reader->m_OutBuf);        m_Reader->m_Processor->Init();    } else {        setg(0,0,0);    }    if ( m_Writer ) {        m_Writer->m_InBuf  = m_Buf + read_bufsize;        m_Writer->m_OutBuf = m_Writer->m_InBuf + m_Writer->m_InBufSize;        m_Writer->m_Begin  = m_Writer->m_OutBuf;        m_Writer->m_End    = m_Writer->m_OutBuf;        // Use one character less for the input buffer than the really        // available one (see overflow())        setp(m_Writer->m_InBuf, m_Writer->m_InBuf + m_Writer->m_InBufSize - 1);        m_Writer->m_Processor->Init();    } else {        setp(0,0);    }    bp.release();}CCompressionStreambuf::~CCompressionStreambuf(){    Finalize();    delete[] m_Buf;}void CCompressionStreambuf::Finalize(CCompressionStream::EDirection dir){    // Finalize read and write processors    if (dir == CCompressionStream::eReadWrite ) {        Finalize(CCompressionStream::eRead);        Finalize(CCompressionStream::eWrite);        return;    }    if ( !IsOkay() ) {        return;    }    // Check processor status    if ( !IsStreamProcessorOkay(dir) ) {        return;    }    // Sync buffers    Sync(dir);    // Finish    CCompressionStreamProcessor* sp = GetStreamProcessor(dir);    if ( sp->m_LastStatus == CP::eStatus_EndOfData ) {        return;    }    CT_CHAR_TYPE* buf = sp->m_OutBuf;    unsigned long out_size = sp->m_OutBufSize, out_avail = 0;    do {        if ( dir == CCompressionStream::eRead ) {            buf = egptr();            out_size = sp->m_OutBuf + sp->m_OutBufSize - egptr();        }        sp->m_LastStatus = sp->m_Processor->Finish(buf, out_size, &out_avail);        if ( sp->m_LastStatus == CP::eStatus_Error ) {           break;        }        if ( dir == CCompressionStream::eRead ) {            // Update the get's pointers            setg(sp->m_OutBuf, gptr(), egptr() + out_avail);        } else {            // Write the data to the underlying stream            if ( out_avail  &&                 m_Stream->rdbuf()->sputn(sp->m_OutBuf, out_avail) !=                 (streamsize)out_avail) {                break;            }        }    } while ( out_avail  &&  sp->m_LastStatus == CP::eStatus_Overflow);    // Cleanup    sp->m_Processor->End();    sp->m_Finalized = true;}int CCompressionStreambuf::sync(){    if ( !IsOkay() ) {        return -1;    }    // Sync write processor buffers    if ( Sync(CCompressionStream::eWrite) != 0 ) {        return -1;    }    // Sync the underlying stream    return m_Stream->rdbuf()->PUBSYNC();}int CCompressionStreambuf::Sync(CCompressionStream::EDirection dir){    // Check processor status    if ( !IsStreamProcessorOkay(dir) ) {        return -1;    }    // Process remaining data in the preprocessing buffer    if ( !Process(dir) ) {        return -1;    }    // Flush    CCompressionStreamProcessor* sp = GetStreamProcessor(dir);    CT_CHAR_TYPE* buf = sp->m_OutBuf;    unsigned long out_size = sp->m_OutBufSize, out_avail = 0;    do {        if ( dir == CCompressionStream::eRead ) {            buf = egptr();            out_size = sp->m_OutBuf + sp->m_OutBufSize - egptr();        }        sp->m_LastStatus = sp->m_Processor->Flush(buf, out_size, &out_avail);        if ( sp->m_LastStatus == CP::eStatus_Error  ||             sp->m_LastStatus == CP::eStatus_EndOfData ) {           break;        }        if ( dir == CCompressionStream::eRead ) {            // Update the get's pointers            setg(sp->m_OutBuf, gptr(), egptr() + out_avail);        } else {            // Write the data to the underlying stream            if ( out_avail  &&                 m_Stream->rdbuf()->sputn(sp->m_OutBuf, out_avail) !=                 (streamsize)out_avail) {                return -1;            }        }    } while ( out_avail  &&  sp->m_LastStatus == CP::eStatus_Overflow );    // Check status    if ( sp->m_LastStatus != CP::eStatus_Success ) {        return -1;    }    return 0;}CT_INT_TYPE CCompressionStreambuf::overflow(CT_INT_TYPE c){    // Check processor status    if ( !IsStreamProcessorOkay(CCompressionStream::eWrite) ) {        return CT_EOF;    }    if ( !CT_EQ_INT_TYPE(c, CT_EOF) ) {        // Put this character in the last position        // (this function is called when pptr() == eptr() but we        // have reserved one byte more in the constructor, thus        // *epptr() and now *pptr() point to valid positions)        *pptr() = c;        // Increment put pointer        pbump(1);    }    if ( ProcessStreamWrite() ) {        return CT_NOT_EOF(CT_EOF);    }

⌨️ 快捷键说明

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