PhoenixFileParser  1.5.1
Set of tools to ease file parsing
Loading...
Searching...
No Matches
parser_json.cpp File Reference
#include "parse_generic_string.h"
#include "parser_json.h"
+ Include dependency graph for parser_json.cpp:

Go to the source code of this file.

Classes

struct  PJsonParserData
 Data used to parse a toml file. More...
 

Functions

bool parser_json (ConfigNode &main, const PPath &fileName)
 Load a JSON file.
 
bool parser_json_fileParser (ConfigNode &node, PJsonParserData &data)
 Parse a json file.
 
bool parser_json_key (ConfigNode &node, PJsonParserData &data)
 Parse a json.
 
bool parser_json_list (ConfigNode &node, PJsonParserData &data)
 Parse a json.
 
bool parser_json_map (ConfigNode &node, PJsonParserData &data)
 Parse a json.
 
bool parser_json_value (ConfigNode &node, PJsonParserData &data)
 Parse a json.
 
bool parser_json_value (PString &value, PJsonParserData &data)
 Parse a json.
 
bool parser_jsonErrorAt (PJsonParserData &data, const PString &errorMsg)
 Print the parsing error.
 
bool parser_jsonString (ConfigNode &main, const PString &fileContent)
 Load a JSON string.
 
bool parser_jsonString (PString &str, PJsonParserData &data)
 Parse a JSON string.
 
PString toJsonSaveRecurse (const ConfigNode &node, const PString &indentation, const PString &baseIndentation, const PString &baseNewLine, bool isInList)
 Convert the ConfigNode in a PString.
 
PString toJsonString (const ConfigNode &main, const PString &baseIndentation, const PString &baseNewLine)
 Convert the current ConfigNode to a JSON string.
 

Function Documentation

◆ parser_json()

bool parser_json ( ConfigNode & main,
const PPath & fileName )

Load a JSON file.

Parameters
[out]main: ConfigNode to be updated
fileName: name of the file to be loaded
Returns
true on success, false otherwise

Definition at line 219 of file parser_json.cpp.

219 {
220 PJsonParserData data;
221 PFileParser & parser = data.parser;
222 parser.setWhiteSpace(" \n\t");
223 parser.setSeparator(":-'\",{}[]>|");
224 parser.setEscapeChar('\\');
225 if(!parser.open(fileName)){
226 std::cerr << "parser_json : cannot open file '"<<fileName<<"'" << std::endl;
227 return false;
228 }
229 main.setFileName(fileName);
230 bool b(parser_json_fileParser(main, data));
231 return b;
232}
void setFileName(const PPath &fileName)
Set the fileName of the current ConfigNode.
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.
void setEscapeChar(char escapeChar)
Sets the escape character of the PFileParser.
void setWhiteSpace(const PString &whiteSpace)
Initialise la liste des caractères blancs.
bool parser_json_fileParser(ConfigNode &node, PJsonParserData &data)
Parse a json file.
Data used to parse a toml file.
PFileParser parser
File parser to be used.

References PFileParser::open(), PJsonParserData::parser, parser_json_fileParser(), PFileParser::setEscapeChar(), ConfigNode::setFileName(), PFileParser::setSeparator(), and PFileParser::setWhiteSpace().

+ Here is the call graph for this function:

◆ parser_json_fileParser()

bool parser_json_fileParser ( ConfigNode & node,
PJsonParserData & data )

Parse a json file.

Parameters
[out]node: ConfigNode of values
data: PJsonParserData to be used
Returns
true on success, false otherwise

Definition at line 182 of file parser_json.cpp.

182 {
183 PFileParser & parser = data.parser;
184 parser.getStrComposedOf(" \t\n"); //Skip all blank characters
185 if(!parser.isMatch("{")){ //It has to start as JSON
186 return !parser_jsonErrorAt(data, "JSON configuration has to start with a {");
187 }
188 node.setLineCol(data.parser.getLocation());
189 //Call the Node Parsing
190 //Map or list or value or set of keys
191 if(parser_json_map(node, data)){}
192 else if(parser_json_list(node, data)){}
193 else if(parser_json_value(node, data)){}
194 else{
195 while(!parser.isEndOfFile() && !parser.isMatchRewind("}") && data.isRun){
196 //key:Map or key:list or key:value
197 if(!parser_json_key(node, data)){
198 return !parser_jsonErrorAt(data, "Expect \"key\"");
199 }
200 if(parser.isMatch(",")){}
201 else if(parser.isMatchRewind("}")){}
202 else{
203 return !parser_jsonErrorAt(data, "Expect ',' or '}' after key");
204 }
205 }
206 }
207
208 if(!parser.isMatch("}")){ //It has to start as JSON
209 return !parser_jsonErrorAt(data, "JSON configuration has to end with a }");
210 }
211 return data.isRun;
212}
void setLineCol(const PLocation &location)
Set the line and the column of the current ConfigNode.
PString getStrComposedOf(const PString &charset)
Get string composed of the characters in the string charset.
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.
bool isEndOfFile() const
Dit si on est à la fin du fichier.
bool parser_jsonErrorAt(PJsonParserData &data, const PString &errorMsg)
Print the parsing error.
bool parser_json_value(PString &value, PJsonParserData &data)
Parse a json.
bool parser_json_key(ConfigNode &node, PJsonParserData &data)
Parse a json.
bool parser_json_map(ConfigNode &node, PJsonParserData &data)
Parse a json.
bool parser_json_list(ConfigNode &node, PJsonParserData &data)
Parse a json.
bool isRun
True to continue the parsing, false to stop.

References PFileParser::getLocation(), PFileParser::getStrComposedOf(), PFileParser::isEndOfFile(), PFileParser::isMatch(), PFileParser::isMatchRewind(), PJsonParserData::isRun, PJsonParserData::parser, parser_json_key(), parser_json_list(), parser_json_map(), parser_json_value(), parser_jsonErrorAt(), and ConfigNode::setLineCol().

Referenced by parser_json(), and parser_jsonString().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parser_json_key()

bool parser_json_key ( ConfigNode & node,
PJsonParserData & data )

Parse a json.

Parameters
[out]node: ConfigNode of values
data: PJsonParserData to be used
Returns
true on success, false otherwise

Definition at line 93 of file parser_json.cpp.

93 {
94 PString key;
95 if(parser_jsonString(key, data)){
96 ConfigNode * child = node.addChild(key);
97 if(child == NULL){ //If the child is NULL, there is already a child named key
98 ConfigNode * prevChild = node.getChild(key.eraseFirstLastChar("\"'"));
99 std::stringstream location;
100 if(prevChild != NULL){
101 location << prevChild->getLocation();
102 }
103 return parser_jsonErrorAt(data, "key '"+key+"' already defined at " + location.str());
104 }
105 if(data.parser.isMatch(":")){
106 child->setLineCol(data.parser.getLocation());
107 //Let's parse the value of this child (map or list or value)
108 if(parser_json_map(*child, data)){}
109 else if(parser_json_list(*child, data)){}
110 else if(parser_json_value(*child, data)){}
111 else{
112 return parser_jsonErrorAt(data, "Cannot parse json value of key '"+key+"'");
113 }
114 return data.isRun;
115 }else{
116 return parser_jsonErrorAt(data, "Expect ':' after key '"+key+"'");
117 }
118 }else{
119 return parser_jsonErrorAt(data, "Expect \"key\"': ...");
120 }
121 return false;
122}
Configuration of values.
Definition ConfigNode.h:18
PLocation getLocation() const
Gets the location of the ConfigNode.
ConfigNode * addChild(const PString &name="")
Add a child in the current ConfigNode.
ConfigNode * getChild(const PString &name)
Get the child of the given name.
bool parser_jsonString(PString &str, PJsonParserData &data)
Parse a JSON string.

References ConfigNode::addChild(), ConfigNode::getChild(), ConfigNode::getLocation(), PFileParser::getLocation(), PFileParser::isMatch(), PJsonParserData::isRun, PJsonParserData::parser, parser_json_list(), parser_json_map(), parser_json_value(), parser_jsonErrorAt(), parser_jsonString(), and ConfigNode::setLineCol().

Referenced by parser_json_fileParser(), and parser_json_map().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parser_json_list()

bool parser_json_list ( ConfigNode & node,
PJsonParserData & data )

Parse a json.

Parameters
[out]node: ConfigNode of values
data: PJsonParserData to be used
Returns
true on success, false otherwise

Definition at line 152 of file parser_json.cpp.

152 {
153 PFileParser & parser = data.parser;
154 if(!parser.isMatch("[")){return false;}
155 node.setLineCol(parser.getLocation());
156 while(!parser.isEndOfFile() && !parser.isMatch("]") && data.isRun){
157 // On crée un enfant anonyme pour chaque élément du tableau
158 ConfigNode * child = node.addChild("");
159 if(parser_json_map(*child, data)){}
160 else if(parser_json_list(*child, data)){}
161 else{
162 PString value;
163 if(parser_json_value(value, data)){
164 child->setValue(value);
165 child->setLineCol(data.parser.getLocation());
166 }
167 }
168 if(parser.isMatch(",")){}
169 else if(parser.isMatchRewind("]")){}
170 else{
171 return parser_jsonErrorAt(data, "Expect ',' or ']' after value");
172 }
173 }
174 return data.isRun;
175}
void setValue(const PString &value)
Sets the value of the ConfigNode.

References ConfigNode::addChild(), PFileParser::getLocation(), PFileParser::isEndOfFile(), PFileParser::isMatch(), PFileParser::isMatchRewind(), PJsonParserData::isRun, PJsonParserData::parser, parser_json_list(), parser_json_map(), parser_json_value(), parser_jsonErrorAt(), ConfigNode::setLineCol(), and ConfigNode::setValue().

Referenced by parser_json_fileParser(), parser_json_key(), and parser_json_list().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parser_json_map()

bool parser_json_map ( ConfigNode & node,
PJsonParserData & data )

Parse a json.

Parameters
[out]node: ConfigNode of values
data: PJsonParserData to be used
Returns
true on success, false otherwise

Definition at line 129 of file parser_json.cpp.

129 {
130 PFileParser & parser = data.parser;
131 if(!parser.isMatch("{")){return false;}
132 node.setLineCol(parser.getLocation());
133 while(!parser.isEndOfFile() && !parser.isMatch("}") && data.isRun){
134 //key:Map or key:list or key:value
135 if(!parser_json_key(node, data)){
136 return parser_jsonErrorAt(data, "Expect \"key\"");
137 }
138 if(parser.isMatch(",")){}
139 else if(parser.isMatchRewind("}")){}
140 else{
141 return parser_jsonErrorAt(data, "Expect ',' or '}' after key");
142 }
143 }
144 return data.isRun;
145}

References PFileParser::getLocation(), PFileParser::isEndOfFile(), PFileParser::isMatch(), PFileParser::isMatchRewind(), PJsonParserData::isRun, PJsonParserData::parser, parser_json_key(), parser_jsonErrorAt(), and ConfigNode::setLineCol().

Referenced by parser_json_fileParser(), parser_json_key(), and parser_json_list().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parser_json_value() [1/2]

bool parser_json_value ( ConfigNode & node,
PJsonParserData & data )

Parse a json.

Parameters
[out]node: ConfigNode of values
data: PJsonParserData to be used
Returns
true on success, false otherwise

Definition at line 78 of file parser_json.cpp.

78 {
79 PString value;
80 if(parser_json_value(value, data)){
81 node.setValue(value);
82 node.setLineCol(data.parser.getLocation());
83 return true;
84 }
85 return false;
86}

References PFileParser::getLocation(), PJsonParserData::parser, parser_json_value(), ConfigNode::setLineCol(), and ConfigNode::setValue().

+ Here is the call graph for this function:

◆ parser_json_value() [2/2]

bool parser_json_value ( PString & value,
PJsonParserData & data )

Parse a json.

Parameters
[out]node: ConfigNode of values
data: PJsonParserData to be used
Returns
true on success, false otherwise

Definition at line 54 of file parser_json.cpp.

54 {
55 PFileParser & parser = data.parser;
56 parser.pushPosition();
57 if(!parser_jsonString(value, data)){
58 value = parser.getStrComposedOf("abcdefghijklmnopqsrtuvwxyzABCDEFGHIJKLMNOPQSRTUVWXYZ0123456789._-+");
59 if(value == ""){
60 parser.popPosition();
61 parser.clearPosition();
62 return false;
63 }
64 }
65 if(parser.isMatchRewind(":")){
66 parser.popPosition();
67 return false;
68 }
69 parser.clearPosition();
70 return true;
71}
void popPosition()
Get to the last saved position of the PFileParser in the current file.
void clearPosition()
Clear the save position of the parser in ther current file.
void pushPosition()
Remember the current position of the PFileParser in the current file.

References PFileParser::clearPosition(), PFileParser::getStrComposedOf(), PFileParser::isMatchRewind(), PJsonParserData::parser, parser_jsonString(), PFileParser::popPosition(), and PFileParser::pushPosition().

Referenced by parser_json_fileParser(), parser_json_key(), parser_json_list(), and parser_json_value().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parser_jsonErrorAt()

bool parser_jsonErrorAt ( PJsonParserData & data,
const PString & errorMsg )

Print the parsing error.

Parameters
[out]parser: parser to be used
[out]isRunning: true to continue the parsing, false to stop it
errorMsg: error message
Returns
true and stop the parsing with isRunning

Definition at line 27 of file parser_json.cpp.

27 {
28 data.isRun = false;
29 std::cerr << "parser_jsonErrorAt : " << data.parser.getLocation() << std::endl;
30 std::cerr << "\t" << errorMsg << std::endl;
31 std::cerr << "Wrong token : '"<<data.parser.getNextToken()<<"'" << std::endl;
32 return true;
33}
PString getNextToken()
Get the next token.

References PFileParser::getLocation(), PFileParser::getNextToken(), PJsonParserData::isRun, and PJsonParserData::parser.

Referenced by parser_json_fileParser(), parser_json_key(), parser_json_list(), and parser_json_map().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parser_jsonString() [1/2]

bool parser_jsonString ( ConfigNode & main,
const PString & fileContent )

Load a JSON string.

Parameters
[out]main: ConfigNode to be updated
fileContent: string to be loaded
Returns
true on success, false otherwise

Definition at line 239 of file parser_json.cpp.

239 {
240 PJsonParserData data;
241 PFileParser & parser = data.parser;
242 parser.setWhiteSpace(" \n\t");
243 parser.setSeparator(":-'\",{}[]>|");
244 parser.setEscapeChar('\\');
245 parser.setFileContent(fileContent);
246 bool b(parser_json_fileParser(main, data));
247 return b;
248}
void setFileContent(const PString &fileContent)
Set the file content.

References PJsonParserData::parser, parser_json_fileParser(), PFileParser::setEscapeChar(), PFileParser::setFileContent(), PFileParser::setSeparator(), and PFileParser::setWhiteSpace().

+ Here is the call graph for this function:

◆ parser_jsonString() [2/2]

bool parser_jsonString ( PString & str,
PJsonParserData & data )

Parse a JSON string.

Parameters
[out]str: parsed string
[out]data: parsing data
Returns
true on success, false otherwise

Definition at line 40 of file parser_json.cpp.

40 {
41 if(data.parser.isMatch("\"")){
42 str = "\"" + data.parser.getUntilKey("\"");
43 return true;
44 }
45 return false;
46}
PString getUntilKey(const PString &patern)
Renvoie la chaine de caractère du caractère courant jusqu'à patern comprise.

References PFileParser::getUntilKey(), PFileParser::isMatch(), and PJsonParserData::parser.

Referenced by parser_json_key(), and parser_json_value().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ toJsonSaveRecurse()

PString toJsonSaveRecurse ( const ConfigNode & node,
const PString & indentation,
const PString & baseIndentation,
const PString & baseNewLine,
bool isInList )

Convert the ConfigNode in a PString.

Parameters
node: ConfigNode to be saved
indentation: indentation of the current ConfigNode
baseIndentation: indentation character(s) to be used
baseNewLine: new line character(s) to be used
isInList: true if the dico value is in a list
Returns
file content

Definition at line 259 of file parser_json.cpp.

259 {
260 PString out(""), newIndentation(indentation);
261 const PString & name = node.getName();
262 if(name != "" || isInList){
263 newIndentation = indentation + baseIndentation;
264 }
265 const VecConfigNode & vecChild = node.getVecChild();
266 const MapConfigNode & mapChild = node.getMapChild();
267 if(mapChild.size() != 0lu){
268 if(name != ""){out += baseNewLine + indentation + name.addPrefixSuffix("\"","\"") + ": {";}
269 else if(isInList){out += baseNewLine+indentation+"{";}
270 PString comma("");
271 for(VecConfigNode::const_iterator it(vecChild.begin()); it != vecChild.end(); ++it){
272 out += comma;
273 out += toJsonSaveRecurse(**it, newIndentation, baseIndentation, baseNewLine, false);
274 comma = ",";
275 }
276 if(name != ""){out += baseNewLine+indentation+"}";}
277 else if(isInList){out += baseNewLine+indentation+"}";}
278 }else if(vecChild.size() != 0lu){
279 if(name != ""){out += baseNewLine + indentation + name.addPrefixSuffix("\"","\"") + ": [";}
280 PString comma("");
281 for(VecConfigNode::const_iterator it(vecChild.begin()); it != vecChild.end(); ++it){
282 out += comma;
283 out += toJsonSaveRecurse(**it, newIndentation, baseIndentation, baseNewLine, true);
284 comma = ", ";
285 }
286 if(name != ""){out += "]";}
287 }else{
288 if(name != ""){out += baseNewLine + indentation + name.addPrefixSuffix("\"","\"") + ": " + node.getValue().addPrefixSuffix("\"","\"");}
289 else{out += node.getValue().addPrefixSuffix("\"","\"");}
290 }
291 return out;
292}
std::vector< ConfigNode * > VecConfigNode
Definition ConfigNode.h:74
std::map< PString, ConfigNode * > MapConfigNode
Definition ConfigNode.h:75
const PString & getValue() const
Gets the value of the ConfigNode.
const PString & getName() const
Gets the name of the ConfigNode.
const std::vector< ConfigNode * > & getVecChild() const
Gets the vecChild of the ConfigNode.
const std::map< PString, ConfigNode * > & getMapChild() const
Gets the mapChild of the ConfigNode.
PString toJsonSaveRecurse(const ConfigNode &node, const PString &indentation, const PString &baseIndentation, const PString &baseNewLine, bool isInList)
Convert the ConfigNode in a PString.

References ConfigNode::getMapChild(), ConfigNode::getName(), ConfigNode::getValue(), ConfigNode::getVecChild(), and toJsonSaveRecurse().

Referenced by toJsonSaveRecurse(), and toJsonString().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ toJsonString()

PString toJsonString ( const ConfigNode & main,
const PString & baseIndentation,
const PString & baseNewLine )

Convert the current ConfigNode to a JSON string.

Parameters
main: ConfigNode to be converted
baseIndentation: indentation to be used
baseNewLine: new line to be used
Returns
corresponding PString

Definition at line 300 of file parser_json.cpp.

300 {
301 PString out("{");
302 out += toJsonSaveRecurse(main, baseIndentation, baseIndentation, baseNewLine, false);
303 out += baseNewLine + "}";
304 return out;
305}

References toJsonSaveRecurse().

+ Here is the call graph for this function: