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.
291 lines
6.3 KiB
291 lines
6.3 KiB
//+------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 1998, Microsoft Corporation
|
|
//
|
|
// File: simparray.cpp
|
|
//
|
|
// Contents: Simple growable array class
|
|
//
|
|
// Classes: CSimpArray
|
|
//
|
|
// Functions:
|
|
//
|
|
// History:
|
|
// jstamerj 1998/07/14 11:37:25: Created.
|
|
//
|
|
//-------------------------------------------------------------
|
|
#include "precomp.h"
|
|
#include "simparray.h"
|
|
|
|
|
|
//+------------------------------------------------------------
|
|
//
|
|
// Function: CSimpArray::Initialize
|
|
//
|
|
// Synopsis: Initializes array to a specified size. Only necessary to
|
|
// call if you wish to optimize usage by starting with a specified
|
|
// array size.
|
|
//
|
|
// Arguments:
|
|
// dwSize: Initial array size
|
|
//
|
|
// Returns:
|
|
// S_OK: Success
|
|
// E_OUTOFMEMORY
|
|
//
|
|
// History:
|
|
// jstamerj 1998/07/14 12:22:01: Created.
|
|
//
|
|
//-------------------------------------------------------------
|
|
template <class T> HRESULT CSimpArray<T>::Initialize(
|
|
DWORD dwSize)
|
|
{
|
|
_ASSERT(m_dwArrayAllocSize == 0);
|
|
_ASSERT(m_dwArrayClaimedSize == 0);
|
|
_ASSERT(m_dwArrayValidSize == 0);
|
|
|
|
_ASSERT(m_rgData == NULL);
|
|
|
|
m_rgData = new T [dwSize];
|
|
|
|
if(m_rgData == NULL) {
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
} else {
|
|
|
|
m_dwArrayAllocSize = dwSize;
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------
|
|
//
|
|
// Function: CSimpArray::Add
|
|
//
|
|
// Synopsis: Adds one element to the array
|
|
//
|
|
// Arguments:
|
|
// Data: Value to add to the array
|
|
//
|
|
// Returns:
|
|
// S_OK: Success
|
|
// E_OUTOFMEMORY
|
|
//
|
|
// History:
|
|
// jstamerj 1998/07/14 15:50:00: Created.
|
|
//
|
|
//-------------------------------------------------------------
|
|
template <class T> HRESULT CSimpArray<T>::Add(
|
|
T Data)
|
|
{
|
|
//
|
|
// Same functionality as AddArray except this is an array with
|
|
// only one element
|
|
//
|
|
return AddArray(1, &Data);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------
|
|
//
|
|
// Function: CSimpArray::AddArray
|
|
//
|
|
// Synopsis: Adds an array of T's to our array
|
|
//
|
|
// Arguments:
|
|
// dwSize: size of passed in array
|
|
// pData: pointer to array data
|
|
//
|
|
// Returns:
|
|
// S_OK: Success
|
|
// E_OUTOFMEMORY
|
|
//
|
|
// History:
|
|
// jstamerj 1998/07/14 12:27:18: Created.
|
|
//
|
|
//-------------------------------------------------------------
|
|
template <class T> HRESULT CSimpArray<T>::AddArray(
|
|
DWORD dwSize,
|
|
T * pData)
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwCopyIndex;
|
|
|
|
_ASSERT(dwSize);
|
|
_ASSERT(pData);
|
|
|
|
hr = AllocArrayRange(dwSize, &dwCopyIndex);
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
//
|
|
// Copy the memory from one array to another
|
|
//
|
|
CopyMemory(&(m_rgData[dwCopyIndex]), pData, sizeof(T) * dwSize);
|
|
|
|
//
|
|
// Increment array element counter
|
|
//NOTE: This really isn't thread safe in the sense that if
|
|
//we're in this call and someone is reading the array,
|
|
//m_dwArrayValidSize could be invalid.
|
|
//
|
|
InterlockedExchangeAdd((PLONG) &m_dwArrayValidSize, dwSize);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------
|
|
//
|
|
// Function: AllocArrayRange
|
|
//
|
|
// Synopsis: Allocates a range on the array for the caller (of unused T's)
|
|
//
|
|
// Arguments:
|
|
// dwSize: Size of the range you'd like
|
|
// pdwIndex: On success, starting index of your allocated range
|
|
//
|
|
// Returns:
|
|
// S_OK: Success
|
|
// E_OUTOFMEMORY
|
|
//
|
|
// History:
|
|
// jstamerj 1998/07/14 12:37:54: Created.
|
|
//
|
|
//-------------------------------------------------------------
|
|
template <class T> HRESULT CSimpArray<T>::AllocArrayRange(
|
|
DWORD dwSize,
|
|
PDWORD pdwIndex)
|
|
{
|
|
HRESULT hr;
|
|
|
|
_ASSERT(dwSize);
|
|
_ASSERT(pdwIndex);
|
|
|
|
AcquireSpinLock(&m_slAllocate);
|
|
|
|
hr = ReAllocArrayIfNecessary(m_dwArrayClaimedSize + dwSize);
|
|
|
|
if(SUCCEEDED(hr)) {
|
|
*pdwIndex = m_dwArrayClaimedSize;
|
|
m_dwArrayClaimedSize += dwSize;
|
|
}
|
|
|
|
ReleaseSpinLock(&m_slAllocate);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------
|
|
//
|
|
// Function: CSimpArray::ReAllocArrayIfNecessary
|
|
//
|
|
// Synopsis: Grow the array size if necessary
|
|
// Not thread safe; locking must be done outside
|
|
//
|
|
// Arguments:
|
|
// dwSize: New size desired
|
|
//
|
|
// Returns:
|
|
// S_OK: Success, array grown
|
|
// S_FALSE: Success, not necessary to grow array
|
|
// E_OUTOFMEMORY
|
|
//
|
|
// History:
|
|
// jstamerj 1998/07/14 13:56:16: Created.
|
|
//
|
|
//-------------------------------------------------------------
|
|
template <class T> HRESULT CSimpArray<T>::ReAllocArrayIfNecessary(
|
|
DWORD dwSize)
|
|
{
|
|
DWORD dwNewSize;
|
|
T *pNewArray;
|
|
T *pOldArray;
|
|
|
|
if(dwSize <= m_dwArrayAllocSize)
|
|
return S_FALSE;
|
|
|
|
//
|
|
// Calculate new size desired
|
|
//
|
|
#ifdef CSIMPARRAY_DOUBLE
|
|
|
|
if(m_dwArrayAllocSize == 0) {
|
|
|
|
dwNewSize = CSIMPARRAY_DEFAULT_INITIAL_SIZE;
|
|
|
|
} else {
|
|
|
|
dwNewSize = m_dwArrayAllocSize;
|
|
|
|
}
|
|
|
|
while(dwNewSize < dwSize)
|
|
dwNewSize *= 2;
|
|
|
|
#else
|
|
|
|
dwNewSize = dwSize;
|
|
|
|
#endif
|
|
|
|
_ASSERT(dwNewSize >= dwSize);
|
|
|
|
pNewArray = new T [dwNewSize];
|
|
|
|
if(pNewArray == NULL)
|
|
return E_OUTOFMEMORY;
|
|
|
|
CopyMemory(pNewArray, m_rgData, sizeof(T) * m_dwArrayAllocSize);
|
|
|
|
//
|
|
// pNewArray is valid. Make the switch now.
|
|
//
|
|
pOldArray = m_rgData;
|
|
m_rgData = pNewArray;
|
|
m_dwArrayAllocSize = dwNewSize;
|
|
|
|
//
|
|
// Release old array memory
|
|
//
|
|
delete pOldArray;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
#ifdef NEVER
|
|
//+------------------------------------------------------------
|
|
//
|
|
// Function: Cat_NeverCalled_SimpArrayTemplateDummy
|
|
//
|
|
// Synopsis: Dummy function that is never called but forces compiler
|
|
// to generate code for desired types
|
|
//
|
|
// Arguments: NONE
|
|
//
|
|
// Returns: NOTHING
|
|
//
|
|
// History:
|
|
// jstamerj 1998/07/16 15:28:37: Created.
|
|
//
|
|
//-------------------------------------------------------------
|
|
#include "smtpevent.h"
|
|
|
|
VOID Cat_NeverCalled_SimpArrayTemplateDummy()
|
|
{
|
|
_ASSERT(0 && "Never call this function!");
|
|
CSimpArray<ICategorizerItem *> csaItem;
|
|
CSimpArray<ICategorizerItemAttributes *> csaItemAttributes;
|
|
|
|
csaItem.Initialize(0);
|
|
csaItemAttributes.Initialize(0);
|
|
csaItem.Add(NULL);
|
|
csaItemAttributes.Add(NULL);
|
|
csaItem.AddArray(0, NULL);
|
|
csaItemAttributes.AddArray(0, NULL);
|
|
}
|
|
#endif //NEVER
|