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.
|
|
/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
SMALLARR.CPP
Abstract:
Small Array
History:
--*/
#include "precomp.h"
#include <stdio.h>
#include "smallarr.h"
CSmallArrayBlob* CSmallArrayBlob::CreateBlob(int nInitialSize) { // Allocate enough space for the header, plus the data
// ===================================================
DWORD dwSize = sizeof(CSmallArrayBlob) - sizeof(void*) * ANYSIZE_ARRAY; dwSize += nInitialSize * sizeof(void*); CSmallArrayBlob* pBlob = (CSmallArrayBlob*)(new BYTE[dwSize]); if(pBlob == NULL) return NULL;
// Initialize it appropriately
// ===========================
pBlob->Initialize(nInitialSize); return pBlob; }
void CSmallArrayBlob::Initialize(int nInitialSize) { // It has already been allocated to be big enough
// ==============================================
m_nExtent = nInitialSize; m_nSize = 0; }
CSmallArrayBlob* CSmallArrayBlob::Grow() { // Allocate a new array of twice our size
// ======================================
CSmallArrayBlob* pNew = CreateBlob(m_nExtent*2); if(pNew == NULL) return NULL; // Copy our data into it
// =====================
pNew->CopyData(this);
// Delete ourselves!
// =================
delete this; return pNew; }
void CSmallArrayBlob::CopyData(CSmallArrayBlob* pOther) { m_nSize = pOther->m_nSize; memcpy(m_apMembers, pOther->m_apMembers, sizeof(void*) * m_nSize); }
CSmallArrayBlob* CSmallArrayBlob::EnsureExtent(int nDesired) { if(m_nExtent < nDesired) return Grow(); // will delete this!
else return this; } CSmallArrayBlob* CSmallArrayBlob::InsertAt(int nIndex, void* pMember) { // Ensure there is enough space
// ============================
CSmallArrayBlob* pArray = EnsureExtent(m_nSize+1); if(pArray == NULL) return NULL;
// Move the data forward to make room
// ==================================
if(pArray->m_nSize > nIndex) { memmove(pArray->m_apMembers + nIndex + 1, pArray->m_apMembers + nIndex, sizeof(void*) * (pArray->m_nSize - nIndex)); }
// Insert
// ======
pArray->m_apMembers[nIndex] = pMember; pArray->m_nSize++;
return pArray; } void CSmallArrayBlob::SetAt(int nIndex, void* pMember, void** ppOld) { // Make sure we even have that index (sparse set)
// ==============================================
EnsureExtent(nIndex+1); if(nIndex >= m_nSize) m_nSize = nIndex+1;
// Save old value
// ==============
if(ppOld) *ppOld = m_apMembers[nIndex];
// Replace
// =======
m_apMembers[nIndex] = pMember; }
CSmallArrayBlob* CSmallArrayBlob::RemoveAt(int nIndex, void** ppOld) { // Save old value
// ==============
if(ppOld) *ppOld = m_apMembers[nIndex]; // Move the data back
// ==================
memcpy(m_apMembers + nIndex, m_apMembers + nIndex + 1, sizeof(void*) * (m_nSize - nIndex - 1));
m_nSize--;
// Ensure we are not too large
// ===========================
return ShrinkIfNeeded(); }
CSmallArrayBlob* CSmallArrayBlob::ShrinkIfNeeded() { if(m_nSize < m_nExtent / 4) return Shrink(); // will delete this!
else return this; }
CSmallArrayBlob* CSmallArrayBlob::Shrink() { // Allocate a new blob of half our size
// ====================================
CSmallArrayBlob* pNew = CreateBlob((m_nExtent+1)/2); if(pNew == NULL) { // Out of memory --- we'll just have to stay large
// ===============================================
return this; }
// Copy our data
// =============
pNew->CopyData(this);
delete this; // we are no longer needed
return pNew; }
void CSmallArrayBlob::Trim() { while(m_nSize > 0 && m_apMembers[m_nSize-1] == NULL) m_nSize--; }
void CSmallArrayBlob::Sort() { qsort(m_apMembers, m_nSize, sizeof(void*), CSmallArrayBlob::CompareEls); }
int __cdecl CSmallArrayBlob::CompareEls(const void* pelem1, const void* pelem2) { return *(DWORD_PTR*)pelem1 - *(DWORD_PTR*)pelem2; }
void** CSmallArrayBlob::CloneData() { void** ppReturn = new void*[m_nSize]; if (ppReturn) memcpy(ppReturn, m_apMembers, m_nSize * sizeof(void*));
return ppReturn; }
|