/////////////////////////////////////////////////////////// // Softwarebauelemente I, Aufgabe M6.5. // // author: Stephan Brumme // last changes: January 07, 2001 #include #include "MDate.h" #include "MRoom.h" #include "MHouseADT.h" using namespace MDate; // data struct THouseADTIntern for a single HouseADT // needed to hide the internal structure of the ADT typedef struct { TDate DateOfFoundation; Ordinal Count; Ordinal Cursor; MHouseADT::TArrayOfRooms PSet; } THouseADTIntern; // constructs a HouseADT void MHouseADT::NewHouseADT(UHouseADT* HouseADT) { *HouseADT = malloc(sizeof(THouseADTIntern)); Init(*HouseADT); } // destructs a HouseADT void MHouseADT::DeleteHouseADT(UHouseADT* HouseADT) { delete(*HouseADT); HouseADT = NULL; } // initializes the UHouseADT structure void MHouseADT::Init(UHouseADT HouseADT) { THouseADTIntern* house = (THouseADTIntern*) HouseADT; house->Count = 0; house->Cursor = -1; MDate::Today(house->DateOfFoundation); } // compares two exemplars // returns "true" if attributes of both are equal; "false" otherwise Boolean MHouseADT::EqualValue(UHouseADT HouseADT1, UHouseADT HouseADT2) { THouseADTIntern* house1 = (THouseADTIntern*) HouseADT1; THouseADTIntern* house2 = (THouseADTIntern*) HouseADT2; // verify number of rooms and date of foundation if (!(house1->Count == house2->Count && MDate::EqualValue(house1->DateOfFoundation, house2->DateOfFoundation))) return false; // dates and numbers of rooms are equal // now compare each room // !!! they must be in the same order, shuffled HouseADTs are NOT recognized !!! // are HouseADTs empty ? => they are equal if (house1->Count == 0) return true; // compare each room for (Ordinal nRun = 0; nRun < house1->Count; nRun++) if (!MRoom::EqualValue(house1->PSet[nRun], house2->PSet[nRun])) return false; // all rooms are equal, so the HouseADTs are equal return true; } // copies the attributes of HouseADT2 // returns "true" if successful, "false" if no memory allocated Boolean MHouseADT::Copy(UHouseADT HouseADT1, UHouseADT HouseADT2) { // are both HouseADTs equal ? if (EqualValue(HouseADT1, HouseADT2)) return false; THouseADTIntern* house1 = (THouseADTIntern*) HouseADT1; THouseADTIntern* house2 = (THouseADTIntern*) HouseADT2; // copy all attributes house1->Count = house2->Count; house1->Cursor = house2->Cursor; MDate::Copy(house1->DateOfFoundation, house2->DateOfFoundation); if (house2->Count > 0) for (Ordinal nRun = 0; nRun < house2->Count; nRun++) MRoom::Copy(house1->PSet[nRun], house2->PSet[nRun]); // successfully done return true; } // retrieve date of foundation TDate MHouseADT::GetDateOfFoundation(UHouseADT HouseADT) { TDate date; MDate::Copy(date, ((THouseADTIntern*)HouseADT)->DateOfFoundation); return date; } // get number of rooms Ordinal MHouseADT::Card(UHouseADT HouseADT) { return ((THouseADTIntern*)HouseADT)->Count; } // add a new room to a HouseADT Boolean MHouseADT::Insert(UHouseADT HouseADT, const MRoom::TRoom& room) { THouseADTIntern* house = (THouseADTIntern*) HouseADT; // is any free space available ? if (house->Count >= ROOMS) return false; // copy room, care for errors if (!MRoom::Copy(house->PSet[house->Count], room)) return false; // set cursor house->Cursor = house->Count; // increase size of array house->Count++; return true; } // returns the first room of a HouseADT Boolean MHouseADT::GetFirst(UHouseADT HouseADT, MRoom::TRoom& room) { THouseADTIntern* house = (THouseADTIntern*) HouseADT; // is HouseADT empty ? if (house->Count == 0) return false; // set cursor house->Cursor = 0; // and return room return GetCurrent(HouseADT, room); } // returns the last room of a HouseADT Boolean MHouseADT::GetNext(UHouseADT HouseADT, MRoom::TRoom& room) { THouseADTIntern* house = (THouseADTIntern*) HouseADT; // verify that current cursor position is valid // they must be a next room, otherwise function will fail if ((house->Cursor < 0) || (house->Cursor >= house->Count)) return false; // set cursor to next room house->Cursor++; return GetCurrent(HouseADT, room); } // looks for a given room and sets cursor, if possible Boolean MHouseADT::Find(UHouseADT HouseADT, const MRoom::TRoom& room) { THouseADTIntern* house = (THouseADTIntern*) HouseADT; // is HouseADT empty ? if (house->Count == 0) return false; for (Ordinal nRun=0; nRunCount; nRun++) if (MRoom::EqualValue(house->PSet[nRun], room)) { house->Cursor = nRun; return true; } // no room found, cursor remains unchanged return false; } // returns the room the cursors points to Boolean MHouseADT::GetCurrent(UHouseADT HouseADT, MRoom::TRoom& room) { THouseADTIntern* house = (THouseADTIntern*) HouseADT; // verify that room exists if ((house->Cursor < 0) || (house->Cursor >= house->Count)) return false; return MRoom::Copy(room, house->PSet[house->Cursor]); } // deletes the room the cursor points to Boolean MHouseADT::Scratch(UHouseADT HouseADT) { THouseADTIntern* house = (THouseADTIntern*) HouseADT; // is HouseADT empty and cursor valid ? if ((house->Count == 0) || (house->Cursor < 0) || (house->Cursor >= house->Count)) return false; // move all rooms beyond HouseADT.Cursor one position ahead for (Ordinal nRun = house->Cursor; nRun < house->Count; nRun++) // verify copy if (!MRoom::Copy(house->PSet[nRun], house->PSet[nRun+1])) return false; // reset Cursor and Count house->Cursor--; house->Count--; // we're done return true; } // displays the attributes void MHouseADT::Show(UHouseADT HouseADT) { THouseADTIntern* house = (THouseADTIntern*) HouseADT; using namespace std; // display general room info cout<<"Das Haus besteht aus "<Count<<" Zimmern."<Cursor<DateOfFoundation); cout<Count > 0) for (Ordinal nRun=0; nRunCount; nRun++) { cout<<"Raum "<PSet[nRun]); } else cout<<"Das Haus ist leer."<