@@ -109,7 +109,9 @@ YAMLParser::~YAMLParser()
109109{
110110 yaml_parser_delete (&_parser);
111111 yaml_emitter_delete (&_emitter);
112- yaml_document_delete (&_document);
112+ #if !defined ESP8266 // TODO: fix mem leak with esp8266
113+ yaml_document_delete (&_document);
114+ #endif
113115}
114116
115117
@@ -219,63 +221,60 @@ void YAMLParser::handle_emitter_error(yaml_emitter_t *e)
219221
220222#if defined HAS_ARDUINOJSON
221223
224+
222225 // yaml_node_t deconstructor => JsonObject
223226 void deserializeYml_JsonObject ( yaml_document_t * document, yaml_node_t * yamlNode, JsonObject &jsonNode, YAMLParser::JNestingType_t nt, const char *nodename, int depth )
224227 {
225- // Prevent "use after free" situations in JsonObject key
226- // ArduinoJson only aliases const char* so use char* to force a copy
227- char * _nodename = (char *)malloc ( strlen (nodename)+1 );
228- strcpy (_nodename, nodename);
229-
230228 switch (yamlNode->type ) {
231- case YAML_NO_NODE: /* YAML_LOG_v("YAML_NO_NODE");*/ break ;
232229 case YAML_SCALAR_NODE:
233230 {
234231 double number;
235232 char * scalar;
236233 char * end;
237- bool is_string;
238234 scalar = (char *)yamlNode->data .scalar .value ;
239235 number = strtod (scalar, &end);
240- is_string = (end == scalar || *end);
236+ bool is_string = (end == scalar || *end);
241237 switch ( nt ) {
242238 case YAMLParser::SEQ_KEY:
243239 {
244- if (is_string) jsonNode[_nodename].add ( scalar );
245- else jsonNode[_nodename].add ( number );
240+ JsonArray array = jsonNode[nodename];
241+ if (is_string) array.add ( scalar );
242+ else array.add ( number );
243+ // YAML_LOG_d("[SEQ][%s][%d] => %s(%s)", nodename, array.size()-1, is_string?"string":"number", is_string?scalar:String(number).c_str() );
246244 }
247245 break ;
248246 case YAMLParser::MAP_KEY:
249- if (is_string) jsonNode[_nodename] = scalar;
250- else jsonNode[_nodename] = number;
247+ if (is_string) jsonNode[nodename] = scalar;
248+ else jsonNode[nodename] = number;
249+ // YAML_LOG_d("[MAP][%d][%s] => %s(%s)", jsonNode.size()-1, nodename, is_string?"string":"number", is_string?scalar:String(number).c_str() );
251250 break ;
252251 default : YAML_LOG_e (" Error invalid nesting type" ); break ;
253252 }
254253 }
255254 break ;
256255 case YAML_SEQUENCE_NODE:
257256 {
258- jsonNode.createNestedArray (_nodename );
257+ JsonArray tmpArray = jsonNode.createNestedArray (nodename );
259258 yaml_node_item_t * item_i;
259+ yaml_node_t *itemNode;
260+ String _nodename;
260261 for (item_i = yamlNode->data .sequence .items .start ; item_i < yamlNode->data .sequence .items .top ; ++item_i) {
261- yaml_node_t * itemNode = yaml_document_get_node (document, *item_i);
262+ itemNode = yaml_document_get_node (document, *item_i);
262263 if ( itemNode->type == YAML_MAPPING_NODE ) { // array of anonymous objects
263- JsonObject tmpObj = jsonNode[_nodename].createNestedObject (); // insert empty nested object
264- deserializeYml_JsonObject ( document, itemNode, tmpObj, YAMLParser::SEQ_KEY, " root" , depth+1 ); // go recursive using temporary node name
265- jsonNode[_nodename][jsonNode[_nodename].size ()-1 ].set ( tmpObj[" root" ] ); // remove temporary name and make object anonymous
264+ JsonObject tmpObj = tmpArray.createNestedObject (); // insert empty nested object
265+ _nodename = ROOT_NODE + String ( nodename ) + String ( tmpArray.size () ); // generate a temporary nodename
266+ deserializeYml_JsonObject ( document, itemNode, tmpObj, YAMLParser::SEQ_KEY, _nodename.c_str (), depth+1 ); // go recursive using temporary node name
267+ jsonNode[nodename][tmpArray.size ()-1 ] = tmpObj[_nodename]; // remove temporary name and make object anonymous
266268 } else { // array of sequences or values
267- deserializeYml_JsonObject ( document, itemNode, jsonNode, YAMLParser::SEQ_KEY, _nodename , depth+1 );
269+ deserializeYml_JsonObject ( document, itemNode, jsonNode, YAMLParser::SEQ_KEY, nodename , depth+1 );
268270 }
269271 }
272+ // YAML_LOG_d("[ARR][%s] has %d items", nodename, tmpArray.size() );
270273 }
271274 break ;
272275 case YAML_MAPPING_NODE:
273276 {
274- jsonNode.createNestedObject (_nodename);
275- JsonObject tmpObj = jsonNode[_nodename];
276- if ( nt == YAMLParser::NONE ) {
277- jsonNode = tmpObj; // topmost object, nodename is empty so apply reparenting
278- }
277+ JsonObject tmpNode = jsonNode.createNestedObject (nodename);
279278 yaml_node_pair_t * pair_i;
280279 yaml_node_t * key;
281280 yaml_node_t * value;
@@ -286,18 +285,20 @@ void YAMLParser::handle_emitter_error(yaml_emitter_t *e)
286285 YAML_LOG_w (" Mapping key is not scalar (line %lu, val=%s)." , key->start_mark .line , (const char *)value->data .scalar .value );
287286 continue ;
288287 }
289- deserializeYml_JsonObject ( document, value, tmpObj, YAMLParser::MAP_KEY, (const char *)key->data .scalar .value , depth+1 );
288+ deserializeYml_JsonObject ( document, value, tmpNode, YAMLParser::MAP_KEY, (const char *)key->data .scalar .value , depth+1 );
289+ }
290+ if ( nt == YAMLParser::NONE ) {
291+ // YAML_LOG_d("Root node has %d items", jsonNode.size() );
292+ } else {
293+ // YAML_LOG_d("[KEY][%s] has %d items", nodename, jsonNode.size() );
290294 }
291295 }
292296 break ;
293- default :
294- YAML_LOG_w (" Unknown node type (line %lu)." , yamlNode->start_mark .line );
295- break ;
297+ case YAML_NO_NODE: YAML_LOG_e (" YAML_NO_NODE" ); break ;
298+ default : YAML_LOG_w (" Unknown node type (line %lu)." , yamlNode->start_mark .line ); break ;
296299 }
297- free (_nodename);
298300 }
299301
300-
301302 // JsonVariant deconstructor => YAML stream
302303 size_t serializeYml_JsonVariant ( JsonVariant root, Stream &out, int depth, YAMLParser::JNestingType_t nt )
303304 {
@@ -362,7 +363,7 @@ void YAMLParser::handle_emitter_error(yaml_emitter_t *e)
362363 {
363364 YAMLToArduinoJson *parser = new YAMLToArduinoJson ();
364365 JsonObject tmpObj = parser->toJson ( src ); // decode yaml stream/string
365- dest_doc.set ( tmpObj );
366+ dest_doc.set ( tmpObj[ROOT_NODE] );
366367 delete parser;
367368 return DeserializationError::Ok;
368369 }
@@ -372,7 +373,7 @@ void YAMLParser::handle_emitter_error(yaml_emitter_t *e)
372373 {
373374 YAMLToArduinoJson *parser = new YAMLToArduinoJson ();
374375 JsonObject tmpObj = parser->toJson ( src ); // decode yaml stream/string
375- dest_doc.set ( tmpObj );
376+ dest_doc.set ( tmpObj[ROOT_NODE] );
376377 delete parser;
377378 return DeserializationError::Ok;
378379 }
0 commit comments