#include "munga.h" #pragma hdrstop #include "namelist.h" //############################################################################# //############## ObjectNameList ######################################### //############################################################################# ObjectNameList::ObjectNameList() { Check_Pointer(this); firstEntry = lastEntry = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ObjectNameList::~ObjectNameList() { Check(this); Entry *next; while (firstEntry) { Check_Pointer(firstEntry); next = firstEntry->nextEntry; Unregister_Pointer(firstEntry); delete firstEntry; firstEntry = next; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // const char* ObjectNameList::AddEntry( const char *name, void *data ) { Check(this); Check_Pointer(name); Entry *entry; entry = (Entry *)new char[ sizeof(Entry) + strlen(name) + 1 ]; Register_Pointer(entry); entry->dataReference = data; entry->nextEntry = NULL; if (firstEntry) { Check_Pointer(lastEntry); lastEntry->nextEntry = entry; } else { firstEntry = entry; } lastEntry = entry; entry->SetName(name); return entry->GetName(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void* ObjectNameList::FindObject(const char *name) { Check(this); Check_Pointer(name); Entry *entry; for (entry = firstEntry; entry; entry = entry->nextEntry) { Check_Pointer(entry); if (!strcmp(entry->GetName(), name)) { break; } } return (entry)?entry->dataReference:NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ObjectNameList::DeleteEntry(const char *name) { Check(this); Check_Pointer(name); Entry *cur, *prev, *entry; //---------------------------------------------------- // ***** DANGEROUS!!! see notice in namelist.hh ***** //---------------------------------------------------- entry = (Entry *)(name - sizeof(Entry)); Check_Pointer(entry); prev = NULL; for (cur=firstEntry; cur && cur != entry; cur = cur->nextEntry) { Check_Pointer(cur); prev = cur; } Verify(cur == entry); if (!prev) { firstEntry = entry->nextEntry; } else { prev->nextEntry = entry->nextEntry; } if (entry == lastEntry) { lastEntry = prev; } Unregister_Pointer(entry); delete entry; return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int ObjectNameList::EntryCount() const { Check(this); Entry *entry = firstEntry; int count = 0; while (entry) { Check_Pointer(entry); count++; entry = entry->nextEntry; } return count; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int ObjectNameList::BuildSubList( const ObjectNameList &source_list, const char *prefix ) { Check(this); Check(&source_list); Check_Pointer(prefix); const int length = strlen(prefix); Entry *entry = source_list.firstEntry; const char *name; int count = 0; //------------------------------------------------------ // add entries to SubList whose name begins with prefix //------------------------------------------------------ while (entry) { Check_Pointer(entry); name = entry->GetName(); Check_Pointer(name); if (!strncmp(name, prefix, length)) { count++; AddEntry(name, entry->dataReference); } entry = entry->nextEntry; } //------------------------------------------- // return number of entries added to SubList //------------------------------------------- return count; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical ObjectNameList::TestInstance() const { // nothing to check return True; } //############################################################################# //############## ObjectNameList::Entry ################################## //############################################################################# void ObjectNameList::Entry::SetName(const char *name) { Check_Pointer(this); Check_Pointer(name); strcpy((char *)this + sizeof(ObjectNameList::Entry), name); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // #if defined(USE_SIGNATURE) int Is_Signature_Bad(const volatile ObjectNameList__Entry *) { return False; } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical ObjectNameList::Entry::IsName(const char *name) const { Check(this); //do not check name here if (name) { Check_Pointer(name); return strcmp(GetName(), name) == 0; } else { return GetName() == name; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical ObjectNameList::Entry::TestInstance() const { // nothing to check //do not check dataReference even if it is not NULL! return True; } //############################################################################# //############## NameList ############################################### //############################################################################# NameList::NameList() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // NameList::~NameList() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // const char* NameList::FindName(void *data) { Check(this); Entry *entry; for (entry = firstEntry; entry; entry = entry->nextEntry) { Check_Pointer(entry); if (entry->dataReference == data) { break; } } return (entry)?entry->GetName():NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // NameList::Entry* NameList::FindEntry(const char *name) { Check(this); Check_Pointer(name); Entry *entry; for (entry = firstEntry; entry; entry = entry->nextEntry) { Check_Pointer(entry); if (!strcmp(entry->GetName(), name)) { break; } } return entry; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // NameList::Entry *NameList::FindEntry(void *data) { Check(this); Entry *entry; for (entry = firstEntry; entry; entry = entry->nextEntry) { Check_Pointer(entry); if (entry->dataReference == data) { break; } } return entry; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NameList::DeleteEntry(const char *name) { Check(this); Check_Pointer(name); Entry *prev = NULL, *entry; for (entry = firstEntry; entry; entry = entry->nextEntry) { Check_Pointer(entry); if (!strcmp(entry->GetName(), name)) { break; } prev = entry; } if (entry) { if (!prev) { firstEntry = entry->nextEntry; } else { prev->nextEntry = entry->nextEntry; } if (entry == lastEntry) { lastEntry = prev; } Unregister_Pointer(entry); delete entry; } return; } //############################################################################# //############## AlphaNameList ########################################## //############################################################################# AlphaNameList::AlphaNameList() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // AlphaNameList::~AlphaNameList() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // const char* AlphaNameList::AddEntry( const char *name, void *data ) { Check(this); Check_Pointer(name); Entry *entry, *next = firstEntry, *prev = NULL; entry = (Entry *)new char[ sizeof(Entry) + strlen(name) + 1 ]; Verify(entry); Register_Pointer(entry); //----------------------------------- // find location to insert new entry //----------------------------------- while (next) { Check_Pointer(next); if (strcmp(name, next->GetName()) < 0) { break; } prev = next; next = next->nextEntry; } //--------------------------------------------- // insert new entry after prev and before next //--------------------------------------------- if (!next) { lastEntry = entry; } if (!prev) { firstEntry = entry; } else { prev->nextEntry = entry; } entry->dataReference = data; entry->nextEntry = next; entry->SetName(name); return entry->GetName(); } #if defined(TEST_CLASS) #include "namelist.tcp" #endif