GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/*************************************** |
||
2 |
Auteur : Pierre Aubert |
||
3 |
Mail : pierre.aubert@lapp.in2p3.fr |
||
4 |
Licence : CeCILL-C |
||
5 |
****************************************/ |
||
6 |
|||
7 |
#include <fstream> |
||
8 |
#include "DicoValue.h" |
||
9 |
|||
10 |
///Constructor of class DicoValue |
||
11 |
1116 |
DicoValue::DicoValue(){ |
|
12 |
|||
13 |
1116 |
} |
|
14 |
|||
15 |
///Copy Constructor of class DicoValue |
||
16 |
/** @param other : DicoValue we want ot copy |
||
17 |
*/ |
||
18 |
631 |
DicoValue::DicoValue(const DicoValue & other){ |
|
19 |
✓ | 631 |
copyDicoValue(other); |
20 |
631 |
} |
|
21 |
|||
22 |
///Destructor of class DicoValue |
||
23 |
3494 |
DicoValue::~DicoValue(){ |
|
24 |
|||
25 |
} |
||
26 |
|||
27 |
///Operator = of class DicoValue |
||
28 |
/** @param other : DicoValue we want ot copy |
||
29 |
* @return copied class DicoValue |
||
30 |
*/ |
||
31 |
435 |
DicoValue & DicoValue::operator = (const DicoValue & other){ |
|
32 |
435 |
copyDicoValue(other); |
|
33 |
435 |
return *this; |
|
34 |
} |
||
35 |
|||
36 |
///Load the DicoValue with a text file |
||
37 |
/** @param fileName : name of the file to be loaded |
||
38 |
* @return true on success, false otherwise |
||
39 |
*/ |
||
40 |
19 |
bool DicoValue::load(const std::string & fileName){ |
|
41 |
✓ | 38 |
PFileParser parser; |
42 |
✓✓✓ | 19 |
if(!parser.open(fileName)){ |
43 |
✓✓✓✓ |
7 |
std::cerr << "DicoValue::load : cannot load the file '"<<fileName<<"'" << std::endl; |
44 |
7 |
return false; |
|
45 |
} |
||
46 |
✓ | 12 |
return loadParser(parser); |
47 |
} |
||
48 |
|||
49 |
///Save the DicoValue with a text file |
||
50 |
/** @param fileName : name of the file to be saved |
||
51 |
* @return true on success, false otherwise |
||
52 |
*/ |
||
53 |
9 |
bool DicoValue::save(const std::string & fileName) const{ |
|
54 |
✓ | 18 |
std::string out("\n{"); |
55 |
✓✓✓ | 9 |
out += saveRecurse("\t"); |
56 |
✓ | 9 |
out += "\n}\n\n"; |
57 |
✓ | 18 |
return saveFileContent(fileName, out); |
58 |
} |
||
59 |
|||
60 |
///Convert the DicoValue into a string |
||
61 |
/** @param indentation : indentation of the current DicoValue |
||
62 |
* @param isAfterDash : true if the toString is performed after a dash, false otherwise |
||
63 |
* @return string |
||
64 |
*/ |
||
65 |
415 |
std::string DicoValue::toString(const std::string & indentation, int isAfterDash) const{ |
|
66 |
✓✓✓ | 1245 |
std::string out(""), newIndentation(indentation), currentIndentation(indentation); |
67 |
✓✓ | 415 |
if(isAfterDash > 0){ |
68 |
✓ | 92 |
currentIndentation = ""; |
69 |
} |
||
70 |
✓✓✓ | 415 |
if(p_key != ""){ |
71 |
✓ | 322 |
newIndentation = indentation + "\t"; |
72 |
} |
||
73 |
✓✓ | 415 |
if(p_mapChild.size() != 0lu){ |
74 |
✓✓✓✓ ✓✓ |
102 |
if(p_key != ""){out += currentIndentation + p_key + ":\n";} |
75 |
✓✓ | 424 |
for(MapDicoValue::const_iterator it(p_mapChild.begin()); it != p_mapChild.end(); ++it){ |
76 |
✓✓ | 322 |
out += it->second.toString(newIndentation, isAfterDash); |
77 |
} |
||
78 |
✓✓ | 313 |
}else if(p_vecChild.size() != 0lu){ |
79 |
✓ | 56 |
std::string dash("- "); |
80 |
✓✓✓ | 28 |
if(p_key != ""){ |
81 |
✓✓✓ | 27 |
out += currentIndentation + p_key + ":\n"; |
82 |
} |
||
83 |
✓✓ | 90 |
for(VecDicoValue::const_iterator it(p_vecChild.begin()); it != p_vecChild.end(); ++it){ |
84 |
✓✓✓✓ |
62 |
out += newIndentation + dash + it->toString(newIndentation, 2); |
85 |
} |
||
86 |
}else{ |
||
87 |
✓✓✓ | 285 |
if(p_key != ""){ |
88 |
✓✓✓✓ ✓ |
236 |
out += indentation + p_key + ": "+p_value+"\n"; |
89 |
}else{ |
||
90 |
✓✓ | 49 |
out += p_value + "\n"; |
91 |
} |
||
92 |
} |
||
93 |
415 |
--isAfterDash; |
|
94 |
830 |
return out; |
|
95 |
} |
||
96 |
|||
97 |
///Print the DicoValue |
||
98 |
31 |
void DicoValue::print() const{ |
|
99 |
✓✓✓✓ |
31 |
std::cout << toString() << std::endl; |
100 |
31 |
} |
|
101 |
|||
102 |
///Say if the DicoValue has a key |
||
103 |
/** @return true if the DicoValue has a key, false otherwise |
||
104 |
*/ |
||
105 |
92 |
bool DicoValue::hasKey() const{return p_key != "";} |
|
106 |
|||
107 |
///Say if the DicoValue has a map of children |
||
108 |
/** @return true if the DicoValue has a map of children, false otherwise |
||
109 |
*/ |
||
110 |
127 |
bool DicoValue::hasMap() const{return p_mapChild.size() != 0lu;} |
|
111 |
|||
112 |
///Say if the DicoValue has a vector of children |
||
113 |
/** @return true if the DicoValue has a vector of children, false otherwise |
||
114 |
*/ |
||
115 |
99 |
bool DicoValue::hasVec() const{return p_vecChild.size() != 0lu;} |
|
116 |
|||
117 |
///Say if the given key exists in the map of children |
||
118 |
/** @param key : key to be checked |
||
119 |
* @return true if the given key exists in the map of children, false otherwise |
||
120 |
*/ |
||
121 |
1 |
bool DicoValue::isKeyExist(const std::string & key) const{ |
|
122 |
✓ | 1 |
std::map<std::string, DicoValue>::const_iterator it(p_mapChild.find(key)); |
123 |
1 |
return it != p_mapChild.end(); |
|
124 |
} |
||
125 |
|||
126 |
///Get a DicoValue in the map of the current one |
||
127 |
/** @param key : name of the DicoValue to get |
||
128 |
* @return pointer to the found DicoValue if it exists, NULL otherwise |
||
129 |
*/ |
||
130 |
324 |
const DicoValue * DicoValue::getMap(const std::string & key) const{ |
|
131 |
✓ | 324 |
std::map<std::string, DicoValue>::const_iterator it(p_mapChild.find(key)); |
132 |
✓✓ | 324 |
if(it != p_mapChild.end()){ |
133 |
260 |
return &(it->second); |
|
134 |
}else{ |
||
135 |
64 |
return NULL; |
|
136 |
} |
||
137 |
} |
||
138 |
|||
139 |
///Get a DicoValue in the map of the current one |
||
140 |
/** @param key : name of the DicoValue to get |
||
141 |
* @return pointer to the found DicoValue if it exists, NULL otherwise |
||
142 |
*/ |
||
143 |
69 |
DicoValue * DicoValue::getMap(const std::string & key){ |
|
144 |
✓ | 69 |
std::map<std::string, DicoValue>::const_iterator it(p_mapChild.find(key)); |
145 |
✓✓ | 69 |
if(it != p_mapChild.end()){ |
146 |
68 |
return (DicoValue *)&(it->second); |
|
147 |
}else{ |
||
148 |
1 |
return NULL; |
|
149 |
} |
||
150 |
} |
||
151 |
|||
152 |
///Sets the value of the DicoValue |
||
153 |
/** @param value : value of the DicoValue |
||
154 |
*/ |
||
155 |
444 |
void DicoValue::setValue(const std::string & value){ |
|
156 |
444 |
p_value = value; |
|
157 |
444 |
} |
|
158 |
|||
159 |
///Sets the key of the DicoValue |
||
160 |
/** @param key : key of the DicoValue |
||
161 |
*/ |
||
162 |
467 |
void DicoValue::setKey(const std::string & key){ |
|
163 |
467 |
p_key = key; |
|
164 |
467 |
} |
|
165 |
|||
166 |
///Sets the vecChild of the DicoValue |
||
167 |
/** @param vecChild : vecChild of the DicoValue |
||
168 |
*/ |
||
169 |
1 |
void DicoValue::setVecChild(const std::vector<DicoValue> & vecChild){ |
|
170 |
1 |
p_vecChild = vecChild; |
|
171 |
1 |
} |
|
172 |
|||
173 |
///Sets the mapChild of the DicoValue |
||
174 |
/** @param mapChild : mapChild of the DicoValue |
||
175 |
*/ |
||
176 |
1 |
void DicoValue::setMapChild(const std::map<std::string, DicoValue> & mapChild){ |
|
177 |
1 |
p_mapChild = mapChild; |
|
178 |
1 |
} |
|
179 |
|||
180 |
///Gets the value of the DicoValue |
||
181 |
/** @return value of the DicoValue |
||
182 |
*/ |
||
183 |
129 |
const std::string & DicoValue::getValue() const{ |
|
184 |
129 |
return p_value; |
|
185 |
} |
||
186 |
|||
187 |
///Gets the value of the DicoValue |
||
188 |
/** @return value of the DicoValue |
||
189 |
*/ |
||
190 |
53 |
std::string & DicoValue::getValue(){ |
|
191 |
53 |
return p_value; |
|
192 |
} |
||
193 |
|||
194 |
///Get a string value without the first and/or last quote or double quote in there are some |
||
195 |
/** @return value without the first and/or last quote or double quote in there are some |
||
196 |
*/ |
||
197 |
260 |
std::string DicoValue::getString() const{ |
|
198 |
✓✓ | 260 |
return eraseFirstLastChars(p_value, "\"\'"); |
199 |
} |
||
200 |
|||
201 |
///Gets the key of the DicoValue |
||
202 |
/** @return key of the DicoValue |
||
203 |
*/ |
||
204 |
43 |
const std::string & DicoValue::getKey() const{ |
|
205 |
43 |
return p_key; |
|
206 |
} |
||
207 |
|||
208 |
///Gets the key of the DicoValue |
||
209 |
/** @return key of the DicoValue |
||
210 |
*/ |
||
211 |
311 |
std::string & DicoValue::getKey(){ |
|
212 |
311 |
return p_key; |
|
213 |
} |
||
214 |
|||
215 |
///Gets the vecChild of the DicoValue |
||
216 |
/** @return vecChild of the DicoValue |
||
217 |
*/ |
||
218 |
43 |
const std::vector<DicoValue> & DicoValue::getVecChild() const{ |
|
219 |
43 |
return p_vecChild; |
|
220 |
} |
||
221 |
|||
222 |
///Gets the vecChild of the DicoValue |
||
223 |
/** @return vecChild of the DicoValue |
||
224 |
*/ |
||
225 |
95 |
std::vector<DicoValue> & DicoValue::getVecChild(){ |
|
226 |
95 |
return p_vecChild; |
|
227 |
} |
||
228 |
|||
229 |
///Gets the mapChild of the DicoValue |
||
230 |
/** @return mapChild of the DicoValue |
||
231 |
*/ |
||
232 |
4 |
const std::map<std::string, DicoValue> & DicoValue::getMapChild() const{ |
|
233 |
4 |
return p_mapChild; |
|
234 |
} |
||
235 |
|||
236 |
///Gets the mapChild of the DicoValue |
||
237 |
/** @return mapChild of the DicoValue |
||
238 |
*/ |
||
239 |
497 |
std::map<std::string, DicoValue> & DicoValue::getMapChild(){ |
|
240 |
497 |
return p_mapChild; |
|
241 |
} |
||
242 |
|||
243 |
///Copy Function of class DicoValue |
||
244 |
/** @param other : DicoValue we want ot copy |
||
245 |
*/ |
||
246 |
1066 |
void DicoValue::copyDicoValue(const DicoValue & other){ |
|
247 |
1066 |
p_value = other.p_value; |
|
248 |
1066 |
p_key = other.p_key; |
|
249 |
1066 |
p_vecChild = other.p_vecChild; |
|
250 |
1066 |
p_mapChild = other.p_mapChild; |
|
251 |
1066 |
} |
|
252 |
|||
253 |
///Load the DicoValue with a parser |
||
254 |
/** @param[out] parser : parser to be used |
||
255 |
* @return true on success, false otherwise |
||
256 |
*/ |
||
257 |
12 |
bool DicoValue::loadParser(PFileParser & parser){ |
|
258 |
✓ | 12 |
parser.setEscapeChar('\\'); |
259 |
✓✓ | 12 |
parser.setWhiteSpace(" \t\n"); |
260 |
✓✓ | 12 |
parser.setSeparator(",:{}\""); |
261 |
12 |
bool isRunning(true); |
|
262 |
✓✓✓✓ ✓✓✓ |
25 |
while(!parser.isEndOfFile() && isRunning){ |
263 |
✓✓✗ | 13 |
if(parseDicoValue(parser, isRunning)){ |
264 |
✓ | 13 |
parser.skipWhiteSpace(); |
265 |
}else{ |
||
266 |
errorAt(parser, isRunning, "Cannot parse dico value"); |
||
267 |
} |
||
268 |
} |
||
269 |
12 |
return isRunning; |
|
270 |
} |
||
271 |
|||
272 |
///Parse a DicoValue with a text file |
||
273 |
/** @param[out] parser : parser to be used |
||
274 |
* @param[out] isRunning : true to continue the parsing, false to stop it |
||
275 |
* @return true on success, false otherwise |
||
276 |
*/ |
||
277 |
86 |
bool DicoValue::parseDicoValue(PFileParser & parser, bool & isRunning){ |
|
278 |
✓✓ | 86 |
if(parseListOrMap(parser, isRunning)){return true;} |
279 |
else{ |
||
280 |
✓ | 66 |
std::string nextKeyOrValue(parseString(parser)); |
281 |
✓✓ | 66 |
if(nextKeyOrValue == ""){ |
282 |
✓✓ | 48 |
nextKeyOrValue = parser.getStrComposedOf("abcdefghijklmnopqsrtuvwxyzABCDEFGHIJKLMNOPQSRTUVWXYZ0123456789._-"); |
283 |
✓✓ | 48 |
if(nextKeyOrValue == ""){ |
284 |
✓✓ | 4 |
return errorAt(parser, isRunning, |
285 |
2 |
"Expecting a string or a keywork composed of letters, number, underscore, slash or minus"); |
|
286 |
} |
||
287 |
} |
||
288 |
✓✓✓✓ |
64 |
if(parser.isMatch(":")){ //It was a key for a dictionnary |
289 |
// std::cerr << "DicoValue::parseDicoValue : find key '"<<nextKeyOrValue<<"'" << std::endl; |
||
290 |
✓ | 26 |
p_key = nextKeyOrValue; |
291 |
✓✗✓ | 26 |
if(!parseDicoValue(parser, isRunning)){ |
292 |
return errorAt(parser, isRunning, "Cannot parse value"); |
||
293 |
} |
||
294 |
}else{ //It was a value |
||
295 |
✓ | 38 |
p_value = nextKeyOrValue; |
296 |
} |
||
297 |
✓ | 64 |
parser.skipWhiteSpace(); |
298 |
} |
||
299 |
64 |
return true; |
|
300 |
} |
||
301 |
|||
302 |
///Parse a list or a map |
||
303 |
/** @param[out] parser : parser to be used |
||
304 |
* @param[out] isRunning : true to continue the parsing, false to stop it |
||
305 |
* @return true on success, false otherwise |
||
306 |
*/ |
||
307 |
86 |
bool DicoValue::parseListOrMap(PFileParser & parser, bool & isRunning){ |
|
308 |
✓✓✓✓ |
86 |
if(!parser.isMatch("{")){return false;} //If this is not a {, then it is not a list or a map |
309 |
|||
310 |
✓✓✓✓ ✓✓✓✓ ✗✓✓✓ ✓✓✓✗ ✗✗✗ |
63 |
while(!parser.isEndOfFile() && !parser.isMatch("}") && isRunning){ |
311 |
✓ | 47 |
DicoValue dv; |
312 |
✓✓✗ | 47 |
if(dv.parseDicoValue(parser, isRunning)){ |
313 |
✓✓✓ | 47 |
if(dv.p_key != ""){ //It is a dico entry |
314 |
// std::cerr << "DicoValue::parseListOrMap : loadParser add DicoValue with key '"<<dv.p_key<<"'" << std::endl; |
||
315 |
✓✓ | 26 |
p_mapChild[dv.p_key] = dv; |
316 |
}else{ //It is a value |
||
317 |
✓ | 21 |
p_vecChild.push_back(dv); |
318 |
} |
||
319 |
}else{ |
||
320 |
errorAt(parser, isRunning, "Cannot parse dico value"); |
||
321 |
} |
||
322 |
✓✓✓✓ |
47 |
if(parser.isMatch(",")){} |
323 |
✓✓✓✓ |
19 |
else if(parser.isMatchRewind("}")){} |
324 |
else{ |
||
325 |
✓✓ | 4 |
return errorAt(parser, isRunning, "Expect ',' or '}' after value"); |
326 |
} |
||
327 |
} |
||
328 |
|||
329 |
16 |
return true; |
|
330 |
} |
||
331 |
|||
332 |
///Parse a string |
||
333 |
/** @param[out] parser : parser to be used |
||
334 |
* @return true on success, false otherwise |
||
335 |
*/ |
||
336 |
66 |
std::string DicoValue::parseString(PFileParser & parser){ |
|
337 |
✓✓✓✓ |
66 |
if(parser.isMatch("\"")){ |
338 |
✓✓ | 16 |
return parser.getUntilKeyWithoutPatern("\""); |
339 |
✓✓✓✓ |
50 |
}else if(parser.isMatch("'")){ |
340 |
✓✓ | 2 |
return parser.getUntilKeyWithoutPatern("'"); |
341 |
} |
||
342 |
✓ | 48 |
return ""; |
343 |
} |
||
344 |
|||
345 |
///Print the parsing error |
||
346 |
/** @param[out] parser : parser to be used |
||
347 |
* @param[out] isRunning : true to continue the parsing, false to stop it |
||
348 |
* @param errorMsg : error message |
||
349 |
* @return true and stop the parsing with isRunning |
||
350 |
*/ |
||
351 |
6 |
bool DicoValue::errorAt(PFileParser & parser, bool & isRunning, const std::string & errorMsg){ |
|
352 |
6 |
isRunning = false; |
|
353 |
✓✓ | 6 |
std::cerr << "DicoValue::errorAt : " << parser.getLocation() << std::endl; |
354 |
6 |
std::cerr << "\t" << errorMsg << std::endl; |
|
355 |
6 |
return true; |
|
356 |
} |
||
357 |
|||
358 |
///Save the DicoValue with a text file |
||
359 |
/** @param indentation : indentation of the current DicoValue |
||
360 |
* @return file content |
||
361 |
*/ |
||
362 |
52 |
std::string DicoValue::saveRecurse(const std::string & indentation) const{ |
|
363 |
✓✓ | 156 |
std::string out(""), newIndentation(""); |
364 |
✓✓✓ | 52 |
if(p_key != ""){ |
365 |
✓ | 25 |
newIndentation = indentation + "\t"; |
366 |
} |
||
367 |
✓✓ | 52 |
if(p_mapChild.size() != 0lu){ |
368 |
✓✓✓✓ ✓✓✓ |
9 |
if(p_key != ""){out += "\n" + indentation +p_key + ": {";} |
369 |
✓ | 18 |
std::string comma(""); |
370 |
✓✓ | 34 |
for(MapDicoValue::const_iterator it(p_mapChild.begin()); it != p_mapChild.end(); ++it){ |
371 |
✓ | 25 |
out += comma; |
372 |
✓✓ | 25 |
out += it->second.saveRecurse(newIndentation); |
373 |
✓ | 25 |
comma = ","; |
374 |
} |
||
375 |
✓✓✓✓ ✓✓ |
9 |
if(p_key != ""){out += "\n"+indentation+"}";} |
376 |
✓✓ | 43 |
}else if(p_vecChild.size() != 0lu){ |
377 |
✓✓✗✓ ✓✓✓ |
6 |
if(p_key != ""){out += "\n" + indentation + p_key + ": {";} |
378 |
✓ | 12 |
std::string comma(""); |
379 |
✓✓ | 24 |
for(VecDicoValue::const_iterator it(p_vecChild.begin()); it != p_vecChild.end(); ++it){ |
380 |
✓ | 18 |
out += comma; |
381 |
✓✓ | 18 |
out += it->saveRecurse(newIndentation); |
382 |
✓ | 18 |
comma = ", "; |
383 |
} |
||
384 |
✓✓✗✓ |
6 |
if(p_key != ""){out += "}";} |
385 |
}else{ |
||
386 |
✓ | 74 |
std::string valueToSave(p_value); |
387 |
✓✓✓✓ |
37 |
if(findCharsInString(p_value, " \t\n':/")){ |
388 |
✓✓ | 3 |
valueToSave = "\"" + p_value + "\""; |
389 |
} |
||
390 |
✓✓✓✓ ✓✓✓✓ |
37 |
if(p_key != ""){out += "\n" + indentation + p_key + ": "+valueToSave;} |
391 |
✓ | 21 |
else{out += valueToSave;} |
392 |
} |
||
393 |
|||
394 |
104 |
return out; |
|
395 |
} |
||
396 |
|||
397 |
Generated by: GCOVR (Version 4.2) |