void CMemoryStackExtended::Clear(void)
{
	int				i;
	CMemoryStack*	pcStack;
	CMemoryStack	cStack;
	int				iNumStacks;
	int				iNumElements;

	iNumStacks = mcStacks.NumElements();
	if (iNumStacks > 0)
	{
		iNumElements = mcStacks.NumElements();
		for (i = 1; i < iNumElements; i++)
		{
			pcStack = mcStacks.Get(i);
			pcStack->Kill();
		}

		pcStack = mcStacks.Get(0);
		memcpy(&cStack, pcStack, sizeof(CMemoryStack));
		mcStacks.Kill();
		mcStacks.Init();
		cStack.Clear();
		mcStacks.Add(&cStack);
	}
	miElements = 0;
}
void TestMemoryStackOutOfMemory(void)
{
	CMemoryStack	cStack;
	void*			pvData;

	cStack.Init(3);
	pvData = cStack.Add(2);
	AssertNotNull(pvData);

	pvData = cStack.Add(2);
	AssertNull(pvData);

	pvData = cStack.Add(1);
	AssertNotNull(pvData);

	pvData = cStack.Add(1);
	AssertNull(pvData);

	cStack.Clear();

	pvData = cStack.Add(3);
	AssertNotNull(pvData);

	pvData = cStack.Add(1);
	AssertNull(pvData);

	cStack.Kill();
}
void CMemoryStackExtended::Rollback(CStackMarkExtended* pcMark)
{
	int				i;
	CMemoryStack*	pcStack;
	SStackMark*		psMark;

	if (pcMark->miElements == 0)
	{
		Clear();
	}
	else
	{
		for (i = 0; i < pcMark->mcMarks.NumElements(); i++)
		{
			psMark = pcMark->mcMarks.Get(i);

			pcStack = mcStacks.Get(i);
			pcStack->Rollback(psMark);
		}

		for (; i < mcStacks.NumElements(); i++)
		{
			pcStack = mcStacks.Get(i);
			pcStack->Clear();
		}

		miElements = pcMark->miElements;
	}
}
void CMemoryStackExtended::Kill(void)
{
	int				i;
	CMemoryStack*	pcStack;

	for (i = 0; i < mcStacks.NumElements(); i++)
	{
		pcStack = mcStacks.Get(i);
		pcStack->Kill();
	}
	mcStacks.Kill();
}
int CMemoryStackExtended::GetUsedMemory(void)
{
	int				i;
	CMemoryStack*	pcStack;
	int				iSize;

	iSize = 0;
	for (i = 0; i < mcStacks.NumElements(); i++)
	{
		pcStack = mcStacks.Get(i);
		iSize += pcStack->GetUsedMemory();
	}
	return iSize;
}
void CMemoryStackExtended::Mark(CStackMarkExtended* psMark)
{
	int				i;
	CMemoryStack*	pcStack;
	SStackMark		sMark;

	psMark->Init(miElements);

	for (i = 0; i < mcStacks.NumElements(); i++)
	{
		pcStack = mcStacks.Get(i);
		sMark = pcStack->Mark();

		psMark->Add(sMark);
	}
}
void* CMemoryStackExtended::Add(int iSize)
{
	int				i;
	CMemoryStack*	pcStack;
	int				iRemaining;

	if (iSize > miChunkSize)
	{
		pcStack = mcStacks.Add();
		pcStack->Init(iSize);
		miElements++;
		return pcStack->Add(iSize);
	}

	for (i = mcStacks.NumElements()-1; i >= 0; i--)
	{
		pcStack = mcStacks.Get(i);
		iRemaining = pcStack->GetRemainingMemory();
		if (iSize <= iRemaining)
		{
			miElements++;
			return pcStack->Add(iSize);
		}
	}

	pcStack = mcStacks.Add();
	pcStack->Init(miChunkSize);
	miElements++;
	return pcStack->Add(iSize);
}
void TestMemoryStackAdd(void)
{
	CMemoryStack	cStack;
	char			szNumbers[] = {"0123456789"};
	char			szLetters[] = {"ABCDEFGHIJ"};
	char			szStuff[] = {"%^&"};
	char*			sz1;
	char*			sz2;
	char*			sz3;
	char*			sz4;

	cStack.Init(100);

	sz1 = (char*)cStack.Add(10);
	memcpy(sz1, szNumbers, 10);
	sz2 = (char*)cStack.Add(11);
	memcpy(sz2, szLetters, 11);
	
	AssertString("0123456789ABCDEFGHIJ", (char*)cStack.mpvMemory);
	
	cStack.Remove();  //Removing doesn't do anything unless every item is removed.
	AssertString("0123456789ABCDEFGHIJ", (char*)cStack.mpvMemory);
	((char*)cStack.mpvMemory)[20] = '.';

	sz3 = (char*)cStack.Add(4);
	memcpy(sz3, szStuff, 4);	
	AssertString("0123456789ABCDEFGHIJ.%^&", (char*)cStack.mpvMemory);

	cStack.Remove(2);
	sz4 = (char*)cStack.Add(4);
	memcpy(sz4, szStuff, 4);	
	AssertString("%^&", (char*)cStack.mpvMemory);
	
	cStack.Kill();

	AssertNull(cStack.mpvMemory);
}