+ int pos = find_child(name, index, _children);
+ if (pos >= 0)
+ return _children[pos];
+ else
+ return 0;
+}
+
+
+/**
+ * Get all children with the same name (but different indices).
+ */
+vector<SGPropertyNode *>
+SGPropertyNode::getChildren (const string &name)
+{
+ vector<SGPropertyNode *> children;
+ int max = _children.size();
+
+ for (int i = 0; i < max; i++)
+ if (_children[i]->getName() == name)
+ children.push_back(_children[i]);
+
+ sort(children.begin(), children.end(), CompareIndices());
+ return children;
+}
+
+
+/**
+ * Get all children const with the same name (but different indices).
+ */
+vector<const SGPropertyNode *>
+SGPropertyNode::getChildren (const string &name) const
+{
+ vector<const SGPropertyNode *> children;
+ int max = _children.size();
+
+ for (int i = 0; i < max; i++)
+ if (_children[i]->getName() == name)
+ children.push_back(_children[i]);
+
+ sort(children.begin(), children.end(), CompareIndices());
+ return children;
+}
+
+
+string
+SGPropertyNode::getPath (bool simplify) const
+{
+ if (_parent == 0)
+ return "";
+
+ string path = _parent->getPath(simplify);
+ path += '/';
+ path += _name;
+ if (_index != 0 || !simplify) {
+ char buffer[128];
+ sprintf(buffer, "[%d]", _index);
+ path += buffer;
+ }
+ return path;
+}
+
+SGPropertyNode::Type
+SGPropertyNode::getType () const
+{
+ if (_type == ALIAS)
+ return _value.alias->getType();
+ else
+ return _type;
+}
+
+
+bool
+SGPropertyNode::getBoolValue () const
+{
+ DO_TRACE_READ(BOOL);
+ TEST_READ(false);
+ switch (_type) {
+ case ALIAS:
+ return _value.alias->getBoolValue();
+ case BOOL:
+ return GET_BOOL;
+ case INT:
+ return GET_INT == 0 ? false : true;
+ case LONG:
+ return GET_LONG == 0L ? false : true;
+ case FLOAT:
+ return GET_FLOAT == 0.0 ? false : true;
+ case DOUBLE:
+ return GET_DOUBLE == 0.0L ? false : true;
+ case STRING:
+ case UNSPECIFIED:
+ return (GET_STRING == "true" || getDoubleValue() != 0.0L);
+ case NONE:
+ default:
+ return false;
+ }
+}
+
+int
+SGPropertyNode::getIntValue () const
+{
+ DO_TRACE_READ(INT);
+ TEST_READ(0);
+ switch (_type) {
+ case ALIAS:
+ return _value.alias->getIntValue();
+ case BOOL:
+ return int(GET_BOOL);
+ case INT:
+ return GET_INT;
+ case LONG:
+ return int(GET_LONG);
+ case FLOAT:
+ return int(GET_FLOAT);
+ case DOUBLE:
+ return int(GET_DOUBLE);
+ case STRING:
+ case UNSPECIFIED:
+ return atoi(GET_STRING.c_str());
+ case NONE:
+ default:
+ return 0;
+ }
+}
+
+long
+SGPropertyNode::getLongValue () const
+{
+ DO_TRACE_READ(LONG);
+ TEST_READ(0L);
+ switch (_type) {
+ case ALIAS:
+ return _value.alias->getLongValue();
+ case BOOL:
+ return long(GET_BOOL);
+ case INT:
+ return long(GET_INT);
+ case LONG:
+ return GET_LONG;
+ case FLOAT:
+ return long(GET_FLOAT);
+ case DOUBLE:
+ return long(GET_DOUBLE);
+ case STRING:
+ case UNSPECIFIED:
+ return strtol(GET_STRING.c_str(), 0, 0);
+ case NONE:
+ default:
+ return 0L;
+ }
+}
+
+float
+SGPropertyNode::getFloatValue () const
+{
+ DO_TRACE_READ(FLOAT);
+ TEST_READ(0.0);
+ switch (_type) {
+ case ALIAS:
+ return _value.alias->getFloatValue();
+ case BOOL:
+ return float(GET_BOOL);
+ case INT:
+ return float(GET_INT);
+ case LONG:
+ return float(GET_LONG);
+ case FLOAT:
+ return GET_FLOAT;
+ case DOUBLE:
+ return float(GET_DOUBLE);
+ case STRING:
+ case UNSPECIFIED:
+ return atof(GET_STRING.c_str());
+ case NONE:
+ default:
+ return 0.0;