-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathutils.cpp
197 lines (175 loc) · 5.09 KB
/
utils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*
* utils.cpp
*
* Baker, Ballard, Jager-Kujawa
* CSC 341.001
* Spring 2016
*/
#include "utils.hpp"
// Case-insensitive string comparison
bool my_strcasecmp(string str1, string str2) {
int length1 = str1.length();
for (int i = 0; i < length1; i++) {
char &c = str1.at(i);
c = tolower(c);
}
int length2 = str2.length();
for (int i = 0; i < length2; i++) {
char &c = str2.at(i);
c = tolower(c);
}
return ((str1 == str2) ? true : false);
}
// Convert int to string
string itos(int i) {
stringstream ss;
ss << i;
return ss.str();
}
// Constructor; takes a FrameTable by reference
PageTable::PageTable(FrameTable& F) : _framesInUse(F) {
// Initialize page table with -1 (i.e. no associated frame)
for (int i = 0; i < NUM_FRAMES; i++) {
_pageTable[i] = -1;
}
}
/*
Subscript operator overload
If the specified page number (index) has an allocated frame,
return that frame number. Otherwise, randomly search for an unallocated
frame, assign said free frame to the specified page number entry,
and set the FrameTable entry to indicate the frame is now allocated.
*/
int& PageTable::operator[] (const int index) {
// If index out of bounds, throw an exception
if (index > 63 || index < 0) {
stringstream ss;
ss << index;
string strIndex = ss.str();
throw out_of_range("PageTable index " + strIndex +
" is invalid! Index must be 0-63!\n");
}
// If page table contains no frame for specified page
if (_pageTable[index] < 0) {
#ifdef DEBUG_VERBOSE
cout << "Page #" << index << " has no associated frame." << endl;
cout << "Searching for next available frame:" << endl;
#endif
// If no more available frames to allocate, throw an exception
if (find(ary::begin(_framesInUse), ary::end(_framesInUse), false)
== ary::end(_framesInUse)) {
throw out_of_range("No more available frames!");
}
// Seed random number generator
srand(time(NULL));
// Find the next available frame number
int i = rand() % 64;
while (_framesInUse[i] == true) {
#ifdef DEBUG_VERBOSE
cout << "\tFrame #" << i << " is in use..." << endl;
#endif
i = rand() % 64;
}
#ifdef DEBUG_VERBOSE
cout << "Frame #" << i << " is available!" << endl;
#endif
_framesInUse[i] = true; // Set FrameTable entry to indicate frame is in use
_pageTable[index] = i; // Set PageTable entry to refer to the frame in question
}
#ifdef DEBUG_VERBOSE
cout << "Page #" << index << " was referenced and has Frame #"
<< _pageTable[index] << endl;
#endif
return _pageTable[index];
}
// Creates a string representation of the page table
string PageTable::toString() {
string out = "";
// Header
out += "*" + padding(14, '-') + "*\n";
out += "| Page | Frame |\n";
out += "*" + padding(14, '-') + "*\n";
// Data
for (int i = 0; i < NUM_FRAMES; i++) {
stringstream ss;
ss << dec << setfill('0');
int frame = _pageTable[i];
ss << "| " << setw(2) << i << " | " << setw(2) << frame << " |\n";
out += (frame > 0 ? ss.str() : "");
}
out += "*" + padding(14, '-') + "*\n";
return out;
}
// Print the string representation of the page table
void PageTable::print() {
cout << PageTable::toString();
}
// Return a string consisting of n of the specified character (default: space)
string padding(int n) { return padding(n, ' '); }
string padding(int n, char c) {
string out = "";
for (int i = 0; i < n; i++) {
out += c;
}
return out;
}
// Return a horizontal rule of # characters (std console width = 80chars)
string horizontalrule() {
string out = "";
for (int i = 0; i < 80; i++) {
out += "#";
}
out += "\n";
return out;
}
// Divide the string into 80 character lines with textbox borders left and right
string textboxline(string text) {
// Trim trailing and leading spaces
text = text.erase(text.find_last_not_of(" \t\n\r") + 1);
text = text.erase(0, text.find_first_not_of(" \t\n\r"));
// Generate box
string out = "";
if (text.length() < 76) {
int numSpacers = 76 - text.length();
int leftSpacers = (numSpacers / 2);
int rightSpacers = leftSpacers + (numSpacers % 2);
out += "# ";
for (int i = 0; i < leftSpacers; i++) {
out += " ";
}
out += text;
for (int i = 0; i < rightSpacers; i++) {
out += " ";
}
out += " #\n";
} else {
int i = (text.length() / 2) - 1;
while (text.at(i) != '-' && text.at(i) != ' ') {
i++;
}
i++;
out += textboxline(text.substr(0, i));
out += textboxline(text.substr(i, text.length() + 1 - i));
}
return out;
}
// Return a textbox of width = 80chars, wrapped with # symbols
string textbox(string text) {
string out = "\n";
out += horizontalrule();
out += textboxline(text);
out += horizontalrule();
out += "\n";
return out;
}
// Return a thicker textbox (i.e.: extra horizontalrule above and below).
string titlebox(string text) {
string out = "\n";
out += horizontalrule();
out += horizontalrule();
out += textboxline(text);
out += horizontalrule();
out += horizontalrule();
out += "\n";
return out;
}