/*TITLE implementation of logical layer classes*/ /****keyword-flag*** "%v %f %n" */ /* "9 11-May-98,18:38:46 NEWQUANT.CPP" */ #include "common.h" FreeSpaceArrayPtr::FreeSpaceArrayPtr() { m_FSA = new FreeSpaceArray; m_FSA->m_ReferenceCount = 1; } FreeSpaceArrayPtr::FreeSpaceArrayPtr(QuantumFile *p_QuantumFile) { m_FSA = new FreeSpaceArray(p_QuantumFile); m_FSA->m_ReferenceCount = 1; } FreeSpaceArrayPtr::FreeSpaceArrayPtr(const FreeSpaceArrayPtr& p_FSAP) { m_FSA = p_FSAP.m_FSA; m_FSA->m_ReferenceCount++; } FreeSpaceArrayPtr::FreeSpaceArray *FreeSpaceArrayPtr::operator->() { return m_FSA; } FreeSpaceArrayPtr& FreeSpaceArrayPtr::operator=(const FreeSpaceArrayPtr& p_FSAP) { m_FSA->m_ReferenceCount--; if (m_FSA->m_ReferenceCount <= 0 && m_FSA != p_FSAP.m_FSA) delete m_FSA; m_FSA = p_FSAP.m_FSA; m_FSA->m_ReferenceCount ++; return *this; } FreeSpaceArrayPtr::~FreeSpaceArrayPtr() { m_FSA->m_ReferenceCount --; if (m_FSA->m_ReferenceCount <= 0) delete m_FSA; } FreeSpaceArrayPtr::FreeSpaceArray::FreeSpaceArray(): m_FreeSpaceListCount(0), m_FreeSpaceListBlockCount(0), m_CurrentLowestFreeBlock(0), m_QuantumBlockNumberAdjustment(0) { } FreeSpaceArrayPtr::FreeSpaceArray::~FreeSpaceArray() { } FreeSpaceArrayPtr::FreeSpaceArray::FreeSpaceArray(QuantumFile *p_MRU) { ArrayIndex i; m_CurrentLowestFreeBlock = 0; m_FreeSpaceListCount = p_MRU->QGetFreeSpaceListCount(); m_FreeSpaceListBlockCount = p_MRU->QGetFreeSpaceListBlockCount(); m_QuantumBlockNumberAdjustment = p_MRU->GetQuantumNumberAdjustment(); m_BlockPtr.SetSize(p_MRU->QGetFreeSpaceListBlockCount()); for (i = 0; i < m_BlockPtr.GetSize(); i ++) m_BlockPtr[i] = p_MRU->MakeFreeSpaceBlockPtr(i); } QFreeSpaceEntry FreeSpaceArrayPtr::FreeSpaceArray::Get(ArrayIndex p_Index) { ArrayIndex Block; ArrayIndex Element; QFreeSpaceEntry Result; if (p_Index >= m_FreeSpaceListCount) { Result.m_ObjectNumber = 0; Result.m_FreeSpaceCode = 0; return Result; } Block = p_Index / FreeSpaceEntriesPerBlock; Element = p_Index % FreeSpaceEntriesPerBlock; Result = m_BlockPtr[Block]->Get(Element); return Result; } void FreeSpaceArrayPtr::FreeSpaceArray::Set(ArrayIndex p_Index, QFreeSpaceEntry p_Entry) { ArrayIndex Block; ArrayIndex Element; if (p_Index >= m_FreeSpaceListCount) return; // can't store off the end Block = p_Index / FreeSpaceEntriesPerBlock; Element = p_Index % FreeSpaceEntriesPerBlock; m_BlockPtr[Block]->Set(Element, p_Entry); if ((p_Entry.m_FreeSpaceCode == AvailableQuantum) && (p_Index < m_CurrentLowestFreeBlock)) m_CurrentLowestFreeBlock = p_Index; return; } QuantumNumber FreeSpaceArrayPtr::FreeSpaceArray::FindEmptyBlock() { ArrayIndex Block; ArrayIndex Element; ArrayIndex Result = BadArrayIndex; Block = m_CurrentLowestFreeBlock / FreeSpaceEntriesPerBlock; Element = m_CurrentLowestFreeBlock % FreeSpaceEntriesPerBlock; for (; Block < m_FreeSpaceListBlockCount; Block ++) { for (; Element < FreeSpaceEntriesPerBlock; Element ++) { if (m_BlockPtr[Block]->Get(Element).m_FreeSpaceCode == AvailableQuantum) { Result = Block * FreeSpaceEntriesPerBlock + Element; break; } } if (Result != BadArrayIndex) break; Element = 0; } m_CurrentLowestFreeBlock = Result; return Result; } QuantumNumber FreeSpaceArrayPtr::FreeSpaceArray::FindSpaceForItem( ObjectNumber p_ObjectNumber, ArrayIndex p_ItemSize) { ArrayIndex Block; ArrayIndex Element; ArrayIndex Result = BadArrayIndex; ArrayIndex ItemSizeCode = p_ItemSize / FreeSpaceConversion; QFreeSpaceEntry TempFreeSpaceEntry; LeafBlockPtr TempLeafBlockPtr; for (Block = 0; Block < m_FreeSpaceListBlockCount; Block ++) { for (Element = 0; Element < FreeSpaceEntriesPerBlock; Element ++) { TempFreeSpaceEntry = m_BlockPtr[Block]->Get(Element); if (TempFreeSpaceEntry.m_FreeSpaceCode == AvailableQuantum) { TempFreeSpaceEntry.m_ObjectNumber = p_ObjectNumber; m_BlockPtr[Block]->Set(Element,TempFreeSpaceEntry); Result = Block * FreeSpaceEntriesPerBlock + Element; TempLeafBlockPtr = m_BlockPtr[Block]->MakeLeafBlockPtr(Result); TempLeafBlockPtr->Clear(); TempLeafBlockPtr->SetQuantumType(LEAF_NODE); TempLeafBlockPtr->SetMainObjectNumber(p_ObjectNumber); break; } if (TempFreeSpaceEntry.m_ObjectNumber == p_ObjectNumber && TempFreeSpaceEntry.m_FreeSpaceCode > ItemSizeCode) { Result = Block * FreeSpaceEntriesPerBlock + Element; TempLeafBlockPtr = m_BlockPtr[Block]->MakeLeafBlockPtr(Result); if (TempLeafBlockPtr->CalculateFreeSpace() > p_ItemSize) break; else Result = BadArrayIndex; } } if (Result != BadArrayIndex) break; } return Result; } MainObjectArrayPtr::MainObjectArrayPtr() { m_MOA = new MainObjectArray; m_MOA->m_ReferenceCount = 1; } MainObjectArrayPtr::MainObjectArrayPtr(QuantumFile *p_QuantumFile) { m_MOA = new MainObjectArray(p_QuantumFile); m_MOA->m_ReferenceCount = 1; } MainObjectArrayPtr::MainObjectArrayPtr(const MainObjectArrayPtr& p_MOAP) { m_MOA = p_MOAP.m_MOA; m_MOA->m_ReferenceCount++; } MainObjectArrayPtr::MainObjectArray *MainObjectArrayPtr::operator->() { return m_MOA; } MainObjectArrayPtr& MainObjectArrayPtr::operator=(const MainObjectArrayPtr& p_MOAP) { m_MOA->m_ReferenceCount--; if (m_MOA->m_ReferenceCount <= 0 && m_MOA != p_MOAP.m_MOA) delete m_MOA; m_MOA = p_MOAP.m_MOA; m_MOA->m_ReferenceCount ++; return *this; } MainObjectArrayPtr::~MainObjectArrayPtr() { m_MOA->m_ReferenceCount --; if (m_MOA->m_ReferenceCount <= 0) delete m_MOA; } MainObjectArrayPtr::MainObjectArray::MainObjectArray(): m_QuantumFile(0), m_BlockPtr(ArrayIndex(0)), m_MainObjectCount(0), m_MainObjectBlockCount(0), m_CurrentLowestFreeObject(0) { } MainObjectArrayPtr::MainObjectArray::~MainObjectArray() { } MainObjectArrayPtr::MainObjectArray::MainObjectArray(QuantumFile *p_MRU) { ArrayIndex i; if (p_MRU) { m_QuantumFile = p_MRU; m_MainObjectCount = p_MRU->GetMainObjectCount(); m_MainObjectBlockCount = p_MRU->GetMainObjectBlockCount(); m_CurrentLowestFreeObject = 0; m_BlockPtr.SetSize(m_MainObjectCount); for (i = 0; i < m_BlockPtr.GetSize(); i ++) m_BlockPtr[i] = p_MRU->MakeMainObjectBlockPtr(i); } } MainObjectEntry MainObjectArrayPtr::MainObjectArray::Get(ArrayIndex p_Index) { ArrayIndex Block; ArrayIndex Element; MainObjectEntry Result; if (p_Index >= m_MainObjectCount) return(NoObject); // say there's no space here Block = p_Index / MainObjectEntriesPerBlock; Element = p_Index % MainObjectEntriesPerBlock; Result = m_BlockPtr[Block]->Get(Element); return Result; } void MainObjectArrayPtr::MainObjectArray::Set(ArrayIndex p_Index, MainObjectEntry p_Entry) { ArrayIndex Block; ArrayIndex Element; if (p_Index >= m_MainObjectCount) return; // can't store off the end Block = p_Index / MainObjectEntriesPerBlock; Element = p_Index % MainObjectEntriesPerBlock; m_BlockPtr[Block]->Set(Element, p_Entry); if ((p_Entry == NoObject) && (p_Index < m_CurrentLowestFreeObject)) m_CurrentLowestFreeObject = p_Index; return; } ObjectNumber MainObjectArrayPtr::MainObjectArray::FindObjectByName( ModifiableElement p_ObjectName) { ObjectNumber i; ModifiableElement TempElement; // note: there is no object numbered 0 for (i = 1; i < m_MainObjectCount; i ++) { TempElement = GetModifiableElement(MainObjectDirectory,i); if (p_ObjectName == TempElement) return i; } return NoObject; } void MainObjectArrayPtr::MainObjectArray::CreateMainObject( ModifiableElement p_ObjectName, ObjectNumber p_ObjectNumber, ArrayIndex p_ElementCount, ArrayIndex p_MaxElementCount) { QuantumNumber NewBigPointerQuantum; BigArrayHeader NewBigArrayHeader; SVector NewBigPointerArray; SVector NewLittlePointerArray; ArrayIndex LittlePointerBlockCount; ArrayIndex i; ArrayIndex NewQuantum; QFreeSpaceEntry TempFreeSpaceEntry; if (p_ElementCount == 0) p_ElementCount = 1; // this is the simplest handling for 0-length arrays TempFreeSpaceEntry.m_ObjectNumber = p_ObjectNumber; TempFreeSpaceEntry.m_FreeSpaceCode = 0; NewBigPointerQuantum = m_QuantumFile->FindEmptyBlock(); BigPointerBlockPtr NewBigPointerBlock = m_QuantumFile->MakeBigPointerBlockPtr(NewBigPointerQuantum); NewBigPointerBlock->Clear(); NewBigPointerBlock->SetQuantumType(BIG_POINTER_ARRAY); NewBigPointerBlock->SetMainObjectNumber(p_ObjectNumber); NewBigArrayHeader.m_ElementCount = p_ElementCount; NewBigArrayHeader.m_MaxElementCount = p_MaxElementCount; NewBigArrayHeader.m_LastQuantumAddedTo = NoQuantum; NewBigPointerBlock->AddItem(&NewBigArrayHeader, sizeof(BigArrayHeader), BIG_ARRAY_HEADER, 0); LittlePointerBlockCount = (p_ElementCount-1)/ItemReferencesPerBlock + 1; NewBigPointerArray = SVector(LittlePointerBlockCount); NewLittlePointerArray = SVector(ItemReferencesPerBlock); for (i = 0; i < LittlePointerBlockCount; i ++) { NewQuantum = m_QuantumFile->FindEmptyBlock(); m_QuantumFile->SetFreeSpace(NewQuantum,TempFreeSpaceEntry); NewBigPointerArray[i] = NewQuantum; LittlePointerBlockPtr NewLittlePointerBlock = m_QuantumFile->MakeLittlePointerBlockPtr(NewQuantum); NewLittlePointerBlock->Clear(); NewLittlePointerBlock->SetQuantumType(LITTLE_POINTER_ARRAY); NewLittlePointerBlock->SetMainObjectNumber(p_ObjectNumber); NewLittlePointerBlock->AddItem(NewLittlePointerArray.GetDataAddress(), NewLittlePointerArray.GetSize()*sizeof(ItemReference), LITTLE_POINTER_ARRAY,0); NewLittlePointerBlock->ClearLittleArray(); m_QuantumFile->SetFreeSpace(NewQuantum,TempFreeSpaceEntry); } NewBigPointerBlock->AddItem(NewBigPointerArray.GetDataAddress(), NewBigPointerArray.GetSize()*sizeof(QuantumNumber), BIG_POINTER_ARRAY,0); m_QuantumFile->SetFreeSpace(NewBigPointerQuantum,TempFreeSpaceEntry); Set(p_ObjectNumber,NewBigPointerQuantum); PutElement(MainObjectDirectory, p_ObjectNumber, p_ObjectName); } ArrayIndex MainObjectArrayPtr::MainObjectArray::GrowMainObject( ObjectNumber p_ObjectNumber, ArrayIndex p_NewElementCount) { MainObjectEntry BPAQuantumNumber; BigPointerBlockPtr BigPointerBlock; LittlePointerBlockPtr NewLittlePointerBlock; SVector NewLittlePointerArray; BigPointerArray OldBigPointerArray; SVector NewBigPointerArray; ArrayIndex NewLittlePointerBlockCount; ArrayIndex OldLittlePointerBlockCount; ArrayIndex i; ArrayIndex NewQuantum; QFreeSpaceEntry TempFreeSpaceEntry; ArrayIndex UpdatedElementCount; BPAQuantumNumber = Get(p_ObjectNumber); BigPointerBlock = m_QuantumFile->MakeBigPointerBlockPtr(BPAQuantumNumber); OldBigPointerArray = BigPointerBlock->GetBigPointerArray(); // big pointer array NewBigPointerArray = OldBigPointerArray; NewLittlePointerBlockCount = (p_NewElementCount-1)/ItemReferencesPerBlock + 1; UpdatedElementCount = NewLittlePointerBlockCount * ItemReferencesPerBlock; OldLittlePointerBlockCount = NewBigPointerArray.GetSize(); if (NewLittlePointerBlockCount == OldLittlePointerBlockCount) // first overflow { BigPointerBlock->SetBigArrayElementCount(UpdatedElementCount); return UpdatedElementCount; } NewBigPointerArray.SetSize(NewLittlePointerBlockCount); BigPointerBlock->SetBigArrayElementCount(UpdatedElementCount); TempFreeSpaceEntry.m_ObjectNumber = p_ObjectNumber; TempFreeSpaceEntry.m_FreeSpaceCode = 0; NewLittlePointerArray = SVector(ItemReferencesPerBlock); for (i = OldLittlePointerBlockCount; i < NewLittlePointerBlockCount; i ++) { NewQuantum = m_QuantumFile->FindEmptyBlock(); m_QuantumFile->SetFreeSpace(NewQuantum,TempFreeSpaceEntry); NewBigPointerArray[i] = NewQuantum; NewLittlePointerBlock = m_QuantumFile->MakeLittlePointerBlockPtr(NewQuantum); NewLittlePointerBlock->Clear(); NewLittlePointerBlock->SetQuantumType(LITTLE_POINTER_ARRAY); NewLittlePointerBlock->SetMainObjectNumber(p_ObjectNumber); NewLittlePointerBlock->AddItem(NewLittlePointerArray.GetDataAddress(), NewLittlePointerArray.GetSize()*sizeof(ItemReference), LITTLE_POINTER_ARRAY,0); NewLittlePointerBlock->ClearLittleArray(); m_QuantumFile->SetFreeSpace(NewQuantum,TempFreeSpaceEntry); } BigPointerBlock->DeleteItem(2); // big pointer array BigPointerBlock->AddItem(NewBigPointerArray.GetDataAddress(), NewBigPointerArray.GetSize()*sizeof(QuantumNumber), BIG_POINTER_ARRAY,0); m_QuantumFile->SetFreeSpace(BPAQuantumNumber,TempFreeSpaceEntry); return UpdatedElementCount; } ObjectNumber MainObjectArrayPtr::MainObjectArray::FindAvailableObject() { ArrayIndex Block; ArrayIndex Element; ObjectNumber Result = NoObject; Block = m_CurrentLowestFreeObject / MainObjectEntriesPerBlock; Element = m_CurrentLowestFreeObject % MainObjectEntriesPerBlock; for (; Block < m_MainObjectBlockCount; Block ++) { for (; Element < MainObjectEntriesPerBlock; Element ++) { if (m_BlockPtr[Block]->Get(Element) == NoObject) { Result = (ObjectNumber) (Block * MainObjectEntriesPerBlock + Element); break; } } if (Result != NoObject) break; } m_CurrentLowestFreeObject = Result; return Result; } ModifiableElement MainObjectArrayPtr::MainObjectArray::GetModifiableElement( ArrayIndex p_MainObjectNumber, ArrayIndex p_ElementIndex) { MainObjectEntry BPAQuantumNumber; BigPointerBlockPtr BigPointerBlock; LittlePointerBlockPtr LittlePointerBlock; LeafBlockPtr ElementBlock; ArrayIndex BigPointerIndex; ArrayIndex LittlePointerIndex; QuantumNumber LPAQuantumNumber; ItemReference ElementRef; ModifiableElement Element; BPAQuantumNumber = Get(p_MainObjectNumber); BigPointerBlock = m_QuantumFile->MakeBigPointerBlockPtr(BPAQuantumNumber); BigPointerIndex = p_ElementIndex / ItemReferencesPerBlock; LPAQuantumNumber = BigPointerBlock->GetBigArrayElement(BigPointerIndex); LittlePointerBlock = m_QuantumFile->MakeLittlePointerBlockPtr(LPAQuantumNumber); LittlePointerIndex = p_ElementIndex % ItemReferencesPerBlock; ElementRef = LittlePointerBlock->GetLittleArrayElement(LittlePointerIndex); if (ElementRef.IsReference()) { ElementBlock = m_QuantumFile->MakeLeafBlockPtr(ElementRef.GetQuantumNumber()); Element = ElementBlock->GetModifiableItem(ElementRef.GetItemNumber()); } else Element = ModifiableElement(); return Element; } int MainObjectArrayPtr::MainObjectArray::PutElement( ObjectNumber p_MainObjectNumber, ArrayIndex p_ElementIndex, ModifiableElement p_Element) { MainObjectEntry BPAQuantumNumber; BigPointerBlockPtr BigPointerBlock; LittlePointerBlockPtr LittlePointerBlock; LeafBlockPtr ElementBlock; ArrayIndex BigPointerIndex; ArrayIndex LittlePointerIndex; QuantumNumber LPAQuantumNumber; ItemReference ElementRef; ItemReference NewElementRef; ModifiableElement Element; QFreeSpaceEntry SpaceAvailable; QuantumNumber NewQuantum; QuantumNumber PossibleQuantum; LeafBlockPtr NewElementBlock; ArrayIndex FreeSpace; ArrayIndex ActualFreeSpace; ArrayIndex NewItemNumber; ObjectNumber LeafObjectNumber; qfassert (p_Element.GetSize() < MaxItemSize); BigPointerIndex = p_ElementIndex / ItemReferencesPerBlock; BPAQuantumNumber = Get(p_MainObjectNumber); BigPointerBlock = m_QuantumFile->MakeBigPointerBlockPtr(BPAQuantumNumber); LPAQuantumNumber = BigPointerBlock->GetBigArrayElement(BigPointerIndex); LittlePointerBlock = m_QuantumFile->MakeLittlePointerBlockPtr(LPAQuantumNumber); LittlePointerIndex = p_ElementIndex % ItemReferencesPerBlock; ElementRef = LittlePointerBlock->GetLittleArrayElement(LittlePointerIndex); if (ElementRef.IsReference()) { ElementBlock = m_QuantumFile->MakeLeafBlockPtr(ElementRef.GetQuantumNumber()); ElementBlock->DeleteItem(ElementRef.GetItemNumber()); } if (p_Element.GetSize() == 0) // nothing to store { ElementRef.SetQuantumNumber(NoQuantum); ElementRef.SetItemNumber(NoItem); LittlePointerBlock->SetLittleArrayElement(LittlePointerIndex,ElementRef); return 0; } NewQuantum = NoQuantum; PossibleQuantum = BigPointerBlock->GetLastQuantumAddedTo(); if (PossibleQuantum != NoQuantum) { SpaceAvailable = m_QuantumFile->QGetFreeSpace(PossibleQuantum); FreeSpace = SpaceAvailable.m_FreeSpaceCode * FreeSpaceConversion; if (SpaceAvailable.m_FreeSpaceCode != AvailableQuantum && FreeSpace > p_Element.GetSize()) { NewElementBlock = m_QuantumFile->MakeLeafBlockPtr(PossibleQuantum); ActualFreeSpace = NewElementBlock->CalculateFreeSpace(); if (ActualFreeSpace > p_Element.GetSize()) NewQuantum = PossibleQuantum; } } if (NewQuantum == NoQuantum) { NewQuantum = m_QuantumFile->FindSpaceForItem(p_MainObjectNumber, p_Element.GetSize()); NewElementBlock = m_QuantumFile->MakeLeafBlockPtr(NewQuantum); LeafObjectNumber = NewElementBlock->GetMainObjectNumber(); qfassert(LeafObjectNumber == p_MainObjectNumber); } BigPointerBlock->SetLastQuantumAddedTo(NewQuantum); NewElementRef.SetQuantumNumber(NewQuantum); NewItemNumber = NewElementBlock->AddItem(p_Element, VARIABLE_LENGTH_STRING, p_ElementIndex); NewElementRef.SetItemNumber(NewItemNumber); LeafObjectNumber = NewElementBlock->GetMainObjectNumber(); qfassert(LeafObjectNumber == p_MainObjectNumber); NewElementBlock->UpdateFreeSpace(); LittlePointerBlock->SetLittleArrayElement(LittlePointerIndex,NewElementRef); return 0; } ArrayIndex MainObjectArrayPtr::MainObjectArray::GetMainObjectElementCount( ArrayIndex p_MainObjectNumber) { MainObjectEntry BPAQuantumNumber; BigPointerBlockPtr BigPointerBlock; BPAQuantumNumber = Get(p_MainObjectNumber); BigPointerBlock = m_QuantumFile->MakeBigPointerBlockPtr(BPAQuantumNumber); return BigPointerBlock->GetBigArrayElementCount(); } ArrayIndex MainObjectArrayPtr::MainObjectArray::GetMainObjectMaxElementCount( ArrayIndex p_MainObjectNumber) { MainObjectEntry BPAQuantumNumber; BigPointerBlockPtr BigPointerBlock; BPAQuantumNumber = Get(p_MainObjectNumber); BigPointerBlock = m_QuantumFile->MakeBigPointerBlockPtr(BPAQuantumNumber); return BigPointerBlock->GetBigArrayMaxElementCount(); } FlexArray::FlexArray() { m_MOAIndex = 0; } FlexArray::FlexArray(MainObjectArrayPtr p_MOA, ObjectNumber p_MOAIndex) { m_MOA = p_MOA; m_MOAIndex = p_MOAIndex; m_ElementCount = m_MOA->GetMainObjectElementCount(m_MOAIndex); m_MaxElementCount = m_MOA->GetMainObjectMaxElementCount(m_MOAIndex); } FlexArray::FlexArray(QuantumFile *p_QF, ModifiableElement p_ArrayName, ArrayIndex p_ElementCount, ArrayIndex p_MaxElementCount) { Open(p_QF,p_ArrayName,p_ElementCount,p_MaxElementCount); } void FlexArray::Open(QuantumFile *p_QF, ModifiableElement p_ArrayName, ArrayIndex p_ElementCount, ArrayIndex p_MaxElementCount) { m_MOA = MainObjectArrayPtr(p_QF); m_MOAIndex = m_MOA->FindObjectByName(p_ArrayName); if (m_MOAIndex == NoObject) { m_MOAIndex = m_MOA->FindAvailableObject(); m_MOA->CreateMainObject(p_ArrayName,m_MOAIndex, p_ElementCount, p_MaxElementCount); } m_ElementCount = m_MOA->GetMainObjectElementCount(m_MOAIndex); m_MaxElementCount = m_MOA->GetMainObjectMaxElementCount(m_MOAIndex); } FlexArrayRef::FlexArrayRef(MainObjectArrayPtr &p_MOA, ObjectNumber p_MOAIndex, ArrayIndex p_ElementIndex) : m_MOA(p_MOA), m_MOAIndex(p_MOAIndex), m_ElementIndex(p_ElementIndex) { } FlexArrayRef& FlexArrayRef::operator=(ModifiableElement p_ROE) { m_MOA->PutElement(m_MOAIndex, m_ElementIndex, p_ROE); return *this; } FlexArrayRef::operator ModifiableElement() { return m_MOA->GetModifiableElement(m_MOAIndex, m_ElementIndex); } FlexArrayRef FlexArray::operator[](ArrayIndex p_ElementIndex) { qfassert(p_ElementIndex < m_MaxElementCount); if (p_ElementIndex >= m_ElementCount) m_ElementCount = m_MOA->GrowMainObject(m_MOAIndex,p_ElementIndex+1); return FlexArrayRef(m_MOA, m_MOAIndex, p_ElementIndex); } AccessVector MainObjectArrayPtr::MainObjectArray::GetAccessVectorUlong( ArrayIndex p_MainObjectNumber, ArrayIndex p_ElementIndex) { MainObjectEntry BPAQuantumNumber; BigPointerBlockPtr BigPointerBlock; LittlePointerBlockPtr LittlePointerBlock; LeafBlockPtr ElementBlock; ArrayIndex BigPointerIndex; ArrayIndex LittlePointerIndex; QuantumNumber LPAQuantumNumber; ItemReference ElementRef; AccessVector Result; BPAQuantumNumber = Get(p_MainObjectNumber); BigPointerBlock = m_QuantumFile->MakeBigPointerBlockPtr(BPAQuantumNumber); BigPointerIndex = p_ElementIndex / ItemReferencesPerBlock; LPAQuantumNumber = BigPointerBlock->GetBigArrayElement(BigPointerIndex); LittlePointerBlock = m_QuantumFile->MakeLittlePointerBlockPtr(LPAQuantumNumber); LittlePointerIndex = p_ElementIndex % ItemReferencesPerBlock; ElementRef = LittlePointerBlock->GetLittleArrayElement(LittlePointerIndex); if (ElementRef.IsReference()) { ElementBlock = m_QuantumFile->MakeLeafBlockPtr(ElementRef.GetQuantumNumber()); Result = ElementBlock->GetAccessVectorUlong(ElementRef.GetItemNumber()); } return Result; } void MainObjectArrayPtr::MainObjectArray::SetModified( ArrayIndex p_MainObjectNumber, ArrayIndex p_ElementIndex) { MainObjectEntry BPAQuantumNumber; BigPointerBlockPtr BigPointerBlock; LittlePointerBlockPtr LittlePointerBlock; LeafBlockPtr ElementBlock; ArrayIndex BigPointerIndex; ArrayIndex LittlePointerIndex; QuantumNumber LPAQuantumNumber; ItemReference ElementRef; ModifiableElement Element; QuantumNumber LeafBlockNumber; BPAQuantumNumber = Get(p_MainObjectNumber); BigPointerBlock = m_QuantumFile->MakeBigPointerBlockPtr(BPAQuantumNumber); BigPointerIndex = p_ElementIndex / ItemReferencesPerBlock; LPAQuantumNumber = BigPointerBlock->GetBigArrayElement(BigPointerIndex); LittlePointerBlock = m_QuantumFile->MakeLittlePointerBlockPtr(LPAQuantumNumber); LittlePointerIndex = p_ElementIndex % ItemReferencesPerBlock; ElementRef = LittlePointerBlock->GetLittleArrayElement(LittlePointerIndex); if (ElementRef.IsReference()) { ElementBlock = m_QuantumFile->MakeLeafBlockPtr(ElementRef.GetQuantumNumber()); LeafBlockNumber = ElementRef.GetQuantumNumber()- m_QuantumFile->GetQuantumNumberAdjustment(); m_QuantumFile->SetModified(LeafBlockNumber); } }