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

📄 cpipeblock.cpp

📁 研读AxCrypt对加解密的处理方法
💻 CPP
字号:
/*! \file
    \brief Implementation of AxPipe::CPipeBlock, providing pushed blocks of a given size.

    @(#) $Id: CPipeBlock.cpp,v 1.1.1.1 2003/12/17 21:36:58 svante Exp $

    AxPipe - Binary Stream Framework

    Copyright (C) 2003 Svante Seleborg/Axon Data, All rights reserved.

    This program is free software; you can redistribute it and/or modify it under the terms
    of the GNU General Public License as published by the Free Software Foundation;
    either version 2 of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
    without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along with this program;
    if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
    Boston, MA 02111-1307 USA

    The author may be reached at mailto:axpipe@axondata.se and http://axpipe.sourceforge.net

    Why is this framework released as GPL and not LGPL? See http://www.gnu.org/philosophy/why-not-lgpl.html

----
\verbatim
    CPipeBlock.cpp                  Implementation of CPipeBlock, providing pushed blocks of a given size.

    E-mail                          YYYY-MM-DD              Reason
    axpipe@axondata.se              2003-12-01              Initial
\endverbatim
*/
#include "stdafx.h"

#include "AxAssert.h"
#define AXLIB_ASSERT_FILE "CPipeBlock.cpp"

namespace AxPipe {
    /// \brief Initialize member variables.
    CPipeBlock::CPipeBlock() {
        Init(0);
    }

    /// \brief Destruct additional member data.
    CPipeBlock::~CPipeBlock() {
        if (m_pBlockPart) {
            m_pBlockPart->Release();
        }
    }
    
    /// \brief Set the size of the blocks to be provided to CPipeBlock::Out()
    /// \param cbBlockSize The size in bytes of the blocks to be provided.
    CPipeBlock *
    CPipeBlock::Init(size_t cbBlockSize) {
        m_cbBlockSize = cbBlockSize;
        m_pBlockPart = NULL;
        return this;
    }

    /// \brief Internal framework override to handle the blocking.
    ///
    /// Ensures that Out() will only be called with segments a multiple of the
    /// m_cbBlockSize.
    /// \param pSeg The segment provided from upstream that we preprocess to ensure the blocking.
    void
    CPipeBlock::OutPump(CSeg *pSeg) {
        // Propagate end of stream, and exit directly. We can never have a full output-block
        // waiting at this stage, if it's end of stream - this will have to be picked up by
        // the OutClose() function. It might also be a special block, those we send as-is.
        if (!CSeg::IsSeg(pSeg)) {
            CPipe::OutPump(pSeg);
            return;
        }

        if (m_pBlockPart) {
            size_t cbToMove = m_cbBlockSize - m_pBlockPart->Len();

            // Adjust if we don't get enough for a full block
            if (cbToMove > pSeg->Len()) {
                cbToMove = pSeg->Len();
            }
            CopyMemory(&m_pBlockPart->PtrWr()[m_pBlockPart->Len()], pSeg->PtrRd(), cbToMove);
            m_pBlockPart->Len(m_pBlockPart->Len() + cbToMove);
            pSeg->Drop(cbToMove);

            // If we do have a block
            if (m_pBlockPart->Len() == m_cbBlockSize) {
                CPipe::OutPump(m_pBlockPart);
                m_pBlockPart = NULL;
            }
        }
        // Now we know that m_pBlockPart is NULL, let see if we can send more.

        // Now output as much as possible. Create a clone, and make it an even multiple of
        // the block size in length. Only do it if there's enough for at least a block.
        if (pSeg->Len() >= m_cbBlockSize) {
            CSeg *pBlockSeg = pSeg->Clone();
            pBlockSeg->Len(pSeg->Len() - pSeg->Len() % m_cbBlockSize);
            pSeg->Drop(pBlockSeg->Len());
            CPipe::OutPump(pBlockSeg);
        }

        if (pSeg->Len()) {
            // There's a partial block left, make a new segment, one block large, and put it there.
            m_pBlockPart = new CSeg(pSeg->PtrRd(), pSeg->Len(), m_cbBlockSize - pSeg->Len());
        }
        pSeg->Release();            
    }
    
    /// \brief Get the partial block pointer.
    ///
    /// Call from your derived OutFlush() and/or OutClose(), depending on your semantics
    /// if you want to handle a final partial block.
    /// \return Pointer to partial block, or NULL if none.
    CSeg *
    CPipeBlock::PartialBlock() {
        return m_pBlockPart;
    }
};

⌨️ 快捷键说明

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