PhoenixFileParser  1.5.1
Set of tools to ease file parsing
Loading...
Searching...
No Matches
DicoValue.cpp
Go to the documentation of this file.
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
14
16
19 copyDicoValue(other);
20}
21
26
28
32 copyDicoValue(other);
33 return *this;
34}
35
37
40bool DicoValue::load(const PPath & fileName){
41 PFileParser parser;
42 if(!parser.open(fileName)){return false;}
43 return loadParser(parser);
44}
45
47
53bool DicoValue::save(const PPath & fileName, const PString & valueDecorator, PString baseIndentation, PString baseNewLine) const{
54 PString out(toString(valueDecorator, baseIndentation, baseNewLine));
55 return fileName.saveFileContent(out);
56}
57
59
62bool DicoValue::fromString(const PString & content){
63 PFileParser parser;
64 parser.setEscapeChar('\\');
65 parser.setFileContent(content);
66 return loadParser(parser);
67}
68
70
75PString DicoValue::toString(const PString & valueDecorator, PString baseIndentation, PString baseNewLine) const{
76 PString out(baseNewLine+"{");
77 out += saveRecurse(baseIndentation, valueDecorator, baseIndentation, baseNewLine);
78 out += baseNewLine+"}"+baseNewLine;
79 return out;
80}
81
83void DicoValue::print() const{
84 std::cout << "{" << std::endl;
85 std::cout << saveRecurse("\t", "\"", "\t", "\n") << std::endl;
86 std::cout << "}" << std::endl;
87}
88
90
92bool DicoValue::hasKey() const{return p_key != "";}
93
95
97bool DicoValue::hasMap() const{return p_mapChild.size() != 0lu;}
98
100
102bool DicoValue::hasVec() const{return p_vecChild.size() != 0lu;}
103
105
108bool DicoValue::isKeyExist(const PString & key) const{
109 std::map<PString, DicoValue>::const_iterator it(p_mapChild.find(key));
110 return it != p_mapChild.end();
111}
112
114
117const DicoValue * DicoValue::getMap(const PString & key) const{
118 std::map<PString, DicoValue>::const_iterator it(p_mapChild.find(key));
119 if(it != p_mapChild.end()){
120 return &(it->second);
121 }else{
122 return NULL;
123 }
124}
125
127
130const DicoValue * DicoValue::getMap(const PVecString & vecKey) const{
131 if(vecKey.size() == 0lu){return NULL;}
132 const DicoValue * tmpDico = this;
133 for(PVecString::const_iterator itAddress(vecKey.begin()); itAddress != vecKey.end() && tmpDico != NULL; ++itAddress){
134 if(tmpDico->hasMap()){
135 const DicoValue * key = tmpDico->getMap(*itAddress);
136 tmpDico = key;
137 }else{
138 tmpDico = NULL;
139 }
140 }
141 return tmpDico;
142}
143
145
149const 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
172
175DicoValue * DicoValue::getMap(const PString & key){
176 std::map<PString, DicoValue>::const_iterator it(p_mapChild.find(key));
177 if(it != p_mapChild.end()){
178 return (DicoValue *)&(it->second);
179 }else{
180 return NULL;
181 }
182}
183
185
187void DicoValue::setValue(const PString & value){
188 p_value = value;
189}
190
192
194void DicoValue::setKey(const PString & key){
195 p_key = key;
196}
197
199
201void DicoValue::setVecChild(const std::vector<DicoValue> & vecChild){
202 p_vecChild = vecChild;
203}
204
206
208void DicoValue::setMapChild(const std::map<PString, DicoValue> & mapChild){
209 p_mapChild = mapChild;
210}
211
213
215const PString & DicoValue::getValue() const{
216 return p_value;
217}
218
220
223 return p_value;
224}
225
227
229PString DicoValue::getString() const{
230 return p_value.eraseFirstLastChar("\"\'");
231}
232
234
236const PString & DicoValue::getKey() const{
237 return p_key;
238}
239
241
244 return p_key;
245}
246
248
250const std::vector<DicoValue> & DicoValue::getVecChild() const{
251 return p_vecChild;
252}
253
255
257std::vector<DicoValue> & DicoValue::getVecChild(){
258 return p_vecChild;
259}
260
262
264const std::map<PString, DicoValue> & DicoValue::getMapChild() const{
265 return p_mapChild;
266}
267
269
271std::map<PString, DicoValue> & DicoValue::getMapChild(){
272 return p_mapChild;
273}
274
276
279 p_value = other.p_value;
280 p_key = other.p_key;
281 p_vecChild = other.p_vecChild;
282 p_mapChild = other.p_mapChild;
283}
284
286
290 parser.setEscapeChar('\\');
291 parser.setWhiteSpace(" \t\n");
292 parser.setSeparator(",:{}\"");
293 bool isRunning(true);
294 while(!parser.isEndOfFile() && isRunning){
295 if(parseDicoValue(parser, isRunning)){
296 parser.skipWhiteSpace();
297 }else{
298 return errorAt(parser, isRunning, "Cannot parse dico value");
299 }
300 }
301 return isRunning;
302}
303
305
309bool DicoValue::parseDicoValue(PFileParser & parser, bool & isRunning){
310 if(parseListOrMap(parser, isRunning)){return true;}
311 else if(parseList(parser, isRunning)){return true;}
312 else{
313 PString nextKeyOrValue;
314 bool isParsingStrOk(parseString(nextKeyOrValue, parser));
315 if(nextKeyOrValue == ""){
316 nextKeyOrValue = parser.getStrComposedOf("abcdefghijklmnopqsrtuvwxyzABCDEFGHIJKLMNOPQSRTUVWXYZ0123456789._-+");
317 if(nextKeyOrValue == "" && !isParsingStrOk){
318 return errorAt(parser, isRunning,
319 "Expecting a string or a keywork composed of letters, number, underscore, slash or minus");
320 }
321 }
322 if(parser.isMatch(":")){ //It was a key for a dictionnary
323// std::cerr << "DicoValue::parseDicoValue : find key '"<<nextKeyOrValue<<"'" << std::endl;
324 p_key = nextKeyOrValue;
325 if(!parseDicoValue(parser, isRunning)){
326 return errorAt(parser, isRunning, "Cannot parse value");
327 }
328 }else{ //It was a value
329 p_value = nextKeyOrValue;
330 }
331 parser.skipWhiteSpace();
332 }
333 return true;
334}
335
337
341bool DicoValue::parseListOrMap(PFileParser & parser, bool & isRunning){
342 if(!parser.isMatch("{")){return false;} //If this is not a {, then it is not a list or a map
343 while(!parser.isEndOfFile() && !parser.isMatch("}") && isRunning){
344 DicoValue dv;
345 if(dv.parseDicoValue(parser, isRunning)){
346 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 p_mapChild[dv.p_key] = dv;
349 }else{ //It is a value
350 p_vecChild.push_back(dv);
351 }
352 }else{
353 return errorAt(parser, isRunning, "Cannot parse dico value");
354 }
355 if(parser.isMatch(",")){}
356 else if(parser.isMatchRewind("}")){}
357 else{
358 return errorAt(parser, isRunning, "Expect ',' or '}' after value");
359 }
360 }
361 return true;
362}
363
365
369bool DicoValue::parseList(PFileParser & parser, bool & isRunning){
370 if(!parser.isMatch("[")){return false;} //If this is not a {, then it is not a list or a map
371
372 while(!parser.isEndOfFile() && !parser.isMatch("]") && isRunning){
373 DicoValue dv;
374 if(dv.parseDicoValue(parser, isRunning)){
375 if(dv.p_key != ""){ //It is a dico entry
376// std::cerr << "DicoValue::parseListOrMap : loadParser add DicoValue with key '"<<dv.p_key<<"'" << std::endl;
377 p_mapChild[dv.p_key] = dv;
378 }else{ //It is a value
379 p_vecChild.push_back(dv);
380 }
381 }else{
382 return errorAt(parser, isRunning, "Cannot parse list value");
383 }
384 if(parser.isMatch(",")){}
385 else if(parser.isMatchRewind("]")){}
386 else{
387 return errorAt(parser, isRunning, "Expect ',' or ']' after value");
388 }
389 }
390
391 return true;
392}
393
395
399bool DicoValue::parseString(PString & parsedString, PFileParser & parser){
400 if(parser.isMatch("\"")){
401 parsedString = parser.getUntilKeyWithoutPatern("\"");
402 return true;
403 }else if(parser.isMatch("'")){
404 parsedString = parser.getUntilKeyWithoutPatern("'");
405 return true;
406 }else{
407 parsedString = "";
408 return false;
409 }
410}
411
413
418bool DicoValue::errorAt(PFileParser & parser, bool & isRunning, const PString & errorMsg){
419 isRunning = false;
420 std::cerr << "DicoValue::errorAt : " << parser.getLocation() << std::endl;
421 std::cerr << "\t" << errorMsg << std::endl;
422 std::cerr << "Wrong token : '"<<parser.getNextToken()<<"'" << std::endl;
423 return true;
424}
425
427
434PString DicoValue::saveRecurse(const PString & indentation, const PString & valueDecorator, PString baseIndentation, PString baseNewLine, bool isInList) const{
435 PString out(""), newIndentation(indentation);
436 if(p_key != "" || isInList){
437 newIndentation = indentation + baseIndentation;
438 }
439 if(p_mapChild.size() != 0lu){
440 if(p_key != ""){out += baseNewLine + indentation +valueDecorator + p_key + valueDecorator + ": {";}
441 else if(isInList){out += baseNewLine+indentation+"{";}
442 PString comma("");
443 for(MapDicoValue::const_iterator it(p_mapChild.begin()); it != p_mapChild.end(); ++it){
444 out += comma;
445 out += it->second.saveRecurse(newIndentation, valueDecorator, baseIndentation, baseNewLine);
446 comma = ",";
447 }
448 if(p_key != ""){out += baseNewLine+indentation+"}";}
449 else if(isInList){out += baseNewLine+indentation+"}";}
450 }else if(p_vecChild.size() != 0lu){
451 if(p_key != ""){out += baseNewLine + indentation + valueDecorator + p_key + valueDecorator + ": [";}
452 PString comma("");
453 for(VecDicoValue::const_iterator it(p_vecChild.begin()); it != p_vecChild.end(); ++it){
454 out += comma;
455 out += it->saveRecurse(newIndentation, valueDecorator, baseIndentation, baseNewLine, true);
456 comma = ", ";
457 }
458 if(p_key != ""){out += "]";}
459 }else{
460 PString valueToSave(p_value);
461 if(valueDecorator != ""){
462 valueToSave = valueDecorator + p_value + valueDecorator;
463 }else if(p_value.find(" \t\n':/")){
464 valueToSave = "\"" + p_value + "\"";
465 }
466 if(p_key != ""){out += baseNewLine + indentation + valueDecorator + p_key + valueDecorator + ": "+valueToSave;}
467 else{out += valueToSave;}
468 }
469 return out;
470}
471
472
void setVecChild(const std::vector< DicoValue > &vecChild)
Sets the vecChild of the DicoValue.
PString toString(const PString &valueDecorator="", PString baseIndentation="\t", PString baseNewLine="\n") const
Convert the DicoValue into a string.
Definition DicoValue.cpp:75
const PString & getKey() const
Gets the key of the DicoValue.
bool isKeyExist(const PString &key) const
Say if the given key exists in the map of children.
PString p_value
Value of the current entry.
Definition DicoValue.h:70
void copyDicoValue(const DicoValue &other)
Copy Function of class DicoValue.
void setKey(const PString &key)
Sets the key of the DicoValue.
bool parseListOrMap(PFileParser &parser, bool &isRunning)
Parse a list or a map.
bool fromString(const PString &content)
Create a DicoValue from a PString.
Definition DicoValue.cpp:62
bool hasKey() const
Say if the DicoValue has a key.
Definition DicoValue.cpp:92
const std::vector< DicoValue > & getVecChild() const
Gets the vecChild of the DicoValue.
DicoValue & operator=(const DicoValue &other)
Operator = of class DicoValue.
Definition DicoValue.cpp:31
virtual ~DicoValue()
Destructor of class DicoValue.
Definition DicoValue.cpp:23
const DicoValue * getMap(const PString &key) const
Get a DicoValue in the map of the current one.
bool save(const PPath &fileName, const PString &valueDecorator="", PString baseIndentation="\t", PString baseNewLine="\n") const
Save the DicoValue with a text file.
Definition DicoValue.cpp:53
void setValue(const PString &value)
Sets the value of the DicoValue.
bool hasMap() const
Say if the DicoValue has a map of children.
Definition DicoValue.cpp:97
void print() const
Print the DicoValue.
Definition DicoValue.cpp:83
PString p_key
Key of the current entry.
Definition DicoValue.h:72
DicoValue()
Constructor of class DicoValue.
Definition DicoValue.cpp:11
std::map< PString, DicoValue > p_mapChild
Map of sub DicoValue.
Definition DicoValue.h:76
const std::map< PString, DicoValue > & getMapChild() const
Gets the mapChild of the DicoValue.
std::vector< DicoValue > p_vecChild
Vector of sub DicoValue.
Definition DicoValue.h:74
T getValue() const
Convert the value of the current DicoValue into a type.
bool parseDicoValue(PFileParser &parser, bool &isRunning)
Parse a DicoValue with a text file.
bool parseString(PString &parsedString, PFileParser &parser)
Parse a string.
bool loadParser(PFileParser &parser)
Load the DicoValue with a parser.
bool errorAt(PFileParser &parser, bool &isRunning, const PString &errorMsg)
Print the parsing error.
PString getString() const
Get a string value without the first and/or last quote or double quote in there are some.
PString saveRecurse(const PString &indentation, const PString &valueDecorator, PString baseIndentation, PString baseNewLine, bool isInList=false) const
Save the DicoValue with a text file.
bool load(const PPath &fileName)
Load the DicoValue with a text file.
Definition DicoValue.cpp:40
const DicoValue * getElementInVecWhere(const PString &key, const PString &value) const
Get the element of a vector of children of the current DicoValue which has 'key'.value = value.
void setMapChild(const std::map< PString, DicoValue > &mapChild)
Sets the mapChild of the DicoValue.
bool hasVec() const
Say if the DicoValue has a vector of children.
bool parseList(PFileParser &parser, bool &isRunning)
Parse a list or a map.
classe qui permet de parser des fichiers texte en renvoyant les tokens les uns après les autres
Definition PFileParser.h:20
void setSeparator(const PString &separator)
Initialise la liste des caractères séparateurs.
bool open(const PPath &fileName)
Fonction qui ouvre le fichier que l'on va parser.
PString getNextToken()
Get the next token.
PString getUntilKeyWithoutPatern(const PString &patern)
Renvoie la chaine de caractère du caractère courant jusqu'à patern exclu.
void setEscapeChar(char escapeChar)
Sets the escape character of the PFileParser.
PString getStrComposedOf(const PString &charset)
Get string composed of the characters in the string charset.
void setWhiteSpace(const PString &whiteSpace)
Initialise la liste des caractères blancs.
bool isMatchRewind(const PString &patern)
Do a isMatch and then go back at the previous position.
bool isMatch(const PString &patern)
Says if the patern match with the current caracters of the PFileParser.
PLocation getLocation() const
Fonction qui renvoie la PLocation du PFileParser.
void skipWhiteSpace()
Skip the white space if there is at the current caracter position.
void setFileContent(const PString &fileContent)
Set the file content.
bool isEndOfFile() const
Dit si on est à la fin du fichier.