📄 streambuf.cpp
字号:
/* * =========================================================================== * 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 + -