Menu

[6d9522]: / examples / mist_gen / src / ValueLoader.cpp  Maximize  Restore  History

Download this file

197 lines (160 with data), 5.4 kB

  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
#include <iterator>
#include <fstream>
#include <cassert>
#include "ValueLoader.h"
using namespace std;
///////////////////////////////////////////////////////////////////////
// Strings
const string groupMarker = "[group]";
const string begMarker = "=>>";
const string endMarker = "<<";
// Errors
const string errOpenFailed = "unable to open file ";
const string errReadFailed = "unable to read file ";
const string errEqExpected = "\'=\' is missing";
const string errNameExpected = "name is missing";
const string errOnlyWhitespaceAllowed =
"only whitespace characters are allowed after ";
const string errEndMarkerExpected = "\"<<\" is missing";
///////////////////////////////////////////////////////////////////////
CValueLoader::CValueLoader()
{}
void
CValueLoader::loadValues(const std::string& filePath)
{
assert(valueGroups.size() == 0);
vector<ValueList> groups(1); // create one element - for the globals
ifstream inputFile(filePath.c_str());
if (!inputFile) {
throw CLoadingError(errOpenFailed + filePath);
}
int lineNumber = 0;
while (loadValueGroup(inputFile, groups.back(), lineNumber)) {
groups.resize(groups.size() + 1);
}
valueGroups.swap(groups);
return;
}
bool
CValueLoader::loadValueGroup(std::istream& inputStream,
ValueList& valueGroup, int& lineNumber)
{
assert(valueGroup.empty());
string line;
while (getline(inputStream, line)) {
++lineNumber;
trimString(line);
// If the line is blank or is a comment, skip it.
if (line.empty() || line.at(0) == '#') {
continue;
}
if (line == groupMarker) {
// reached the end of the current group, nothing more to do
return true;
}
if (line.length() > groupMarker.length()
&& line.compare(0, groupMarker.length(), groupMarker) == 0)
{
string err = formatErrorMessage(lineNumber,
errOnlyWhitespaceAllowed + "\"" + groupMarker + "\"");
throw CLoadingError(err);
}
combineSplitLine(line, inputStream, lineNumber);
// Extract the name of the parameter.
CValue v;
string::size_type posEq = line.find('=');
if (posEq == string::npos) {
string err = formatErrorMessage(lineNumber, errEqExpected);
throw CLoadingError(err);
} else if (posEq == 0) {
string err = formatErrorMessage(lineNumber, errNameExpected);
throw CLoadingError(err);
}
string::size_type pos = line.find_last_not_of(whitespaceList,
posEq - 1);
v.name = line.substr(0, pos + 1);
if (line.compare(posEq, begMarker.length(), begMarker) == 0) {
// Possibly a multi-line value
if (line.length() - posEq != begMarker.length()) {
string err = formatErrorMessage(lineNumber,
errOnlyWhitespaceAllowed + "\"" + begMarker + "\"");
throw CLoadingError(err);
}
loadMultiLineValue(inputStream, v.value, lineNumber);
} else {
// A single-line value
pos = line.find_first_not_of(whitespaceList, posEq + 1);
if (pos != string::npos) {
v.value = line.substr(pos);
}
}
// Now both the name and the value must be prepared.
valueGroup.push_back(v);
}
return false;
}
void
CValueLoader::combineSplitLine(std::string& str, std::istream& inputStream,
int& lineNumber)
{
assert(str.length() >= 1);
string::size_type length = str.length();
while (str.at(length - 1) == '\\') {
str.erase(--length);
if (length != 0 && str.at(length - 1) == '\\') {
// "escaped" backslash, nothing more to do: no line break
return;
}
// remove trailing whitespace chars
string::size_type pos = str.find_last_not_of(whitespaceList);
if (pos == string::npos) {
// the string consists entirely of whitespace characters
str.clear();
} else {
str.erase(pos + 1);
}
string line;
if (! getline(inputStream, line)) {
return;
}
++lineNumber;
trimString(line);
if (line.empty()) {
return;
}
if (! str.empty()) {
str = str + " " + line;
} else {
str = line;
}
length = str.length();
}
return;
}
void
CValueLoader::loadMultiLineValue(std::istream& inputStream,
std::string& value, int& lineNumber)
{
assert(value.empty());
do {
string line;
if (! getline(inputStream, line)) {
string err = formatErrorMessage(lineNumber,
errEndMarkerExpected);
throw CLoadingError(err);
}
++lineNumber;
string trimmed = line;
trimString(trimmed);
if (trimmed == endMarker) {
break;
}
if (value.empty()) {
value = line;
} else {
value = value + "\n" + line;
}
}
while (true);
return;
}