]> git.mxchange.org Git - simgear.git/commitdiff
* Add a function to create a node after the laste node with the same name
authorehofman <ehofman>
Sat, 9 May 2009 11:34:28 +0000 (11:34 +0000)
committerTim Moore <timoore@redhat.com>
Sun, 17 May 2009 22:36:46 +0000 (00:36 +0200)
   (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.

simgear/props/props.cxx
simgear/props/props.hxx

index f73e773e02577527387536758494aed5ea4b81bf..83b586c06a7637f696b4d196aef8ef9c18f6b9db 100644 (file)
@@ -229,11 +229,13 @@ parse_path (const string &path, vector<PathComponent> &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<SGPropertyNode_ptr>& 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<SGPropertyNode_ptr>& 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.
index d25637e04a351fc793b521fa9ab34ce298f51017..cc1ed537e700837759baca30dea4c5d864541f5f 100644 (file)
@@ -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.