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 |
///List of allowed char as balise name |
||
8 |
#define ALLOWED_BALISE_CHAR "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:?!-" |
||
9 |
|||
10 |
///List of allowed char as attribute name |
||
11 |
#define ALLOWED_ATTRIBUTE_CHAR "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:-" |
||
12 |
|||
13 |
#include "pxml_utils.h" |
||
14 |
|||
15 |
///Set the PFileParser for xml |
||
16 |
/** @param fileContent : content to be parsed |
||
17 |
* @param isSvg : true if the parsed file is a svg |
||
18 |
* @return PFileParser |
||
19 |
*/ |
||
20 |
21 |
PFileParser pxml_setXmlParser(const std::string & fileContent, bool isSvg){ |
|
21 |
21 |
PFileParser parser; |
|
22 |
✓✓ | 21 |
parser.setSeparator("<>\"="); |
23 |
✓✓ | 21 |
if(isSvg){ |
24 |
✓✓ | 8 |
parser.setWhiteSpace(""); |
25 |
}else{ |
||
26 |
✓✓ | 13 |
parser.setWhiteSpace("\t\n "); |
27 |
} |
||
28 |
✓ | 21 |
parser.setFileContent(fileContent); |
29 |
21 |
return parser; |
|
30 |
} |
||
31 |
|||
32 |
///Parse a PXml with a file |
||
33 |
/** @param[out] xml : PXml to be initialised |
||
34 |
* @param fileName : name of the intialisation file |
||
35 |
* @param isSvg : true if the parsed file is a svg |
||
36 |
* @return true on success, false otherwise |
||
37 |
*/ |
||
38 |
9 |
bool pxml_parserFile(PXml & xml, const std::string & fileName, bool isSvg){ |
|
39 |
✓ | 9 |
return pxml_parserContent(xml, getFileContent(fileName), isSvg); |
40 |
} |
||
41 |
|||
42 |
///Parse a PXml with a file content |
||
43 |
/** @param[out] xml : PXml to be initialised |
||
44 |
* @param fileContent : file content |
||
45 |
* @param isSvg : true if the parsed file is a svg |
||
46 |
* @return true on success, false otherwise |
||
47 |
*/ |
||
48 |
21 |
bool pxml_parserContent(PXml & xml, const std::string & fileContent, bool isSvg){ |
|
49 |
✓ | 42 |
PFileParser parser(pxml_setXmlParser(fileContent, isSvg)); |
50 |
✓✓ | 21 |
xml.setName("root"); |
51 |
|||
52 |
✓ | 42 |
return pxml_parserXmlContent(xml, parser, true); |
53 |
|||
54 |
// return pxml_parserVecXml(xml.getVecChild(), parser, isSvg); |
||
55 |
} |
||
56 |
|||
57 |
///Say if it is the end of the attribute definition of the current balise |
||
58 |
/** @param[out] parent : xml parent in wich to set the isCompact attribute |
||
59 |
* @param[out] parser : parser to be used |
||
60 |
* @return true if the attribute end is reached, false if not |
||
61 |
*/ |
||
62 |
83 |
bool pxml_isAttributeEnd(PXml & parent, PFileParser & parser){ |
|
63 |
✓✓✓✓ |
83 |
if(parser.isMatch("/>")){ |
64 |
1 |
parent.setIsCompact(true); |
|
65 |
1 |
return true; |
|
66 |
✓✓✓✓ |
82 |
}else if(parser.isMatch(">")){ |
67 |
72 |
parent.setIsCompact(false); |
|
68 |
72 |
return true; |
|
69 |
}else{ |
||
70 |
10 |
return false; |
|
71 |
} |
||
72 |
} |
||
73 |
|||
74 |
///Parse the attribute of a xml balise |
||
75 |
/** @param[out] parent : xml parent in wich to put the attribute |
||
76 |
* @param[out] parser : parser to be used |
||
77 |
* @return true on success, false otherwise |
||
78 |
*/ |
||
79 |
73 |
bool pxml_parserXmlAttribute(PXml & parent, PFileParser & parser){ |
|
80 |
✓✓ | 73 |
parser.setWhiteSpace(" \t\n"); |
81 |
✓✓✓✗ ✓✓ |
83 |
while(!pxml_isAttributeEnd(parent, parser) && !parser.isEndOfFile()){ |
82 |
✓✓ | 20 |
std::string attributeName(parser.getStrComposedOf(ALLOWED_ATTRIBUTE_CHAR)); |
83 |
✗✓ | 10 |
if(attributeName == ""){ |
84 |
std::cerr << "pxml_parserXmlAttribute : error at : " << parser.getLocation() << std::endl; |
||
85 |
std::cerr << "\tcannot parse the attributes name as '"<<parser.getNextToken()<<"'" << std::endl; |
||
86 |
return false; |
||
87 |
} |
||
88 |
✓✓✗✓ |
10 |
if(!parser.isMatch("=")){ |
89 |
std::cerr << "pxml_parserXmlAttribute : error at : " << parser.getLocation() << std::endl; |
||
90 |
std::cerr << "\texpected '=' after attribute '"<<attributeName<<"'" << std::endl; |
||
91 |
return false; |
||
92 |
} |
||
93 |
✓✓✗✓ |
10 |
if(!parser.isMatch("\"")){ |
94 |
std::cerr << "pxml_parserXmlAttribute : error at : " << parser.getLocation() << std::endl; |
||
95 |
std::cerr << "\texpected '\"' after attribute '"<<attributeName<<"='" << std::endl; |
||
96 |
return false; |
||
97 |
} |
||
98 |
✓✓ | 30 |
std::string attributeValue(parser.getUntilKeyWithoutPatern("\"")); |
99 |
✓ | 20 |
PXmlAttr tmpAttribute; |
100 |
✓ | 10 |
tmpAttribute.setName(attributeName); |
101 |
✓ | 10 |
tmpAttribute.setValue(attributeValue); |
102 |
✓✓ | 10 |
parent.getVecAttr().push_back(tmpAttribute); |
103 |
} |
||
104 |
✓✓ | 73 |
parser.setWhiteSpace(""); |
105 |
73 |
return true; |
|
106 |
} |
||
107 |
|||
108 |
|||
109 |
///Parse the content of an xml balise |
||
110 |
/** @param[out] parent : xml parent in wich to put the content |
||
111 |
* @param[out] parser : parser to be used |
||
112 |
* @param isMainBalise : true if the parent balise if the main one, false otherwise |
||
113 |
* @return true on success, false otherwise |
||
114 |
*/ |
||
115 |
93 |
bool pxml_parserXmlContent(PXml & parent, PFileParser & parser, bool isMainBalise){ |
|
116 |
✓✓ | 93 |
parser.setSeparator("<>\"="); |
117 |
✓✓ | 93 |
parser.setWhiteSpace(""); |
118 |
✓✓✓ | 186 |
std::string balisePartialEnd("/" + parent.getName() + ">"); |
119 |
✓ | 186 |
std::string baliseEnd("<" + balisePartialEnd); |
120 |
✓ | 186 |
PXml text; |
121 |
✓ | 93 |
text.setIsText(true); |
122 |
✓✓✓✓ ✓✓✓✓ |
167 |
while(!parser.isMatch(baliseEnd) && !parser.isEndOfFile()){ |
123 |
✓✓ | 306 |
std::string textString(parser.getUntilKeyWithoutPatern("<")); |
124 |
✓✓ | 153 |
if(textString != ""){ //If the next token is not a < it is a text |
125 |
✓✓ | 117 |
text.getValue() += textString; |
126 |
✓✓✓ | 117 |
if(parent.getVecChild().size() == 0lu){ |
127 |
✓✓✓ | 71 |
if(parser.isMatch(balisePartialEnd)){ |
128 |
✓✓ | 40 |
parent.setValue(text.getValue()); |
129 |
40 |
return true; |
|
130 |
}else{ |
||
131 |
✓✓ | 31 |
parent.getVecChild().push_back(text); |
132 |
} |
||
133 |
}else{ |
||
134 |
✓✓ | 46 |
parent.getVecChild().push_back(text); |
135 |
} |
||
136 |
✓✓ | 77 |
text.setValue(""); //Reset value for next one |
137 |
} |
||
138 |
✓✓✓ | 113 |
if(parser.isEndOfFile()){ |
139 |
✓✓ | 14 |
if(isMainBalise){ |
140 |
13 |
return true; |
|
141 |
}else{ |
||
142 |
✓✓✓✓ |
1 |
std::cerr << "pxml_parserXmlContent : error at : " << parser.getLocation() << std::endl; |
143 |
✓✓✓✓ ✓ |
1 |
std::cerr << "\tunexpected end of file. We are supposed to be in the balise '"<<parent.getName()<<"'" << std::endl; |
144 |
1 |
return false; |
|
145 |
} |
||
146 |
} |
||
147 |
✓✓✓ | 99 |
if(parser.isMatch(balisePartialEnd)){ //We find the end of the balise |
148 |
24 |
return true; |
|
149 |
}else{ //Or it can be another balise |
||
150 |
✓✓ | 150 |
std::string childBaliseName(parser.getStrComposedOf(ALLOWED_BALISE_CHAR)); |
151 |
✓✗ | 75 |
if(childBaliseName != ""){ //We find a new balise |
152 |
✓ | 75 |
PXml xml; |
153 |
✓ | 75 |
xml.setName(childBaliseName); |
154 |
✓✓ | 75 |
if(childBaliseName == "!--"){ |
155 |
✓✓ | 1 |
parser.getUntilKeyWithoutPatern("-->"); //Skip the comment |
156 |
✓✓ | 74 |
}else if(childBaliseName == "?xml"){ |
157 |
✓✓ | 1 |
parser.getUntilKeyWithoutPatern("?>"); //Skip the svg balise |
158 |
}else{ |
||
159 |
✓✗✓ | 73 |
if(!pxml_parserXmlAttribute(xml, parser)){ //Let's parse the attribute |
160 |
std::cerr << "pxml_parserXmlContent : error at : " << parser.getLocation() << std::endl; |
||
161 |
std::cerr << "\tcannot parse the attributes of balise '"<<childBaliseName<<"'" << std::endl; |
||
162 |
return false; |
||
163 |
} |
||
164 |
✓✓✓ | 73 |
if(!xml.getIsCompact()){ |
165 |
//Let's parse the content |
||
166 |
✓✓✓ | 72 |
if(!pxml_parserXmlContent(xml, parser, false)){ |
167 |
✓✓✓✓ |
1 |
std::cerr << "pxml_parserXmlContent : error at : " << parser.getLocation() << std::endl; |
168 |
✓✓✓✓ |
1 |
std::cerr << "\tcannot parse balise '"<<childBaliseName<<"'" << std::endl; |
169 |
1 |
return false; |
|
170 |
} |
||
171 |
} |
||
172 |
✓✓ | 72 |
parent.getVecChild().push_back(xml); |
173 |
} |
||
174 |
}else if(parser.isMatch("/")){ |
||
175 |
std::cerr << "pxml_parserXmlContent : in balise '"<<parent.getName()<<"' unexpected '</' at : " << parser.getLocation() << std::endl; |
||
176 |
return false; |
||
177 |
}else{ //It was just a text < |
||
178 |
text.getValue() += "<"; |
||
179 |
} |
||
180 |
} |
||
181 |
} |
||
182 |
14 |
return true; |
|
183 |
} |
||
184 |
|||
185 |
|||
186 |
|||
187 |
|||
188 |
|||
189 |
|||
190 |
|||
191 |
///Get the vector of childs with given name if exist |
||
192 |
/** @param[out] vecMatch : vector of matched childs |
||
193 |
* @param xml : xml input |
||
194 |
* @param childName : name of the searched childs |
||
195 |
* @return true if the childs exist, false otherwise |
||
196 |
*/ |
||
197 |
7 |
bool pxml_getVecChildIfExist(PVecXml & vecMatch, const PXml & xml, const std::string & childName){ |
|
198 |
7 |
bool isFound(false); |
|
199 |
7 |
const PVecXml & vecChild = xml.getVecChild(); |
|
200 |
✓✓ | 48 |
for(PVecXml::const_iterator it(vecChild.begin()); it != vecChild.end(); ++it){ |
201 |
✓✓✓ | 41 |
if(it->getName() == childName){ |
202 |
✓ | 17 |
vecMatch.push_back(*it); |
203 |
17 |
isFound = true; |
|
204 |
} |
||
205 |
} |
||
206 |
7 |
return isFound; |
|
207 |
} |
||
208 |
|||
209 |
///Get the child with given name if exist |
||
210 |
/** @param[out] match : matched child |
||
211 |
* @param xml : xml input |
||
212 |
* @param childName : name of the searched child |
||
213 |
* @return true if the child exist, false otherwise |
||
214 |
*/ |
||
215 |
11 |
bool pxml_getChildIfExist(PXml & match, const PXml & xml, const std::string & childName){ |
|
216 |
11 |
bool isSearched(true); |
|
217 |
✓ | 11 |
const PVecXml & vecChild = xml.getVecChild(); |
218 |
11 |
PVecXml::const_iterator it(vecChild.begin()); |
|
219 |
✓✓✓✗ ✓✓ |
29 |
while(it != vecChild.end() && isSearched){ |
220 |
✓✓✓ | 18 |
if(it->getName() == childName){ |
221 |
✓ | 2 |
match = *it; |
222 |
2 |
isSearched = false; |
|
223 |
} |
||
224 |
18 |
++it; |
|
225 |
} |
||
226 |
11 |
return !isSearched; |
|
227 |
} |
||
228 |
|||
229 |
///Get the child with given name if exist |
||
230 |
/** @param xml : xml input |
||
231 |
* @param childName : name of the searched child |
||
232 |
* @return pointer to the existing child, NULL otherwise |
||
233 |
*/ |
||
234 |
7 |
PXml * pxml_getChildPtr(PXml & xml, const std::string & childName){ |
|
235 |
7 |
PXml * out = NULL; |
|
236 |
7 |
PVecXml & vecChild = xml.getVecChild(); |
|
237 |
✓✗✓✓ ✓✓ |
14 |
for(PVecXml::iterator it(vecChild.begin()); it != vecChild.end() && out == NULL; ++it){ |
238 |
✓✓✗ | 7 |
if(it->getName() == childName){ |
239 |
7 |
out = &(*it); |
|
240 |
} |
||
241 |
} |
||
242 |
7 |
return out; |
|
243 |
} |
||
244 |
|||
245 |
///Get the attribute with given name if exist |
||
246 |
/** @param[out] attr : vector of matched child |
||
247 |
* @param xml : xml input |
||
248 |
* @param attrName : name of the searched child |
||
249 |
* @return true if the attribute exists, false otherwise |
||
250 |
*/ |
||
251 |
17 |
bool pxml_getAttrIfExist(PXmlAttr & attr, const PXml & xml, const std::string & attrName){ |
|
252 |
17 |
bool isSearched(true); |
|
253 |
✓ | 17 |
const PVecXmlAttr & vecAttr = xml.getVecAttr(); |
254 |
17 |
PVecXmlAttr::const_iterator it(vecAttr.begin()); |
|
255 |
✓✓✓✗ ✓✓ |
22 |
while(it != vecAttr.end() && isSearched){ |
256 |
✓✓✗ | 5 |
if(it->getName() == attrName){ |
257 |
✓ | 5 |
attr = *it; |
258 |
5 |
isSearched = false; |
|
259 |
} |
||
260 |
5 |
++it; |
|
261 |
} |
||
262 |
17 |
return !isSearched; |
|
263 |
} |
||
264 |
|||
265 |
///Set a value to an attribute |
||
266 |
/** @param[out] xml : xml to be modified |
||
267 |
* @param nameAttr : name of the attribute |
||
268 |
* @param valueAttr : value of the attribute |
||
269 |
*/ |
||
270 |
1 |
void pxml_setAttr(PXml & xml, const std::string & nameAttr, const std::string & valueAttr){ |
|
271 |
1 |
bool isSearched(true); |
|
272 |
✓ | 1 |
PVecXmlAttr & vecAttr = xml.getVecAttr(); |
273 |
1 |
PVecXmlAttr::iterator it(vecAttr.begin()); |
|
274 |
✗✓✗✗ ✗✓ |
1 |
while(it != vecAttr.end() && isSearched){ |
275 |
if(it->getName() == nameAttr){ |
||
276 |
it->setValue(valueAttr); |
||
277 |
isSearched = false; |
||
278 |
} |
||
279 |
++it; |
||
280 |
} |
||
281 |
1 |
} |
|
282 |
|||
283 |
///Erase the childs of the current xml if it has childName as name |
||
284 |
/** @param xml : current input |
||
285 |
* @param childName : name of the childs to be erased |
||
286 |
* @return output xml without childs named childName |
||
287 |
*/ |
||
288 |
1 |
PXml pxml_eraseVecChild(const PXml & xml, const std::string & childName){ |
|
289 |
1 |
PXml out; |
|
290 |
✓✓ | 1 |
out.setName(xml.getName()); |
291 |
✓✓ | 1 |
out.setValue(xml.getValue()); |
292 |
✓✓ | 1 |
out.setVecAttr(xml.getVecAttr()); |
293 |
✓ | 1 |
const PVecXml & vecXml = xml.getVecChild(); |
294 |
✓✓ | 7 |
for(PVecXml::const_iterator it(vecXml.begin()); it != vecXml.end(); ++it){ |
295 |
✓✗✓ | 6 |
if(it->getName() != childName){ |
296 |
out.getVecChild().push_back(*it); |
||
297 |
} |
||
298 |
} |
||
299 |
1 |
return out; |
|
300 |
} |
||
301 |
|||
302 |
///Save a xml in a file |
||
303 |
/** @param fileName : name of the output file |
||
304 |
* @param xml : xml to be saved |
||
305 |
* @param isSvg : say if the output xml has to be SVG like (with no space between chevron and newline between attribute |
||
306 |
* @return true on success, false otherwise |
||
307 |
*/ |
||
308 |
4 |
bool pxml_saveFile(const std::string & fileName, const PXml & xml, bool isSvg){ |
|
309 |
✓ | 8 |
std::string body(pxml_baliseStr(xml, isSvg)); |
310 |
✓ | 8 |
return saveFileContent(fileName, body); |
311 |
} |
||
312 |
|||
313 |
///Convert xml in string |
||
314 |
/** @param xml : xml to be converted into string |
||
315 |
* @param isSvg : say if the output xml has to be SVG like (with no space between chevron and newline between attribute |
||
316 |
* @return output string |
||
317 |
*/ |
||
318 |
157 |
std::string pxml_baliseStr(const PXml & xml, bool isSvg){ |
|
319 |
✓✓✓ | 471 |
std::string body(""), name(xml.getName()); |
320 |
✓ | 314 |
std::string baseXmlNewLine("\n"); |
321 |
✓✓ | 157 |
if(isSvg){ |
322 |
✓ | 23 |
baseXmlNewLine = ""; |
323 |
} |
||
324 |
✓✓✓ | 157 |
if(xml.getIsText()){ |
325 |
✓✓ | 69 |
body += xml.getValue(); |
326 |
}else{ |
||
327 |
✓✓ | 88 |
if(name != ""){ |
328 |
✓ | 84 |
body += "<"; |
329 |
✓ | 84 |
body += name; |
330 |
✓✓✓ | 84 |
body += pxml_vecAttrStr(xml.getVecAttr(), isSvg); |
331 |
|||
332 |
✗✓✗✗ |
84 |
if(name == "?xml"){body += " ?>\n";} |
333 |
✗✓✗✗ |
84 |
else if(name == "!--"){body += " -->\n";} |
334 |
✓✓✓ | 84 |
else if(xml.getIsCompact()){ |
335 |
✓✓ | 1 |
body += " />"+baseXmlNewLine; |
336 |
}else{ |
||
337 |
✓✓ | 83 |
body += ">"+baseXmlNewLine; |
338 |
✓✓✓ | 83 |
body += pxml_vecXmlStr(xml.getVecChild(), isSvg); |
339 |
✓✓ | 83 |
body += xml.getValue(); |
340 |
✓✓✓✓ |
83 |
body += "</"+ name + ">" + baseXmlNewLine; |
341 |
} |
||
342 |
}else{ |
||
343 |
|||
344 |
✓✓✓ | 4 |
body += pxml_vecXmlStr(xml.getVecChild(), isSvg); |
345 |
} |
||
346 |
} |
||
347 |
314 |
return body; |
|
348 |
} |
||
349 |
|||
350 |
///Convert a vecto of xml in string |
||
351 |
/** @param vecXml : vecor of xml to be converted into string |
||
352 |
* @param isSvg : say if the output xml has to be SVG like (with no space between chevron and newline between attribute |
||
353 |
* @return output string |
||
354 |
*/ |
||
355 |
94 |
std::string pxml_vecXmlStr(const PVecXml & vecXml, bool isSvg){ |
|
356 |
✓ | 94 |
std::string body(""); |
357 |
✓✓ | 234 |
for(PVecXml::const_iterator it(vecXml.begin()); it != vecXml.end(); ++it){ |
358 |
✓✓ | 140 |
body += pxml_baliseStr(*it, isSvg); |
359 |
} |
||
360 |
94 |
return body; |
|
361 |
} |
||
362 |
|||
363 |
///Convert attribute in string |
||
364 |
/** @param xmlAttr : xml attribute to be converted into string |
||
365 |
* @param isSvg : say if the output xml has to be SVG like (with no space between chevron and newline between attribute |
||
366 |
* @return output string |
||
367 |
*/ |
||
368 |
10 |
std::string pxml_attrStr(const PXmlAttr & xmlAttr, bool isSvg){ |
|
369 |
✓ | 10 |
std::string body(" "); |
370 |
✓✓✓✓ ✓✓ |
10 |
body += xmlAttr.getName() + "=\"" + xmlAttr.getValue() + "\""; |
371 |
✓✓ | 10 |
if(isSvg){ |
372 |
✓ | 3 |
body += "\n\t"; |
373 |
} |
||
374 |
10 |
return body; |
|
375 |
} |
||
376 |
|||
377 |
///Convert attributes in string |
||
378 |
/** @param vecXmlAttr : xml attributes to be converted into string |
||
379 |
* @param isSvg : say if the output xml has to be SVG like (with no space between chevron and newline between attribute |
||
380 |
* @return output string |
||
381 |
*/ |
||
382 |
84 |
std::string pxml_vecAttrStr(const PVecXmlAttr & vecXmlAttr, bool isSvg){ |
|
383 |
✓✓✓ | 84 |
if(vecXmlAttr.size() == 0lu){return "";} |
384 |
✓ | 20 |
std::string body(""); |
385 |
✓✓ | 20 |
for(PVecXmlAttr::const_iterator it(vecXmlAttr.begin()); it != vecXmlAttr.end(); ++it){ |
386 |
✓✓ | 10 |
body += pxml_attrStr(*it, isSvg); |
387 |
} |
||
388 |
10 |
return body; |
|
389 |
} |
||
390 |
|||
391 |
///Get the content of the PXml (children or value) |
||
392 |
/** @param xml : PXml to be used |
||
393 |
* @return content of the PXml (children or value) |
||
394 |
*/ |
||
395 |
58 |
std::string pxml_getFullContent(const PXml & xml){ |
|
396 |
58 |
const PVecXml & vecXml = xml.getVecChild(); |
|
397 |
✓✓ | 58 |
if(vecXml.size() != 0lu){ |
398 |
7 |
return pxml_vecXmlStr(vecXml); |
|
399 |
}else{ |
||
400 |
51 |
return xml.getValue(); |
|
401 |
} |
||
402 |
} |
||
403 |
|||
404 |
Generated by: GCOVR (Version 4.2) |