sources:
M06_5.cpp (808 bytes)
MDate.cpp (1.8k)
MDate.h (956 bytes)
MHouseADT.cpp (6.3k)
MHouseADT.h (2.0k)
MRoom.cpp (1.5k)
MRoom.h (1.1k)
PrimitiveTypes.h (421 bytes)


website:
more info here
studies/bauelemente/Softwarebauelemente-CodeM6-5/MHouseADT.cpp
download file

  1 ///////////////////////////////////////////////////////////
  2 // Softwarebauelemente I, Aufgabe M6.5.
  3 //
  4 // author: Stephan Brumme
  5 // last changes: January 07, 2001
  6
  7
  8 #include <iostream>
  9 #include "MDate.h"
 10 #include "MRoom.h"
 11 #include "MHouseADT.h"
 12
 13
 14 using namespace MDate;
 15
 16
 17 // data struct THouseADTIntern for a single HouseADT
 18 // needed to hide the internal structure of the ADT
 19 typedef struct
 20 {
 21     TDate   DateOfFoundation;
 22     Ordinal Count;
 23     Ordinal Cursor;
 24     MHouseADT::TArrayOfRooms PSet;
 25 } THouseADTIntern;
 26
 27
 28 // constructs a HouseADT
 29 void MHouseADT::NewHouseADT(UHouseADT* HouseADT)
 30 {
 31     *HouseADT = malloc(sizeof(THouseADTIntern));
 32     Init(*HouseADT);
 33 }
 34
 35
 36 // destructs a HouseADT
 37 void MHouseADT::DeleteHouseADT(UHouseADT* HouseADT)
 38 {
 39     delete(*HouseADT);
 40     HouseADT = NULL;
 41 }
 42
 43
 44 // initializes the UHouseADT structure
 45 void MHouseADT::Init(UHouseADT HouseADT)
 46 {
 47     THouseADTIntern* house = (THouseADTIntern*) HouseADT;
 48
 49     house->Count  = 0;
 50     house->Cursor = -1;
 51     MDate::Today(house->DateOfFoundation);
 52 }
 53
 54
 55 // compares two exemplars
 56 // returns "true" if attributes of both are equal; "false" otherwise
 57 Boolean MHouseADT::EqualValue(UHouseADT HouseADT1, UHouseADT HouseADT2)
 58 {
 59     THouseADTIntern* house1 = (THouseADTIntern*) HouseADT1;
 60     THouseADTIntern* house2 = (THouseADTIntern*) HouseADT2;
 61
 62     // verify number of rooms and date of foundation
 63     if (!(house1->Count == house2->Count &&
 64         MDate::EqualValue(house1->DateOfFoundation, house2->DateOfFoundation))
)

 65         return false;
 66
 67     // dates and numbers of rooms are equal
 68     // now compare each room
 69     // !!! they must be in the same order, shuffled HouseADTs are NOT recognized !!!
 70
 71     // are HouseADTs empty ? => they are equal
 72     if (house1->Count == 0)
 73         return true;
 74
 75     // compare each room
 76     for (Ordinal nRun = 0; nRun < house1->Count; nRun++)
 77         if (!MRoom::EqualValue(house1->PSet[nRun], house2->PSet[nRun]))
 78             return false;
 79
 80     // all rooms are equal, so the HouseADTs are equal
 81     return true;
 82 }
 83
 84
 85 // copies the attributes of HouseADT2
 86 // returns "true" if successful, "false" if no memory allocated
 87 Boolean MHouseADT::Copy(UHouseADT HouseADT1, UHouseADT HouseADT2)
 88 {
 89     // are both HouseADTs equal ?
 90     if (EqualValue(HouseADT1, HouseADT2))
 91         return false;
 92
 93     THouseADTIntern* house1 = (THouseADTIntern*) HouseADT1;
 94     THouseADTIntern* house2 = (THouseADTIntern*) HouseADT2;
 95
 96     // copy all attributes
 97     house1->Count  = house2->Count;
 98     house1->Cursor = house2->Cursor;
 99     MDate::Copy(house1->DateOfFoundation, house2->DateOfFoundation);
100
101     if (house2->Count > 0)
102         for (Ordinal nRun = 0; nRun < house2->Count; nRun++)
103             MRoom::Copy(house1->PSet[nRun], house2->PSet[nRun]);
104
105     // successfully done
106     return true;
107 }
108
109
110 // retrieve date of foundation
111 TDate MHouseADT::GetDateOfFoundation(UHouseADT HouseADT)
112 {
113     TDate date;
114     MDate::Copy(date, ((THouseADTIntern*)HouseADT)->DateOfFoundation);
115
116     return date;
117 }
118
119
120 // get number of rooms
121 Ordinal MHouseADT::Card(UHouseADT HouseADT)
122 {
123     return ((THouseADTIntern*)HouseADT)->Count;
124 }
125
126
127 // add a new room to a HouseADT
128 Boolean MHouseADT::Insert(UHouseADT HouseADT, const MRoom::TRoom& room)
129 {
130     THouseADTIntern* house = (THouseADTIntern*) HouseADT;
131
132     // is any free space available ?
133     if (house->Count >= ROOMS)
134         return false;
135
136     // copy room, care for errors
137     if (!MRoom::Copy(house->PSet[house->Count], room))
138         return false;
139
140     // set cursor
141     house->Cursor = house->Count;
142     // increase size of array
143     house->Count++;
144
145     return true;
146 }
147
148
149 // returns the first room of a HouseADT
150 Boolean MHouseADT::GetFirst(UHouseADT HouseADT, MRoom::TRoom& room)
151 {
152     THouseADTIntern* house = (THouseADTIntern*) HouseADT;
153
154     // is HouseADT empty ?
155     if (house->Count == 0)
156         return false;
157
158     // set cursor
159     house->Cursor = 0;
160
161     // and return room
162     return GetCurrent(HouseADT, room);
163 }
164
165
166 // returns the last room of a HouseADT
167 Boolean MHouseADT::GetNext(UHouseADT HouseADT, MRoom::TRoom& room)
168 {
169     THouseADTIntern* house = (THouseADTIntern*) HouseADT;
170
171     // verify that current cursor position is valid
172     // they must be a next room, otherwise function will fail
173     if ((house->Cursor < 0) ||
174         (house->Cursor >= house->Count))

175         return false;
176
177     // set cursor to next room
178     house->Cursor++;
179        
180     return GetCurrent(HouseADT, room);
181 }
182
183
184 // looks for a given room and sets cursor, if possible
185 Boolean MHouseADT::Find(UHouseADT HouseADT, const MRoom::TRoom& room)
186 {
187     THouseADTIntern* house = (THouseADTIntern*) HouseADT;
188
189     // is HouseADT empty ?
190     if (house->Count == 0)
191         return false;
192
193     for (Ordinal nRun=0; nRun<house->Count; nRun++)
194         if (MRoom::EqualValue(house->PSet[nRun], room))
195         {
196             house->Cursor = nRun;
197             return true;
198         }
199
200     // no room found, cursor remains unchanged
201     return false;
202 }
203
204
205 // returns the room the cursors points to
206 Boolean MHouseADT::GetCurrent(UHouseADT HouseADT, MRoom::TRoom& room)
207 {
208     THouseADTIntern* house = (THouseADTIntern*) HouseADT;
209
210     // verify that room exists
211     if ((house->Cursor < 0) ||
212         (house->Cursor >= house->Count))

213         return false;
214
215     return MRoom::Copy(room, house->PSet[house->Cursor]);
216 }
217
218
219 // deletes the room the cursor points to
220 Boolean MHouseADT::Scratch(UHouseADT HouseADT)
221 {
222     THouseADTIntern* house = (THouseADTIntern*) HouseADT;
223
224     // is HouseADT empty and cursor valid ?
225     if ((house->Count == 0) ||
226         (house->Cursor < 0) ||
227         (house->Cursor >= house->Count))

228         return false;
229
230     // move all rooms beyond HouseADT.Cursor one position ahead
231     for (Ordinal nRun = house->Cursor; nRun < house->Count; nRun++)
232         // verify copy
233         if (!MRoom::Copy(house->PSet[nRun], house->PSet[nRun+1]))
234             return false;
235    
236     // reset Cursor and Count
237     house->Cursor--;
238     house->Count--;
239
240     // we're done
241     return true;
242 }
243
244
245 // displays the attributes
246 void MHouseADT::Show(UHouseADT HouseADT)
247 {
248     THouseADTIntern* house = (THouseADTIntern*) HouseADT;
249
250     using namespace std;
251
252     // display general room info
253     cout<<"Das Haus besteht aus "<<house->Count<<" Zimmern."<<endl;
254     cout<<"Das aktuelle Zimmer ist "<<house->Cursor<<endl;
255
256     // foundation date
257     cout<<"Das Haus wurde gebaut am ";
258     MDate::Show(house->DateOfFoundation);
259     cout<<endl;
260    
261     // display each room
262     if (house->Count > 0)
263         for (Ordinal nRun=0; nRun<house->Count; nRun++)
264         {
265             cout<<"Raum "<<nRun<<": ";
266             MRoom::Show(house->PSet[nRun]);
267         }
268     else         cout<<"Das Haus ist leer."<<endl;
269 }
270
271