Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

174 lines
5.0 KiB

/*==========================================================================
*
* Copyright (C) 1995 - 2000 Microsoft Corporation. All Rights Reserved.
*
* File: AutoArray.inl
* Content: CAutoArray methods
*
* History:
* Date By Reason
* ====== == ======
* 12-12-2001 simonpow Created
***************************************************************************/
template <class T>
void CAutoArray<T>::SetExistingElements(DWORD dwIndex, const T * pElemData, DWORD dwNumElem)
{
DNASSERT(dwIndex+dwNumElem<=m_dwSize);
//have to handle the case where pElemData is actually a pointer
//into this arrays data (don't want to overwrite original data
//with copied data prematurely).
//copy from top down if destination is in front of source
T * pDest=m_pData+dwIndex;
if (pDest>pElemData)
{
T * pDestScan=pDest+dwNumElem-1;
pElemData+=(dwNumElem-1);
while (pDestScan>=pDest)
*pDestScan--=*pElemData--;
}
//otherwise it must be bottom up
else
{
T * pDestScan=pDest;
pDest+=dwNumElem;
while (pDestScan<pDest)
*pDestScan++=*pElemData++;
}
}
//make array larger so index falls within its range
//N.B. Caller must have tested that dwIndex>=m_dwSize already!
template <class T>
BOOL CAutoArray<T>::GrowToAtLeast(DWORD dwIndex)
{
//allocate new memory block
DWORD dwNewSize=GetArraySize(dwIndex);
T * pNewData=new T[dwNewSize];
if (!pNewData)
return FALSE;
//if we've got existing data copy it to new block
if (m_pData)
{
for (DWORD dwLoop=0; dwLoop<m_dwSize; dwLoop++)
pNewData[dwLoop]=m_pData[dwLoop];
delete[] m_pData;
}
//set state based on newly allocated block
m_pData=pNewData;
m_dwSize=dwNewSize;
return TRUE;
}
//Set a block of elements in the array
template <class T>
BOOL CAutoArray<T>::SetElements(DWORD dwIndex, const T * pElemData, DWORD dwNumElem)
{
//calculate the top dwIndex+1 we need to touch
DWORD dwCeilingIndex=dwIndex+dwNumElem;
DWORD dwLoop;
//Are we going to exceed current array size
if (dwCeilingIndex<=m_dwSize)
{
//No=easy case, just set new elements
for (dwLoop=dwIndex; dwLoop<dwCeilingIndex; dwLoop++)
m_pData[dwLoop]=*pElemData++;
return TRUE;
}
//need to grow the array, calc size/allocate new array based on the top index
DWORD dwNewSize=GetArraySize(dwCeilingIndex-1);
T * pNewData=new T[dwNewSize];
if (!pNewData)
return FALSE;
//copy in new elements. N.B. We have do this now and not leave it to
//end since elem could be a pointer to our own data. Hence, if we
//wait we'll either have duff data (if we only copied the elements that
//will survive) or we'll risk overwriting elements that we've only
//just copied
for (dwLoop=dwIndex; dwLoop<dwCeilingIndex; dwLoop++)
pNewData[dwLoop]=*pElemData++;
//copy across any old elements, clipping against the block
//of elements just inserted
if (m_pData)
{
if (dwIndex<m_dwSize)
m_dwSize=dwIndex;
for (dwLoop=0; dwLoop<m_dwSize; dwLoop++)
pNewData[dwLoop]=m_pData[dwLoop];
delete[] m_pData;
}
m_pData=pNewData;
m_dwSize=dwNewSize;
return TRUE;
}
//Move a block of elements within the array
template <class T>
BOOL CAutoArray<T>::MoveElements(DWORD dwIndex, DWORD dwNumElements,
DWORD dwNewIndex, BOOL bCopySemantics)
{
DNASSERT(dwIndex+dwNumElements<=m_dwSize);
DWORD dw;
//Are we shifting element block down?
if (dwNewIndex<=dwIndex)
{
//Yes=easy case. Just copy elements from bottom up
for (dw=0; dw<dwNumElements; dw++)
m_pData[dwNewIndex+dw]=m_pData[dwIndex+dw];
return TRUE;
}
//New to move element up. Do we need to grow array?
dw=dwNewIndex+dwNumElements-1;
if (dw<m_dwSize)
{
//No=easy case. Just copy elements top down
dwNewIndex--;
dwIndex--;
for (dw=dwNumElements; dw>0; dw--)
m_pData[dwNewIndex+dw]=m_pData[dwIndex+dw];
return TRUE;
}
//array does need to grow, so create larger array
DWORD dwNewSize=GetArraySize(dw);
T * pNewData=new T[dwNewSize];
if (!pNewData)
return FALSE;
if (m_pData)
{
//copy across block of elements below the
//block we've got to move
for (dw=0; dw<dwIndex; dw++)
pNewData[dw]=m_pData[dw];
//move the block of elements we were originally
//asked to move
for (dw=0; dw<dwNumElements; dw++)
pNewData[dwNewIndex+dw]=m_pData[dwIndex+dw];
//if we were asked to use copy type semantics
//then copy across the portion of the moved block
//that isn't being overwritten in its new position
if (bCopySemantics)
{
for (dw=dwIndex; dw<dwNewIndex; dw++)
pNewData[dw]=m_pData[dw];
}
//move elements above the block we were originally asked
//to move. This copy needs to be clipped against the bottom
//of the moved element block.
if (dwNewIndex<m_dwSize)
m_dwSize=dwNewIndex;
for (dw=dwIndex+dwNumElements; dw<m_dwSize; dw++)
pNewData[dw]=m_pData[dw];
//release the old array memory
delete[] m_pData;
}
m_pData=pNewData;
m_dwSize=dwNewSize;
return TRUE;
}