GCC Code Coverage Report


Directory: ./
File: tmp_project/PhoenixFileParser/src/DicoValue.cpp
Date: 2025-03-14 11:45:13
Exec Total Coverage
Lines: 155 166 93.4%
Branches: 195 227 85.9%

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