// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include "carray.h"
//constructs new object - 0 size
CArray::CArray()
{
m_iAllocatedBlocks = 0;
m_iArrayItems = 0;
m_pFirstBlock = NULL;
}
//destructor calls destroy
CArray::~CArray()
{
Destroy();
}
//destructs all sub array blocks
void CArray::Destroy()
{
if ( m_iAllocatedBlocks )
{
SubArray* pCurr = m_pFirstBlock;
SubArray* pNext;
while ( pCurr )
{
pNext = pCurr->pNext;
delete pCurr;
pCurr = pNext;
}
}
m_iAllocatedBlocks = 0;
m_iArrayItems = 0;
m_pFirstBlock = NULL;
}
//deletes last item
BOOL CArray::DeleteLast()
{
m_iArrayItems--;
return TRUE;
}
//gets value from array
void* CArray::GetAt( int iItem )
{
if ( ( iItem + 1 ) > m_iArrayItems )
return NULL;
int iBlockNeeded = iItem / CARRAY_SUB_SIZE;
int iBlockCurr = 0;
SubArray* pCurr = m_pFirstBlock;
while( iBlockCurr < iBlockNeeded )
{
pCurr = pCurr->pNext;
iBlockCurr++;
if ( !pCurr )
return NULL;
}
return pCurr->array[ iItem % CARRAY_SUB_SIZE ];
}
//sets array's value - must exist before
BOOL CArray::SetAt( int iItem, void* pPtr )
{
if ( ( iItem + 1 ) > m_iArrayItems )
return FALSE;
int iBlockNeeded = iItem / CARRAY_SUB_SIZE;
int iBlockCurr = 0;
SubArray* pCurr = m_pFirstBlock;
while( iBlockCurr < iBlockNeeded )
{
pCurr = pCurr->pNext;
iBlockCurr++;
if ( !pCurr )
return FALSE;
}
pCurr->array[ iItem % CARRAY_SUB_SIZE ] = pPtr;
return TRUE;
}
//adds array's value
BOOL CArray::Add( void* pPtr )
{
if ( ((( m_iArrayItems ) / CARRAY_SUB_SIZE ) + 1 ) > m_iAllocatedBlocks )
{
//if we need new block, we try to add them
if ( !AddNewBlock() )
return FALSE;
}
m_iArrayItems++;
if ( !SetAt( m_iArrayItems - 1, pPtr ) )
{
m_iArrayItems--;
return FALSE;
}
return TRUE;
}
//adds new sub array block
BOOL CArray::AddNewBlock()
{
SubArray* pCurr = m_pFirstBlock;
SubArray* pNext = m_pFirstBlock;
//find end
while ( pNext )
{
pCurr = pNext;
pNext = pCurr->pNext;
}
if ( !( pNext = new SubArray ) )
return FALSE;
memset( pNext, 0, sizeof( SubArray) );
if ( !m_pFirstBlock )
m_pFirstBlock = pNext;
else
pCurr->pNext = pNext;
m_iAllocatedBlocks++;
return TRUE;
}