/*TITLE persistent array class implementation */

/****keyword-flag*** "%v %f %n" */
/* "3 3-May-98,19:52:22 PERSIST.CPP" */

#include "common.h"

PersistentArrayUlong::PersistentArrayUlong()
{
	m_ObjectNumber = 0;
}

PersistentArrayUlong::~PersistentArrayUlong()
{
}

PersistentArrayUlong::PersistentArrayUlong(QuantumFile *p_QF, ModifiableElement p_ArrayName)
{
	m_ArrayName = p_ArrayName;
	m_QF = p_QF;
	m_MOA = MainObjectArrayPtr(m_QF);

	m_ObjectNumber = m_MOA->FindObjectByName(m_ArrayName);
	if (m_ObjectNumber == NoObject)
		{
		m_ObjectNumber = m_MOA->FindAvailableObject();
		m_MOA->CreateMainObject(m_ArrayName,m_ObjectNumber,1,
			MaxFileQuantumCount);
		}
}

void PersistentArrayUlong::StoreElement(Ulong p_Index, Ulong p_Element)
{
	ArrayIndex SegmentNumber;
	ArrayIndex ElementNumber;
	ModifiableElement TempVector;
	AccessVector<Ulong> TempUlongVector;
	ArrayIndex OldSegmentCount;
	ArrayIndex RequiredSegmentCount;
	
	SegmentNumber = ArrayIndex(p_Index / UlongEntriesPerBlock);
	ElementNumber = ArrayIndex(p_Index % UlongEntriesPerBlock);

	qfassert(SegmentNumber < m_MOA->GetMainObjectMaxElementCount(m_ObjectNumber));
	OldSegmentCount = m_MOA->GetMainObjectElementCount(m_ObjectNumber);
	RequiredSegmentCount = SegmentNumber+1;
	if (RequiredSegmentCount > OldSegmentCount)
		m_MOA->GrowMainObject(m_ObjectNumber,RequiredSegmentCount);

	TempVector = m_MOA->GetModifiableElement(m_ObjectNumber,SegmentNumber);
	if (TempVector.GetSize() == 0)
		{
		TempVector = ModifiableElement(UlongEntriesPerBlock*sizeof(Ulong));
		memset(TempVector.GetDataAddress(),0,TempVector.GetSize());
		}			

	TempUlongVector = AccessVector<Ulong>(UlongEntriesPerBlock,(Ulong *)TempVector.GetDataAddress());
	TempUlongVector[ElementNumber] = p_Element;

	m_MOA->PutElement(m_ObjectNumber,SegmentNumber,TempVector);
}

Ulong PersistentArrayUlong::GetElement(Ulong p_Index)
{
	ArrayIndex SegmentNumber;
	ArrayIndex ElementNumber;
	ModifiableElement TempVector;
	AccessVector<Ulong> TempUlongVector;

	SegmentNumber = ArrayIndex(p_Index / UlongEntriesPerBlock);
	ElementNumber = ArrayIndex(p_Index % UlongEntriesPerBlock);

	qfassert(SegmentNumber < m_MOA->GetMainObjectElementCount(m_ObjectNumber));
	TempVector = m_MOA->GetModifiableElement(m_ObjectNumber,SegmentNumber);
	TempUlongVector = AccessVector<Ulong>(UlongEntriesPerBlock,(Ulong *)TempVector.GetDataAddress());
	return TempUlongVector[ElementNumber];
}

PersistentArrayUlongRef::PersistentArrayUlongRef(PersistentArrayUlong &p_PAU, 
Ulong p_Index) : m_PAU(p_PAU), m_Index(p_Index)
{
}

PersistentArrayUlongRef &PersistentArrayUlongRef::operator =(Ulong p_Element)
{
	m_PAU.StoreElement(m_Index,p_Element);
	return *this;
}

PersistentArrayUlongRef::operator Ulong()
{
	return m_PAU.GetElement(m_Index);
}

PersistentArrayUlongRef PersistentArrayUlong::operator[ ](Ulong p_Index)
{
	return PersistentArrayUlongRef(*this, p_Index);
}

