📄 cbqueue.cpp
字号:
if (m_pTail < m_pData || m_pTail >= m_pMax) { return( FALSE ); } // Ensure m_pHead is in range if (m_pHead < m_pData || m_pHead >= m_pMax) { return( FALSE ); } // Ensure m_pMax is the correct value for our size if (m_pMax != m_pData + m_nSize) { return( FALSE ); } // Everything looks good! return( TRUE );} // IsQueueValid()/* ** UINT16 CByteQueue::Base_DeQueueBytes( pOutBuffer, nByteCount ) * * PARAMETERS: * void *pOutBuffer Pointer to buffer to receive data. * UINT16 nAmount Number of bytes desired. * * DESCRIPTION: * Attempts to dequeue nAmount bytes from the Queue and transfers them * to pOutBuffer. * * RETURNS: * Number of bytes written to pOutBuffer. */UINT16 CByteQueue::Base_DeQueueBytes( void *pOutBuffer, UINT16 nByteCount ){ UINT16 nRead; HX_ASSERT( this ); HX_ASSERT( IsQueueValid() ); HX_ASSERT( pOutBuffer ); // First read the Queue into pOutBuffer nRead = Base_PeekBuff( pOutBuffer, nByteCount ); // Now update m_pHead which is our read pointer m_pHead = Base_Normalize( m_pHead, nRead ); HX_ASSERT( IsQueueValid() ); return( nRead );} // Base_DeQueueBytes()voidCByteQueue::SetMaxSize(UINT16 ulMax){ m_nMaxSize = ulMax;}/* * Grow the queue to twice its size or at least big enough to hold n more, * whichever is greater. returns 1 for good, 0 for bad. */intCByteQueue::Grow(UINT16 nItems){ //XXXPM Need to check for wrap around on these UINT16s if (m_nSize == m_nMaxSize) { return 0; } /* * Set our initial guess for the new target size by doubling the * current size. */ UINT16 ulUsedBytes = Base_GetUsedByteCount(); UINT16 ulMinFinalCapacity = ulUsedBytes + nItems * GetElementSize() + 1; UINT16 ulNewSize; // check ulMinFinalCapacity for rollover if (ulMinFinalCapacity < m_nSize) { return 0; } if (m_nMaxSize && ulMinFinalCapacity > m_nMaxSize) { return 0; } for (ulNewSize = 0xFFFF; ulNewSize && (ulNewSize >= ulMinFinalCapacity); ulNewSize = ulNewSize >> 1) { ; } if (!ulNewSize) return 0; ulNewSize = (ulNewSize << 1) + 1; if (m_nMaxSize && ulNewSize > m_nMaxSize) { ulNewSize = m_nMaxSize; } UCHAR* pNewBuf = new UCHAR[ulNewSize]; if( !pNewBuf ) { // It would be nice to be able to return HXR_OUTOFMEMORY. return 0; } /* * Let the queue copy every thing over for us. * +1 because its best to start out with head pointing at 0, * and data starting at 1. */ Base_DeQueueBytes((void*)(pNewBuf + 1), ulUsedBytes); /* * Destroy current structure and re-create with new buffer. */ delete[] m_pData; m_pData = pNewBuf; m_nSize = ulNewSize; //max points one past the end. m_pMax = m_pData + m_nSize; //head points at spot before first queued data m_pHead = m_pData; //tail points at last used byte m_pTail = m_pData + ulUsedBytes; return 1;}/* ** UINT16 CByteQueue::Base_EnQueueBytes( pInBuffer, nByteCount ) * * PARAMETERS: * void *pInBuffer Pointer to buffer containing data to EnQueue * UINT16 nByteCount Number of bytes items in buffer for EnQueue. * * DESCRIPTION: * Attempts to put nByteCount bytes into queue. If insufficient room, will * not enqueue anything. * * RETURNS: * Number of bytes written to pInBuffer. * Should be nByteCount or 0 because we fail if we don't have * room for ALL data */UINT16 CByteQueue::Base_EnQueueBytes( void *pInBuffer, UINT16 nByteCount ){ HX_ASSERT( this ); HX_ASSERT( IsQueueValid() ); HX_ASSERT( pInBuffer ); if (!nByteCount || Base_GetAvailableBytes() < nByteCount) { return( 0 ); } // Ok, we've guaranteed that we have enough room to enqueue nAmount items // Now switch on the state of our head & tail pointers if (m_pTail < m_pHead) { // No need to normalize pointers, because we're guaranteed // that we have room, hence m_pTail + nAmount HAS to be remain < m_pHead // Remember that m_pTail points at the postion just BEFORE our next // empty spot in the queue memcpy( m_pTail + 1, pInBuffer, nByteCount ); /* Flawfinder: ignore */ m_pTail += nByteCount; } else { // m_pTail >= m_pHead // This may require a copy in two passes if we have to wrap around the buffer UINT16 nCopy; UINT16 nPrevCopy; void *pDest; // Copying from (m_pTail + 1) to the end of the allocated buffer or nAmount // which ever comes first. pDest = Base_Normalize( m_pTail, 1); nCopy = __min( (UINT16)(m_pMax - (UCHAR *)pDest), nByteCount ); memcpy( pDest, pInBuffer, nCopy ); /* Flawfinder: ignore */ m_pTail = (UCHAR *)pDest + nCopy - 1; // Figure out how much more we have to copy (if any) nPrevCopy = nCopy; nCopy = nByteCount - nCopy; if (nCopy) { // Now we're copying into the base of the allocated array // whatever we didn't copy the first pass around memcpy( m_pData, (UCHAR *)pInBuffer + nPrevCopy, nCopy ); /* Flawfinder: ignore */ m_pTail = m_pData + nCopy - 1; } } HX_ASSERT( IsQueueValid() ); return( nByteCount );} // Base_EnQueueBytes()UINT16 CByteQueue::PeekAt( UINT16 nIndex, void *pOutBuffer ) const{ UINT16 nCopy; UINT16 nByteCount; void *pHead; void *pTail; HX_ASSERT( pOutBuffer ); HX_ASSERT( this ); HX_ASSERT( IsQueueValid() ); if (nIndex >= GetQueuedItemCount()) { return( 0 ); } // We don't want to modify m_pTail or m_pHead here, so copy them // and use our copies to manipulate the buffer. pTail = m_pTail; // Advance pHead till it points at the correct position // relative to the index we want. nByteCount = GetElementSize(); pHead = Base_Normalize( m_pHead, (nIndex * nByteCount + 1) ); if (pHead < pTail) { memcpy( pOutBuffer, (UCHAR *)pHead, nByteCount ); /* Flawfinder: ignore */ return( nByteCount ); } else { // pHead > pTail UINT16 nPrevCopy; // Copying from (pHead + 1) to the end of the allocated buffer or // nByteCount which ever comes first. nCopy = __min( (UINT16)(m_pMax - (UCHAR *)pHead), nByteCount ); memcpy( pOutBuffer, pHead, nCopy ); /* Flawfinder: ignore */ // Figure out how much more we have to copy (if any) nPrevCopy = nCopy; nCopy = nByteCount - nCopy; if (nCopy) { // Now we're copying from the base of the allocated array // whatever we didn't copy the first pass around memcpy( (UCHAR *)pOutBuffer + nPrevCopy, m_pData, nCopy ); /* Flawfinder: ignore */ } return( nCopy + nPrevCopy ); }}/* ** UINT16 CByteQueue::Base_PeekBuff( pOutBuffer, nByteCount ) * * PARAMETERS: * pOutBuffer Pointer to buffer to receive data in queue. * nByteCount Number of bytes to copy out of queue. * * DESCRIPTION: * Private primitive used to copy data out of a queue buffer. * This is a workhorse function used in DeQueue(), operator=(), * and our copy constructor. * * RETURNS: * The number of bytes copied out of the buffer. */UINT16 CByteQueue::Base_PeekBuff( void *pOutBuffer, UINT16 nByteCount ) const{ UINT16 nCopy; void *pHead; void *pTail; HX_ASSERT( this ); HX_ASSERT( IsQueueValid() ); // if the Queue is empty, then we can't get anything if (IsEmpty()) { return( 0 ); } // We don't want to modify m_pTail or m_pHead here, so copy them // and use our copies to manipulate the buffer. pTail = m_pTail; pHead = m_pHead; if (pHead < pTail) { // We can do the copy in one pass w/o having to Normalize() the pointer nCopy = __min( nByteCount, Base_GetUsedByteCount() ); memcpy( pOutBuffer, (UCHAR *)pHead + 1, nCopy ); /* Flawfinder: ignore */ return( nCopy ); } else { // pHead > pTail UINT16 nPrevCopy; UCHAR * pSrc; // Copying from (pHead + 1) to the end of the allocated buffer or // nByteCount which ever comes first. pSrc = Base_Normalize( (UCHAR *)pHead, 1 ); nCopy = __min( (UINT16)(m_pMax - pSrc), nByteCount ); memcpy( pOutBuffer, pSrc, nCopy ); /* Flawfinder: ignore */ // The __min() above ensures we don't need to Normalize the pointer pHead = pSrc + nCopy - 1; // Figure out how much more we have to copy (if any) nPrevCopy = nCopy; nCopy = nByteCount - nCopy; if (nCopy) { // Now we're copying from the base of the allocated array // whatever we didn't copy the first pass around memcpy( (UCHAR *)pOutBuffer + nPrevCopy, m_pData, nCopy ); /* Flawfinder: ignore */ } return( nCopy + nPrevCopy ); }} // Base_PeekBuff()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -