Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

CPipeBlock.cpp

Go to the documentation of this file.
00001 
00034 #include "stdafx.h"
00035 
00036 namespace AxPipe {
00038     CPipeBlock::CPipeBlock() {
00039         Init(0);
00040     }
00041 
00043     CPipeBlock::~CPipeBlock() {
00044         if (m_pBlockPart) {
00045             m_pBlockPart->Release();
00046         }
00047     }
00048     
00051     CPipeBlock *
00052     CPipeBlock::Init(size_t cbBlockSize) {
00053         m_cbBlockSize = cbBlockSize;
00054         m_pBlockPart = NULL;
00055         return this;
00056     }
00057 
00063     void
00064     CPipeBlock::OutPump(CSeg *pSeg) {
00065         // Propagate end of stream, and exit directly. We can never have a full output-block
00066         // waiting at this stage, if it's end of stream - this will have to be picked up by
00067         // the OutClose() function. It might also be a special block, those we send as-is.
00068         if (!CSeg::IsSeg(pSeg)) {
00069             CPipe::OutPump(pSeg);
00070             return;
00071         }
00072 
00073         if (m_pBlockPart) {
00074             size_t cbToMove = m_cbBlockSize - m_pBlockPart->Len();
00075 
00076             // Adjust if we don't get enough for a full block
00077             if (cbToMove > pSeg->Len()) {
00078                 cbToMove = pSeg->Len();
00079             }
00080             CopyMemory(&m_pBlockPart->PtrWr()[m_pBlockPart->Len()], pSeg->PtrRd(), cbToMove);
00081             m_pBlockPart->Len(m_pBlockPart->Len() + cbToMove);
00082             pSeg->Drop(cbToMove);
00083 
00084             // If we do have a block
00085             if (m_pBlockPart->Len() == m_cbBlockSize) {
00086                 CPipe::OutPump(m_pBlockPart);
00087                 m_pBlockPart = NULL;
00088             }
00089         }
00090         // Now we know that m_pBlockPart is NULL, let see if we can send more.
00091 
00092         // Now output as much as possible. Create a clone, and make it an even multiple of
00093         // the block size in length. Only do it if there's enough for at least a block.
00094         if (pSeg->Len() >= m_cbBlockSize) {
00095             CSeg *pBlockSeg = pSeg->Clone();
00096             pBlockSeg->Len(pSeg->Len() - pSeg->Len() % m_cbBlockSize);
00097             pSeg->Drop(pBlockSeg->Len());
00098             CPipe::OutPump(pBlockSeg);
00099         }
00100 
00101         if (pSeg->Len()) {
00102             // There's a partial block left, make a new segment, one block large, and put it there.
00103             m_pBlockPart = new CSeg(pSeg->PtrRd(), pSeg->Len(), m_cbBlockSize - pSeg->Len());
00104         }
00105         pSeg->Release();            
00106     }
00107     
00113     CSeg *
00114     CPipeBlock::PartialBlock() {
00115         return m_pBlockPart;
00116     }
00117 };

Generated on Mon Feb 2 13:19:18 2004 for AxPipe by doxygen 1.3.5