#ifndef __CASC_ARRAY_H__
#define __CASC_ARRAY_H__
class CASC_ARRAY
{
public:
CASC_ARRAY()
{
m_pItemArray = NULL;
m_ItemCountMax = 0;
m_ItemCount = 0;
m_ItemSize = 0;
}
~CASC_ARRAY()
{
Free();
}
template<typename TYPE>
int Create(size_t ItemCountMax)
{
return Create(sizeof(TYPE), ItemCountMax);
}
int Create(size_t ItemSize, size_t ItemCountMax)
{
assert(ItemCountMax != 0);
if((m_pItemArray = CASC_ALLOC<BYTE>(ItemSize * ItemCountMax)) == NULL)
return ERROR_NOT_ENOUGH_MEMORY;
m_ItemCountMax = ItemCountMax;
m_ItemCount = 0;
m_ItemSize = ItemSize;
return ERROR_SUCCESS;
}
void * Insert(size_t NewItemCount, bool bEnlargeAllowed = true)
{
void * pNewItems;
if(!EnlargeArray(m_ItemCount + NewItemCount, bEnlargeAllowed))
return NULL;
pNewItems = m_pItemArray + (m_ItemCount * m_ItemSize);
m_ItemCount += NewItemCount;
return pNewItems;
}
void * Insert(const void * NewItems, size_t NewItemCount, bool bEnlargeAllowed = true)
{
void * pNewItem = Insert(NewItemCount, bEnlargeAllowed);
if(pNewItem && NewItems)
memcpy(pNewItem, NewItems, (NewItemCount * m_ItemSize));
return pNewItem;
}
void * ItemAt(size_t ItemIndex)
{
return (ItemIndex < m_ItemCount) ? (m_pItemArray + (ItemIndex * m_ItemSize)) : NULL;
}
void * LastItem()
{
return m_pItemArray + (m_ItemCount * m_ItemSize);
}
void * InsertAt(size_t ItemIndex)
{
LPBYTE pbLastItem;
LPBYTE pbNewItem;
if(!EnlargeArray(ItemIndex + 1, true))
return NULL;
pbLastItem = m_pItemArray + (m_ItemCount * m_ItemSize);
pbNewItem = m_pItemArray + (ItemIndex * m_ItemSize);
m_ItemCount = CASCLIB_MAX(m_ItemCount, ItemIndex+1);
if(pbNewItem > pbLastItem)
{
memset(pbLastItem, 0, (pbNewItem - pbLastItem));
m_ItemCount = ItemIndex + 1;
}
return pbNewItem;
}
size_t IndexOf(const void * pItem)
{
LPBYTE pbItem = (LPBYTE)pItem;
assert((m_pItemArray <= pbItem) && (pbItem <= m_pItemArray + (m_ItemCount * m_ItemSize)));
assert(((pbItem - m_pItemArray) % m_ItemSize) == 0);
return ((pbItem - m_pItemArray) / m_ItemSize);
}
void * ItemArray()
{
return m_pItemArray;
}
size_t ItemCount()
{
return m_ItemCount;
}
size_t ItemCountMax()
{
return m_ItemCountMax;
}
size_t ItemSize()
{
return m_ItemSize;
}
bool IsInitialized()
{
return (m_pItemArray && m_ItemCountMax);
}
void Reset()
{
memset(m_pItemArray, 0, m_ItemCountMax * m_ItemSize);
m_ItemCount = 0;
}
void Free()
{
CASC_FREE(m_pItemArray);
m_ItemCountMax = m_ItemCount = m_ItemSize = 0;
}
#ifdef CASCLIB_DEBUG
size_t BytesAllocated()
{
return m_ItemCountMax * m_ItemSize;
}
void Dump(const char * szFileName)
{
FILE * fp;
if((fp = fopen(szFileName, "wb")) != NULL)
{
fwrite(m_pItemArray, m_ItemSize, m_ItemCount, fp);
fclose(fp);
}
}
#endif
protected:
bool EnlargeArray(size_t NewItemCount, bool bEnlargeAllowed)
{
LPBYTE NewItemArray;
size_t ItemCountMax;
assert(m_pItemArray != NULL);
assert(m_ItemCountMax != 0);
if(NewItemCount > m_ItemCountMax)
{
if(bEnlargeAllowed == false)
return false;
ItemCountMax = m_ItemCountMax;
while (ItemCountMax < NewItemCount)
ItemCountMax = ItemCountMax << 1;
NewItemArray = CASC_REALLOC(m_pItemArray, (ItemCountMax * m_ItemSize));
if(NewItemArray == NULL)
return false;
m_ItemCountMax = ItemCountMax;
m_pItemArray = NewItemArray;
}
return true;
}
LPBYTE m_pItemArray; size_t m_ItemCountMax; size_t m_ItemCount; size_t m_ItemSize; };
#endif