301 lines
5.4 KiB
Plaintext
301 lines
5.4 KiB
Plaintext
|
/*++
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
|