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 };