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