#pragma once #include "Stuff.hpp" namespace Stuff { ////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// // **************************** DATABASE API **************************** // ////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// class Record; class RecordHandle; class Database; class DatabaseHandle; class RecordHandle { public: DatabaseHandle *m_databaseHandle; WORD m_ID; const char *m_name; __int64 m_timeStamp; DWORD m_length; const void *m_data; const Record *m_record; #if defined(_ARMOR) RecordHandle(); ~RecordHandle(); #endif // // Add - Adds a record to the database and returns a unique ID that can be used to access the record. // The record can be found by the RecordID returned or the RecordName // The info fields will be changed to point at the database's copy of the field // void Add(); // // Replace - Overwrites a record based on the RecordID passed. // The record can be found by the RecordID returned or the RecordName // The info fields will be changed to point at the database's copy of the field // void Replace(); // // Delete - Removes the record with the given RecordID. // void Delete(); // // FindID - Returns a pointer to the Data contained in the record with the ID specified, also fills in a pointer to the original name. // True is returned if a record is found // bool FindID(bool load); // // FindName - Returns a pointer to the Data contained in the record with the Name specified, also fills in a pointer to the record ID number. // True is returned if a record is found // The info fields will be changed to point at the database's copy of the field // bool FindName(bool load); // // This function must be called before the data will be loaded (note that data is automatically loaded if loaded by ID rather than name) // void LoadData(); // // This function will unload any loaded data for the record // void UnloadData(); DWORD GetRealRecordSize(); // // This function will unload any loaded data for the record BUT IT WILL NOT DELETE THE ACTUAL DATA ITSELF!!!! // void AbandonData(); int GetDiskOffset(); // // Return the current record information and moves the current record to the next record. // If there is a current record, True will be returned. // void First(); bool ReadAndNext(); void TestInstance() const; }; class DatabaseHandle { friend class Database; friend class Record; friend class RecordHandle; public: Database *m_dataBase; DatabaseHandle( const char* filename, bool read_only, DWORD content_version ); DatabaseHandle( const char* filename, MemoryStream *stream, DWORD content_version ); ~DatabaseHandle(); void Save(); void ScatterSave(); void SaveAs(const char* filename); void Save(BYTE* buffer, DWORD length); void SpewLoadedRecords(); void UnloadRecords(); // // GetNumberOfRecords - Returns the number of records in the database // WORD GetNumberOfRecords(); void TestInstance() const; // it does not store the crc on purpose // that way a hacker can't find the number easily... __int64 CalculateCRC(int key); __int64 CalculateDateCRC(); MString GetFileName() {return m_fileName;} HGOSFILE GetFileHandle() {return m_fileHandle;} DWORD GetFileLength() {return m_fileLength;} protected: __int64 m_currentCRC; MString m_fileName; HGOSFILE m_fileHandle; BYTE *m_fileAddress; DWORD m_fileLength; DWORD m_MMHandle; DWORD m_contentVersion; HGOSHEAP m_heap; bool m_dirtyFlag, m_readOnly; }; extern HGOSHEAP g_DatabaseHeap; }