Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

300 lines
5.4 KiB

/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
SMALLARR.INL
Abstract:
Small Array Inlines.
History:
--*/
CSmallArray::CSmallArray()
{
SetBlob(NULL);
}
CSmallArray::~CSmallArray()
{
Empty();
}
void* CSmallArray::GetAt(int nIndex) const
{
if(IsSingleton())
return GetOnlyMember(); // nIndex better be 0!
else
{
const CSmallArrayBlob* pBlob;
if (pBlob = GetBlob())
return pBlob->GetAt(nIndex);
else
return NULL;
}
}
void CSmallArray::SetAt(int nIndex, void *p, void** ppOld)
{
if(IsSingleton() && nIndex == 0)
{
// Changing our only element
// =========================
if(ppOld) *ppOld = GetOnlyMember();
SetOnlyMember(p);
}
else
{
EnsureBlob(nIndex+1);
CSmallArrayBlob* pBlob;
if (pBlob = GetBlob())
pBlob->SetAt(nIndex, p, ppOld);
}
}
int CSmallArray::RemoveAt(int nIndex, void** ppOld)
{
if(IsSingleton())
{
// Removing our only element --- nIndex better be 0
// ================================================
Empty();
}
else
{
CSmallArrayBlob* pBlob;
if (pBlob = GetBlob())
{
SetBlob(pBlob->RemoveAt(nIndex, ppOld));
pBlob = NULL; // to ward off temptation --- pBlob is no longer valid
// Check if the blob has become empty
// ==================================
pBlob = GetBlob();
if(pBlob && pBlob->Size() == 0)
Empty();
}
else
return CFlexArray::out_of_memory;
}
return CFlexArray::no_error;
}
int CSmallArray::InsertAt(int nIndex, void* pMember)
{
if(IsEmpty())
{
// Inserting our first element --- nIndex better be 0
// ==================================================
SetOnlyMember(pMember);
}
else
{
EnsureBlob(nIndex+1);
CSmallArrayBlob* pBlob;
if (pBlob = GetBlob())
SetBlob(pBlob->InsertAt(nIndex, pMember));
else
return CFlexArray::out_of_memory;
}
return CFlexArray::no_error;
}
int CSmallArray::Size() const
{
if(IsEmpty())
return 0;
else if(IsSingleton())
return 1;
else
{
const CSmallArrayBlob* pBlob;
if (pBlob = GetBlob())
return pBlob->Size();
else
return 0;
}
}
void CSmallArray::Trim()
{
if(IsSingleton())
{
// If the member is NULL, get rid of it
// ====================================
if(GetOnlyMember() == NULL)
Empty();
}
else if(IsEmpty())
{
}
else
{
CSmallArrayBlob* pBlob;
if (pBlob = GetBlob())
{
pBlob->Trim();
// If the blob is now empty, convert to "empty"
// ============================================
if(pBlob->Size() == 0)
Empty();
}
}
}
void CSmallArray::Empty()
{
if(IsBlob())
delete [] GetBlob();
SetBlob(NULL);
}
void CSmallArray::EnsureBlob(int nMinSize)
{
if(IsSingleton())
{
// Allocate a new blob
// ===================
CSmallArrayBlob* pBlob = CSmallArrayBlob::CreateBlob(nMinSize);
// Copy the data
// =============
if(pBlob != NULL)
pBlob->InsertAt(0, GetOnlyMember());
SetBlob(pBlob);
}
}
void** CSmallArray::GetArrayPtr()
{
if(IsEmpty())
return NULL;
else if(IsSingleton())
return &GetOnlyMember();
else
{
CSmallArrayBlob* pBlob;
if (pBlob = GetBlob())
return pBlob->GetArrayPtr();
else
return NULL;
}
}
void** CSmallArray::UnbindPtr()
{
void** ppReturn = NULL;
if(IsSingleton())
{
ppReturn = new void*[1];
if (ppReturn)
*ppReturn = GetOnlyMember();
}
else if(IsBlob())
{
CSmallArrayBlob* pBlob;
if (pBlob = GetBlob())
ppReturn = pBlob->CloneData();
}
Empty();
return ppReturn;
}
void* const* CSmallArray::GetArrayPtr() const
{
if(IsEmpty())
return NULL;
else if(IsSingleton())
return &GetOnlyMember();
else
{
const CSmallArrayBlob* pBlob;
if (pBlob = GetBlob())
return pBlob->GetArrayPtr();
else
return NULL;
}
}
void CSmallArray::Sort()
{
if(IsBlob())
{
CSmallArrayBlob* pBlob;
if (pBlob = GetBlob())
pBlob->Sort();
}
}
void*& CSmallArray::GetOnlyMember()
{
return m_pData;
}
void* const & CSmallArray::GetOnlyMember() const
{
return m_pData;
}
void CSmallArray::SetOnlyMember(void* p)
{
m_pData = p;
}
BOOL CSmallArray::IsEmpty() const
{
return (m_pData == (void*)1);
}
BOOL CSmallArray::IsSingleton() const
{
return (((DWORD_PTR)m_pData & 1) == 0);
}
BOOL CSmallArray::IsBlob() const
{
return (m_pData != (void*)1) && ((DWORD_PTR)m_pData & 1);
}
CSmallArrayBlob* CSmallArray::GetBlob()
{
return (CSmallArrayBlob*)((DWORD_PTR)m_pData & ~(DWORD_PTR)1);
}
const CSmallArrayBlob* CSmallArray::GetBlob() const
{
return (CSmallArrayBlob*)((DWORD_PTR)m_pData & ~(DWORD_PTR)1);
}
void CSmallArray::SetBlob(CSmallArrayBlob* pBlob)
{
m_pData = (CSmallArrayBlob*)((DWORD_PTR)pBlob | 1);
}