Directory: | ./ |
---|---|
File: | src/DicoValue.cpp |
Date: | 2025-05-14 16:06:02 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 174 | 211 | 82.5% |
Branches: | 222 | 353 | 62.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.setEscapeChar('\\'); |
65 |
1/1✓ Branch 1 taken 1 times.
|
1 | parser.setFileContent(content); |
66 |
1/1✓ Branch 1 taken 1 times.
|
2 | return loadParser(parser); |
67 | 1 | } | |
68 | |||
69 | ///Convert the DicoValue into a string | ||
70 | /** @param valueDecorator : string to add around keys and values ('"' for JSON) | ||
71 | * @param baseIndentation : indentation character(s) to be used | ||
72 | * @param baseNewLine : new line character(s) to be used | ||
73 | * @return corresponding string | ||
74 | */ | ||
75 | 12 | PString DicoValue::toString(const PString & valueDecorator, PString baseIndentation, PString baseNewLine) const{ | |
76 |
1/1✓ Branch 2 taken 12 times.
|
12 | PString out(baseNewLine+"{"); |
77 |
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); |
78 |
3/3✓ Branch 1 taken 12 times.
✓ Branch 4 taken 12 times.
✓ Branch 7 taken 12 times.
|
12 | out += baseNewLine+"}"+baseNewLine; |
79 | 12 | return out; | |
80 | } | ||
81 | |||
82 | ///Print the DicoValue | ||
83 | ✗ | void DicoValue::print() const{ | |
84 | ✗ | std::cout << "{" << std::endl; | |
85 | ✗ | std::cout << saveRecurse("\t", "\"", "\t", "\n") << std::endl; | |
86 | ✗ | std::cout << "{" << std::endl; | |
87 | } | ||
88 | |||
89 | ///Say if the DicoValue has a key | ||
90 | /** @return true if the DicoValue has a key, false otherwise | ||
91 | */ | ||
92 | 2 | bool DicoValue::hasKey() const{return p_key != "";} | |
93 | |||
94 | ///Say if the DicoValue has a map of children | ||
95 | /** @return true if the DicoValue has a map of children, false otherwise | ||
96 | */ | ||
97 | 2 | bool DicoValue::hasMap() const{return p_mapChild.size() != 0lu;} | |
98 | |||
99 | ///Say if the DicoValue has a vector of children | ||
100 | /** @return true if the DicoValue has a vector of children, false otherwise | ||
101 | */ | ||
102 | 1 | bool DicoValue::hasVec() const{return p_vecChild.size() != 0lu;} | |
103 | |||
104 | ///Say if the given key exists in the map of children | ||
105 | /** @param key : key to be checked | ||
106 | * @return true if the given key exists in the map of children, false otherwise | ||
107 | */ | ||
108 | 1 | bool DicoValue::isKeyExist(const PString & key) const{ | |
109 |
1/1✓ Branch 1 taken 1 times.
|
1 | std::map<PString, DicoValue>::const_iterator it(p_mapChild.find(key)); |
110 | 1 | return it != p_mapChild.end(); | |
111 | } | ||
112 | |||
113 | ///Get a DicoValue in the map of the current one | ||
114 | /** @param key : name of the DicoValue to get | ||
115 | * @return pointer to the found DicoValue if it exists, NULL otherwise | ||
116 | */ | ||
117 | 37 | const DicoValue * DicoValue::getMap(const PString & key) const{ | |
118 |
1/1✓ Branch 1 taken 37 times.
|
37 | std::map<PString, DicoValue>::const_iterator it(p_mapChild.find(key)); |
119 |
2/2✓ Branch 2 taken 28 times.
✓ Branch 3 taken 9 times.
|
37 | if(it != p_mapChild.end()){ |
120 | 28 | return &(it->second); | |
121 | }else{ | ||
122 | 9 | return NULL; | |
123 | } | ||
124 | } | ||
125 | |||
126 | ///Get a nested DicoValue in the map of the current one | ||
127 | /** @param vecKey : full address name of the DicoValue to get | ||
128 | * @return pointer to the found DicoValue if it exists, NULL otherwise | ||
129 | */ | ||
130 | 1 | const DicoValue * DicoValue::getMap(const PVecString & vecKey) const{ | |
131 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if(vecKey.size() == 0lu){return NULL;} |
132 | 1 | const DicoValue * tmpDico = this; | |
133 |
5/6✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
|
2 | for(PVecString::const_iterator itAddress(vecKey.begin()); itAddress != vecKey.end() && tmpDico != NULL; ++itAddress){ |
134 |
2/3✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | if(tmpDico->hasMap()){ |
135 |
1/1✓ Branch 2 taken 1 times.
|
1 | const DicoValue * key = tmpDico->getMap(*itAddress); |
136 | 1 | tmpDico = key; | |
137 | }else{ | ||
138 | ✗ | tmpDico = NULL; | |
139 | } | ||
140 | } | ||
141 | 1 | return tmpDico; | |
142 | } | ||
143 | |||
144 | ///Get the element of a vector of children of the current DicoValue which has 'key'.value = value | ||
145 | /** @param key : key to be found in a child of the current DicoValue | ||
146 | * @param value : expected value of the child | ||
147 | * @return pointer to the found child, NULL otherwise | ||
148 | */ | ||
149 | ✗ | const DicoValue * DicoValue::getElementInVecWhere(const PString & key, const PString & value) const{ | |
150 | ✗ | if(!hasVec()){return NULL;} | |
151 | ✗ | for(VecDicoValue::const_iterator it(p_vecChild.begin()); it != p_vecChild.end(); ++it){ | |
152 | ✗ | const DicoValue * element = it->getMap(key); | |
153 | ✗ | if(element != NULL){ | |
154 | ✗ | if(element->getString() == value){ | |
155 | ✗ | return &(*it); | |
156 | } | ||
157 | ✗ | }else if(it->p_mapChild.size() == 1lu){ | |
158 | ✗ | const DicoValue & mapElement = it->p_mapChild.begin()->second; | |
159 | ✗ | const DicoValue * elMap = mapElement.getMap(key); | |
160 | ✗ | if(elMap != NULL){ | |
161 | ✗ | if(elMap->getString() == value){ | |
162 | ✗ | return &mapElement; | |
163 | } | ||
164 | } | ||
165 | } | ||
166 | } | ||
167 | ✗ | return NULL; | |
168 | } | ||
169 | |||
170 | |||
171 | ///Get a DicoValue in the map of the current one | ||
172 | /** @param key : name of the DicoValue to get | ||
173 | * @return pointer to the found DicoValue if it exists, NULL otherwise | ||
174 | */ | ||
175 | 16 | DicoValue * DicoValue::getMap(const PString & key){ | |
176 |
1/1✓ Branch 1 taken 16 times.
|
16 | std::map<PString, DicoValue>::const_iterator it(p_mapChild.find(key)); |
177 |
2/2✓ Branch 3 taken 15 times.
✓ Branch 4 taken 1 times.
|
16 | if(it != p_mapChild.end()){ |
178 | 15 | return (DicoValue *)&(it->second); | |
179 | }else{ | ||
180 | 1 | return NULL; | |
181 | } | ||
182 | } | ||
183 | |||
184 | ///Sets the value of the DicoValue | ||
185 | /** @param value : value of the DicoValue | ||
186 | */ | ||
187 | 7 | void DicoValue::setValue(const PString & value){ | |
188 | 7 | p_value = value; | |
189 | 7 | } | |
190 | |||
191 | ///Sets the key of the DicoValue | ||
192 | /** @param key : key of the DicoValue | ||
193 | */ | ||
194 | 5 | void DicoValue::setKey(const PString & key){ | |
195 | 5 | p_key = key; | |
196 | 5 | } | |
197 | |||
198 | ///Sets the vecChild of the DicoValue | ||
199 | /** @param vecChild : vecChild of the DicoValue | ||
200 | */ | ||
201 | 1 | void DicoValue::setVecChild(const std::vector<DicoValue> & vecChild){ | |
202 | 1 | p_vecChild = vecChild; | |
203 | 1 | } | |
204 | |||
205 | ///Sets the mapChild of the DicoValue | ||
206 | /** @param mapChild : mapChild of the DicoValue | ||
207 | */ | ||
208 | 1 | void DicoValue::setMapChild(const std::map<PString, DicoValue> & mapChild){ | |
209 | 1 | p_mapChild = mapChild; | |
210 | 1 | } | |
211 | |||
212 | ///Gets the value of the DicoValue | ||
213 | /** @return value of the DicoValue | ||
214 | */ | ||
215 | ✗ | const PString & DicoValue::getValue() const{ | |
216 | ✗ | return p_value; | |
217 | } | ||
218 | |||
219 | ///Gets the value of the DicoValue | ||
220 | /** @return value of the DicoValue | ||
221 | */ | ||
222 | 2 | PString & DicoValue::getValue(){ | |
223 | 2 | return p_value; | |
224 | } | ||
225 | |||
226 | ///Get a string value without the first and/or last quote or double quote in there are some | ||
227 | /** @return value without the first and/or last quote or double quote in there are some | ||
228 | */ | ||
229 | 7 | PString DicoValue::getString() const{ | |
230 |
1/1✓ Branch 2 taken 7 times.
|
7 | return p_value.eraseFirstLastChar("\"\'"); |
231 | } | ||
232 | |||
233 | ///Gets the key of the DicoValue | ||
234 | /** @return key of the DicoValue | ||
235 | */ | ||
236 | ✗ | const PString & DicoValue::getKey() const{ | |
237 | ✗ | return p_key; | |
238 | } | ||
239 | |||
240 | ///Gets the key of the DicoValue | ||
241 | /** @return key of the DicoValue | ||
242 | */ | ||
243 | 1 | PString & DicoValue::getKey(){ | |
244 | 1 | return p_key; | |
245 | } | ||
246 | |||
247 | ///Gets the vecChild of the DicoValue | ||
248 | /** @return vecChild of the DicoValue | ||
249 | */ | ||
250 | 9 | const std::vector<DicoValue> & DicoValue::getVecChild() const{ | |
251 | 9 | return p_vecChild; | |
252 | } | ||
253 | |||
254 | ///Gets the vecChild of the DicoValue | ||
255 | /** @return vecChild of the DicoValue | ||
256 | */ | ||
257 | 3 | std::vector<DicoValue> & DicoValue::getVecChild(){ | |
258 | 3 | return p_vecChild; | |
259 | } | ||
260 | |||
261 | ///Gets the mapChild of the DicoValue | ||
262 | /** @return mapChild of the DicoValue | ||
263 | */ | ||
264 | 8 | const std::map<PString, DicoValue> & DicoValue::getMapChild() const{ | |
265 | 8 | return p_mapChild; | |
266 | } | ||
267 | |||
268 | ///Gets the mapChild of the DicoValue | ||
269 | /** @return mapChild of the DicoValue | ||
270 | */ | ||
271 | 10 | std::map<PString, DicoValue> & DicoValue::getMapChild(){ | |
272 | 10 | return p_mapChild; | |
273 | } | ||
274 | |||
275 | ///Copy Function of class DicoValue | ||
276 | /** @param other : DicoValue we want ot copy | ||
277 | */ | ||
278 | 145 | void DicoValue::copyDicoValue(const DicoValue & other){ | |
279 | 145 | p_value = other.p_value; | |
280 | 145 | p_key = other.p_key; | |
281 | 145 | p_vecChild = other.p_vecChild; | |
282 | 145 | p_mapChild = other.p_mapChild; | |
283 | 145 | } | |
284 | |||
285 | ///Load the DicoValue with a parser | ||
286 | /** @param[out] parser : parser to be used | ||
287 | * @return true on success, false otherwise | ||
288 | */ | ||
289 | 15 | bool DicoValue::loadParser(PFileParser & parser){ | |
290 |
1/1✓ Branch 1 taken 15 times.
|
15 | parser.setEscapeChar('\\'); |
291 |
2/2✓ Branch 1 taken 15 times.
✓ Branch 4 taken 15 times.
|
15 | parser.setWhiteSpace(" \t\n"); |
292 |
2/2✓ Branch 1 taken 15 times.
✓ Branch 4 taken 15 times.
|
15 | parser.setSeparator(",:{}\""); |
293 | 15 | bool isRunning(true); | |
294 |
6/7✓ Branch 1 taken 31 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16 times.
✓ Branch 8 taken 15 times.
|
31 | while(!parser.isEndOfFile() && isRunning){ |
295 |
2/3✓ Branch 1 taken 16 times.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | if(parseDicoValue(parser, isRunning)){ |
296 |
1/1✓ Branch 1 taken 16 times.
|
16 | parser.skipWhiteSpace(); |
297 | }else{ | ||
298 | ✗ | errorAt(parser, isRunning, "Cannot parse dico value"); | |
299 | } | ||
300 | } | ||
301 | 15 | return isRunning; | |
302 | } | ||
303 | |||
304 | ///Parse a DicoValue with a text file | ||
305 | /** @param[out] parser : parser to be used | ||
306 | * @param[out] isRunning : true to continue the parsing, false to stop it | ||
307 | * @return true on success, false otherwise | ||
308 | */ | ||
309 | 143 | bool DicoValue::parseDicoValue(PFileParser & parser, bool & isRunning){ | |
310 |
2/2✓ Branch 1 taken 29 times.
✓ Branch 2 taken 114 times.
|
143 | if(parseListOrMap(parser, isRunning)){return true;} |
311 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 114 times.
|
114 | else if(parseList(parser, isRunning)){return true;} |
312 | else{ | ||
313 |
1/1✓ Branch 1 taken 114 times.
|
114 | PString nextKeyOrValue; |
314 |
1/1✓ Branch 1 taken 114 times.
|
114 | bool isParsingStrOk(parseString(nextKeyOrValue, parser)); |
315 |
2/2✓ Branch 1 taken 48 times.
✓ Branch 2 taken 66 times.
|
114 | if(nextKeyOrValue == ""){ |
316 |
3/3✓ Branch 1 taken 48 times.
✓ Branch 4 taken 48 times.
✓ Branch 7 taken 48 times.
|
48 | nextKeyOrValue = parser.getStrComposedOf("abcdefghijklmnopqsrtuvwxyzABCDEFGHIJKLMNOPQSRTUVWXYZ0123456789._-+"); |
317 |
5/6✓ Branch 1 taken 2 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 46 times.
|
48 | if(nextKeyOrValue == "" && !isParsingStrOk){ |
318 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 4 taken 2 times.
|
4 | return errorAt(parser, isRunning, |
319 | 2 | "Expecting a string or a keywork composed of letters, number, underscore, slash or minus"); | |
320 | } | ||
321 | } | ||
322 |
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 |
323 | // std::cerr << "DicoValue::parseDicoValue : find key '"<<nextKeyOrValue<<"'" << std::endl; | ||
324 |
1/1✓ Branch 1 taken 53 times.
|
53 | p_key = nextKeyOrValue; |
325 |
2/3✓ Branch 1 taken 53 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 53 times.
|
53 | if(!parseDicoValue(parser, isRunning)){ |
326 | ✗ | return errorAt(parser, isRunning, "Cannot parse value"); | |
327 | } | ||
328 | }else{ //It was a value | ||
329 |
1/1✓ Branch 1 taken 59 times.
|
59 | p_value = nextKeyOrValue; |
330 | } | ||
331 |
1/1✓ Branch 1 taken 112 times.
|
112 | parser.skipWhiteSpace(); |
332 |
2/2✓ Branch 1 taken 112 times.
✓ Branch 2 taken 2 times.
|
114 | } |
333 | 112 | return true; | |
334 | } | ||
335 | |||
336 | ///Parse a list or a map | ||
337 | /** @param[out] parser : parser to be used | ||
338 | * @param[out] isRunning : true to continue the parsing, false to stop it | ||
339 | * @return true on success, false otherwise | ||
340 | */ | ||
341 | 143 | bool DicoValue::parseListOrMap(PFileParser & parser, bool & isRunning){ | |
342 |
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 |
343 |
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){ |
344 |
1/1✓ Branch 1 taken 74 times.
|
74 | DicoValue dv; |
345 |
2/3✓ Branch 1 taken 74 times.
✓ Branch 3 taken 74 times.
✗ Branch 4 not taken.
|
74 | if(dv.parseDicoValue(parser, isRunning)){ |
346 |
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 |
347 | // std::cerr << "DicoValue::parseListOrMap : loadParser add DicoValue with key '"<<dv.p_key<<"'" << std::endl; | ||
348 |
2/2✓ Branch 1 taken 53 times.
✓ Branch 4 taken 53 times.
|
53 | p_mapChild[dv.p_key] = dv; |
349 | }else{ //It is a value | ||
350 |
1/1✓ Branch 1 taken 21 times.
|
21 | p_vecChild.push_back(dv); |
351 | } | ||
352 | }else{ | ||
353 | ✗ | errorAt(parser, isRunning, "Cannot parse dico value"); | |
354 | } | ||
355 |
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(",")){} |
356 |
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("}")){} |
357 | else{ | ||
358 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
|
4 | return errorAt(parser, isRunning, "Expect ',' or '}' after value"); |
359 | } | ||
360 |
2/2✓ Branch 1 taken 70 times.
✓ Branch 2 taken 4 times.
|
74 | } |
361 | |||
362 | 25 | return true; | |
363 | } | ||
364 | |||
365 | ///Parse a list or a map | ||
366 | /** @param[out] parser : parser to be used | ||
367 | * @param[out] isRunning : true to continue the parsing, false to stop it | ||
368 | * @return true on success, false otherwise | ||
369 | */ | ||
370 | 114 | bool DicoValue::parseList(PFileParser & parser, bool & isRunning){ | |
371 |
2/3✓ Branch 2 taken 114 times.
✓ Branch 5 taken 114 times.
✗ Branch 6 not taken.
|
114 | if(!parser.isMatch("[")){return false;} //If this is not a {, then it is not a list or a map |
372 | |||
373 | ✗ | while(!parser.isEndOfFile() && !parser.isMatch("]") && isRunning){ | |
374 | ✗ | DicoValue dv; | |
375 | ✗ | if(dv.parseDicoValue(parser, isRunning)){ | |
376 | ✗ | if(dv.p_key != ""){ //It is a dico entry | |
377 | // std::cerr << "DicoValue::parseListOrMap : loadParser add DicoValue with key '"<<dv.p_key<<"'" << std::endl; | ||
378 | ✗ | p_mapChild[dv.p_key] = dv; | |
379 | }else{ //It is a value | ||
380 | ✗ | p_vecChild.push_back(dv); | |
381 | } | ||
382 | }else{ | ||
383 | ✗ | errorAt(parser, isRunning, "Cannot parse list value"); | |
384 | } | ||
385 | ✗ | if(parser.isMatch(",")){} | |
386 | ✗ | else if(parser.isMatchRewind("]")){} | |
387 | else{ | ||
388 | ✗ | return errorAt(parser, isRunning, "Expect ',' or ']' after value"); | |
389 | } | ||
390 | } | ||
391 | |||
392 | ✗ | return true; | |
393 | } | ||
394 | |||
395 | ///Parse a string | ||
396 | /** @param[out] parsedString : parsed string | ||
397 | * @param[out] parser : parser to be used | ||
398 | * @return true on success, false otherwise | ||
399 | */ | ||
400 | 114 | bool DicoValue::parseString(PString & parsedString, PFileParser & parser){ | |
401 |
3/3✓ Branch 2 taken 114 times.
✓ Branch 5 taken 64 times.
✓ Branch 6 taken 50 times.
|
114 | if(parser.isMatch("\"")){ |
402 |
2/2✓ Branch 2 taken 64 times.
✓ Branch 5 taken 64 times.
|
64 | parsedString = parser.getUntilKeyWithoutPatern("\""); |
403 | 64 | return true; | |
404 |
3/3✓ Branch 2 taken 50 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 48 times.
|
50 | }else if(parser.isMatch("'")){ |
405 |
2/2✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
|
2 | parsedString = parser.getUntilKeyWithoutPatern("'"); |
406 | 2 | return true; | |
407 | }else{ | ||
408 | 48 | parsedString = ""; | |
409 | 48 | return false; | |
410 | } | ||
411 | } | ||
412 | |||
413 | ///Print the parsing error | ||
414 | /** @param[out] parser : parser to be used | ||
415 | * @param[out] isRunning : true to continue the parsing, false to stop it | ||
416 | * @param errorMsg : error message | ||
417 | * @return true and stop the parsing with isRunning | ||
418 | */ | ||
419 | 6 | bool DicoValue::errorAt(PFileParser & parser, bool & isRunning, const PString & errorMsg){ | |
420 | 6 | isRunning = false; | |
421 |
2/2✓ Branch 3 taken 6 times.
✓ Branch 6 taken 6 times.
|
6 | std::cerr << "DicoValue::errorAt : " << parser.getLocation() << std::endl; |
422 | 6 | std::cerr << "\t" << errorMsg << std::endl; | |
423 |
3/3✓ Branch 3 taken 6 times.
✓ Branch 6 taken 6 times.
✓ Branch 9 taken 6 times.
|
6 | std::cerr << "Wrong token : '"<<parser.getNextToken()<<"'" << std::endl; |
424 | 6 | return true; | |
425 | } | ||
426 | |||
427 | ///Save the DicoValue with a text file | ||
428 | /** @param indentation : indentation of the current DicoValue | ||
429 | * @param valueDecorator : decorator to put around keys and values ('"' for JSON) | ||
430 | * @param baseIndentation : indentation character(s) to be used | ||
431 | * @param baseNewLine : new line character(s) to be used | ||
432 | * @param isInList : true if the dico value is in a list | ||
433 | * @return file content | ||
434 | */ | ||
435 | 82 | PString DicoValue::saveRecurse(const PString & indentation, const PString & valueDecorator, PString baseIndentation, PString baseNewLine, bool isInList) const{ | |
436 |
2/2✓ Branch 1 taken 82 times.
✓ Branch 4 taken 82 times.
|
82 | PString out(""), newIndentation(indentation); |
437 |
7/7✓ Branch 1 taken 82 times.
✓ Branch 3 taken 30 times.
✓ Branch 4 taken 52 times.
✓ Branch 5 taken 18 times.
✓ Branch 6 taken 12 times.
✓ Branch 7 taken 70 times.
✓ Branch 8 taken 12 times.
|
82 | if(p_key != "" || isInList){ |
438 |
2/2✓ Branch 1 taken 70 times.
✓ Branch 4 taken 70 times.
|
70 | newIndentation = indentation + baseIndentation; |
439 | } | ||
440 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 2 taken 64 times.
|
82 | if(p_mapChild.size() != 0lu){ |
441 |
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 + ": {";} |
442 |
1/8✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
|
9 | else if(isInList){out += baseNewLine+indentation+"{";} |
443 |
1/1✓ Branch 1 taken 18 times.
|
18 | PString comma(""); |
444 |
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){ |
445 |
1/1✓ Branch 1 taken 52 times.
|
52 | out += comma; |
446 |
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); |
447 |
1/1✓ Branch 1 taken 52 times.
|
52 | comma = ","; |
448 | } | ||
449 |
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+"}";} |
450 |
1/8✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
|
9 | else if(isInList){out += baseNewLine+indentation+"}";} |
451 |
2/2✓ Branch 2 taken 6 times.
✓ Branch 3 taken 58 times.
|
82 | }else if(p_vecChild.size() != 0lu){ |
452 |
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 + ": [";} |
453 |
1/1✓ Branch 1 taken 6 times.
|
6 | PString comma(""); |
454 |
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){ |
455 |
1/1✓ Branch 1 taken 18 times.
|
18 | out += comma; |
456 |
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, true); |
457 |
1/1✓ Branch 1 taken 18 times.
|
18 | comma = ", "; |
458 | } | ||
459 |
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 += "]";} |
460 | 6 | }else{ | |
461 |
1/1✓ Branch 1 taken 58 times.
|
58 | PString valueToSave(p_value); |
462 |
3/3✓ Branch 1 taken 58 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 46 times.
|
58 | if(valueDecorator != ""){ |
463 |
3/3✓ Branch 1 taken 12 times.
✓ Branch 4 taken 12 times.
✓ Branch 7 taken 12 times.
|
12 | valueToSave = valueDecorator + p_value + valueDecorator; |
464 |
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':/")){ |
465 |
3/3✓ Branch 1 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 7 taken 3 times.
|
3 | valueToSave = "\"" + p_value + "\""; |
466 | } | ||
467 |
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;} |
468 |
1/1✓ Branch 1 taken 21 times.
|
21 | else{out += valueToSave;} |
469 | 58 | } | |
470 | 164 | return out; | |
471 | 82 | } | |
472 | |||
473 | |||
474 |