/*TITLE declarations for block classes*/ /****keyword-flag*** "%v %f %n" */ /* "6 6-May-98,18:08:18 BLOCKI.H" */ #ifndef BLOCKI_H #define BLOCKI_H enum ObjectType {UNUSED_ITEM=1,VARIABLE_LENGTH_STRING,LITTLE_POINTER_ARRAY, BIG_POINTER_ARRAY,LEAF_NODE,BIG_ARRAY_HEADER}; /* Critical consts that affect the capacity of the quantum file */ #ifdef SMALL_Q const ArrayIndex BlockSize = 1024; // size of each quantum const ArrayIndex MaxFileQuantumCount = 512; // max number of quanta in a file #else const ArrayIndex BlockSize = 16384; // size of each quantum const ArrayIndex MaxFileQuantumCount = 10000; // max number of quanta in a file #endif /* Critical consts that affect the capacity of the quantum file */ const RelativeItemNumber NoItem = 4095; // must be fewer elements than this in each quantum const ArrayIndex FreeSpaceConversion = BlockSize/256; // granularity of free space const ArrayIndex Margin = 5*FreeSpaceConversion; const FreeSpaceCode AvailableQuantum = 0xff; const MainObjectEntry NoObject = 0; const QuantumNumber NoQuantum = UINT_MAX-1; const ObjectNumber MainObjectIndexCount = 255; const ArrayIndex BadArrayIndex = (ArrayIndex)-1; const ObjectNumber MainNameObject = 1; struct QFreeSpaceEntry { FreeSpaceCode m_FreeSpaceCode; ObjectNumber m_ObjectNumber; }; const ArrayIndex FreeSpaceEntriesPerBlock = BlockSize/sizeof(QFreeSpaceEntry); const ArrayIndex MainObjectEntriesPerBlock = BlockSize/sizeof(MainObjectEntry); struct ItemIndex { unsigned m_Index:32; // must be size of ArrayIndex // Note: must consider changing the next two items if increasing block size unsigned m_Offset:16; unsigned m_Type:16; }; class ItemReference { protected: // The size of the m_QuantumNumber field limits the number // of quanta that can exist in one file. If we don't want // to increase the size of an ItemReference object, then // we can't increase this number without simultaneously // lowering the number of items in a block. unsigned m_QuantumNumber:20; unsigned m_RelativeItemNumber:12; public: int IsReference() { return m_RelativeItemNumber != NoItem; } int GetItemNumber() {return m_RelativeItemNumber;} int GetQuantumNumber() {return m_QuantumNumber;} void SetItemNumber(ArrayIndex p_ItemNumber) { m_RelativeItemNumber = p_ItemNumber; } void SetQuantumNumber(QuantumNumber p_QuantumNumber) { m_QuantumNumber = p_QuantumNumber; } }; typedef AccessVector LittlePointerArray; struct QuantumFileHeaderStruct { char quantum_version_info[64]; FILE *dos_file_ptr; char *file_name; ObjectNumber main_object_index_count; ArrayIndex free_space_list_count; ArrayIndex memory_resident_quantum_count; int filler0; void *filler1; void *filler2; void *filler3; void *filler4; void *filler5; void *filler6; void *filler7; FileOffset main_object_index_offset; FileOffset free_space_list_offset; FileOffset starting_quantum_offset; }; struct BigArrayHeader { ArrayIndex m_ElementCount; ArrayIndex m_MaxElementCount; QuantumNumber m_LastQuantumAddedTo; }; const unsigned BadBlockNumber = ArrayIndex(-1); struct QuantumBlockHeader { ObjectType m_QuantumType; ObjectNumber m_MainObjectNumber; ArrayIndex m_ItemCount; }; const ArrayIndex ItemReferencesPerBlock = (BlockSize - (sizeof(QuantumBlockHeader) + 8*FreeSpaceConversion)) / sizeof(ItemReference); const ArrayIndex MaxItemSize = BlockSize - (sizeof(QuantumBlockHeader) + Margin); struct QuantumBlockStruct { QuantumBlockHeader m_QuantumBlockHeader; ItemIndex m_ItemIndex[1]; // place holder for item index array }; union Block { char m_Data[BlockSize]; char m_QuantumVersionInfo[64]; QFreeSpaceEntry m_FreeSpaceData[FreeSpaceEntriesPerBlock]; MainObjectEntry m_MainObjectData[MainObjectEntriesPerBlock]; QuantumBlockStruct m_QuantumBlockData; }; class BaseBlockPtr { protected: Block *m_Block; ArrayIndex m_BlockNumber; QuantumFile *m_BlockManager; BaseBlockPtr(); }; class FreeSpaceBlockPtr { class FreeSpaceBlock : public BaseBlockPtr { friend FreeSpaceBlockPtr; public: FreeSpaceBlock(); FreeSpaceBlock(ArrayIndex p_BlockNumber, QuantumFile *p_BlockManager); QFreeSpaceEntry Get(ArrayIndex p_Index); void Set(ArrayIndex p_Index, QFreeSpaceEntry p_Value); LeafBlockPtr MakeLeafBlockPtr(ArrayIndex p_Index); }; protected: FreeSpaceBlock m_FreeSpaceBlock; public: FreeSpaceBlockPtr(); FreeSpaceBlockPtr(ArrayIndex p_BlockNumber, QuantumFile *p_BlockManager); FreeSpaceBlock *operator->(); }; class MainObjectBlockPtr { class MainObjectBlock : public BaseBlockPtr { friend MainObjectBlockPtr; public: MainObjectBlock(); MainObjectBlock(ArrayIndex p_BlockNumber, QuantumFile *p_BlockManager); MainObjectEntry Get(ArrayIndex p_Index); void Set(ArrayIndex p_Index, MainObjectEntry p_Value); }; protected: MainObjectBlock m_MainObjectBlock; public: MainObjectBlockPtr(); MainObjectBlockPtr(ArrayIndex p_BlockNumber, QuantumFile *p_BlockManager); MainObjectBlock *operator->(); }; class QuantumBlock : public BaseBlockPtr { protected: ItemIndex *m_ItemIndex; public: void SetItemCount(ArrayIndex p_NewItemCount); void SetQuantumType(ObjectType p_QuantumType); ObjectType GetQuantumType(); void SetMainObjectNumber(ObjectNumber p_MainObjectNumber); ObjectNumber GetMainObjectNumber(); ArrayIndex GetItemCount(); ModifiableElement GetModifiableItem(ArrayIndex p_ItemNumber); ItemIndex GetItemIndexEntry(ArrayIndex p_ItemNumber); AccessVector GetAccessVectorUlong(ArrayIndex p_ItemNumber); void DeleteItem(ArrayIndex p_ItemNumber); ArrayIndex AddItem(ModifiableElement p_Element, ObjectType p_Type, ArrayIndex p_Index); ArrayIndex AddItem(void *p_Element, ArrayIndex p_ElementSize, ObjectType p_Type, ArrayIndex p_Index); void UpdateFreeSpace(); ArrayIndex CalculateFreeSpace(); void SetModified(); void Clear(); void DumpQuantumBlock(); // for debugging bool CheckQuantumBlock(); // for debugging }; class BigPointerBlock : public QuantumBlock { friend BigPointerBlockPtr; protected: BigArrayHeader *m_BigArrayHeader; BigPointerArray m_BigPointerArray; public: BigPointerArray &GetBigPointerArray(){return m_BigPointerArray;}; void SetBigArrayHeader(); void SetBigPointerArray(); ArrayIndex GetBigArrayElementCount(); void SetBigArrayElementCount(ArrayIndex p_ElementCount); ArrayIndex GetBigArrayMaxElementCount(); QuantumNumber GetBigArrayElement(ArrayIndex p_Index); void SetBigArrayElement(ArrayIndex p_Index, QuantumNumber p_Element); QuantumNumber GetLastQuantumAddedTo(); void SetLastQuantumAddedTo(QuantumNumber p_QuantumNumber); void DumpQuantumBlock(); }; class LittlePointerBlock : public QuantumBlock { friend LittlePointerBlockPtr; protected: LittlePointerArray m_LittlePointerArray; public: void SetLittlePointerArray(); void ClearLittleArray(); ItemReference GetLittleArrayElement(ArrayIndex p_Index); void SetLittleArrayElement(ArrayIndex p_Index, ItemReference p_ItemReference); ArrayIndex GetLittleArraySize(); }; class LeafBlock : public QuantumBlock { friend LeafBlockPtr; }; class BigPointerBlockPtr { protected: BigPointerBlock m_BigPointerBlock; public: BigPointerBlockPtr(ArrayIndex p_BlockNumber, QuantumFile *p_BlockManager); BigPointerBlockPtr(); BigPointerBlock *operator->(); }; class LittlePointerBlockPtr { protected: LittlePointerBlock m_LittlePointerBlock; public: LittlePointerBlockPtr(ArrayIndex p_BlockNumber, QuantumFile *p_BlockManager); LittlePointerBlockPtr(); LittlePointerBlock *operator->(); }; class LeafBlockPtr { protected: LeafBlock m_LeafBlock; public: LeafBlockPtr(ArrayIndex p_BlockNumber, QuantumFile *p_BlockManager); LeafBlockPtr(); LeafBlock *operator->(); }; #endif