From: ehofman Date: Sat, 9 May 2009 11:34:28 +0000 (+0000) Subject: * Add a function to create a node after the laste node with the same name X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=56c4ba67c6249f4f8779ccf710ceb650c7c81acf;p=simgear.git * Add a function to create a node after the laste node with the same name (this frees the xml property loader from keeping track of the number of nodes with the same name that have already been added to the property tree). * make some small code cleanups at the core of the property tree. --- diff --git a/simgear/props/props.cxx b/simgear/props/props.cxx index f73e773e..83b586c0 100644 --- a/simgear/props/props.cxx +++ b/simgear/props/props.cxx @@ -229,11 +229,13 @@ parse_path (const string &path, vector &components) static char * copy_string (const char * s) { - // FIXME: potential buffer overflow. - // For some reason, strnlen and - // strncpy cause all kinds of crashes. - char * copy = new char[strlen(s) + 1]; - strcpy(copy, s); + unsigned long int slen = strlen(s); + char * copy = new char[slen + 1]; + + // the source string length is known so no need to check for '\0' + // when copying every single character + memcpy(copy, s, slen); + *(copy + slen) = '\0'; return copy; } @@ -252,12 +254,32 @@ find_child (const char * name, int index, const vector& node int nNodes = nodes.size(); for (int i = 0; i < nNodes; i++) { SGPropertyNode * node = nodes[i]; - if (compare_strings(node->getName(), name) && node->getIndex() == index) + + // searching for a mathing index is a lot less time consuming than + // comparing two strings so do that first. + if (node->getIndex() == index && compare_strings(node->getName(), name)) return i; } return -1; } +/** + * Locate the last child node with a given name. +*/ +static int +find_last_child (const char * name, const vector& nodes) +{ + int nNodes = nodes.size(); + int pos = -1; + + for (int i = 0; i < nNodes; i++) { + SGPropertyNode * node = nodes[i]; + if (compare_strings(node->getName(), name)) + pos++; + } + return pos; +} + /** * Locate another node, given a relative path. @@ -824,6 +846,21 @@ SGPropertyNode::getAliasTarget () const return (_type == ALIAS ? _value.alias : 0); } +/** + * create a non-const child by name after the last node with the same name. + */ +SGPropertyNode * +SGPropertyNode::addChild (const char * name) +{ + int pos = find_last_child(name, _children); + + SGPropertyNode_ptr node; + node = new SGPropertyNode(name, ++pos, this); + _children.push_back(node); + fireChildAdded(node); + return node; +} + /** * Get a non-const child by index. diff --git a/simgear/props/props.hxx b/simgear/props/props.hxx index d25637e0..cc1ed537 100644 --- a/simgear/props/props.hxx +++ b/simgear/props/props.hxx @@ -622,6 +622,10 @@ public: return (getChild(name, index) != 0); } + /** + * Create a child node after the last node with the same name. + */ + SGPropertyNode * addChild (const char * name); /** * Get a child node by name and index.