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.7 KiB
300 lines
5.7 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);
|
|
}
|
|
|