From 23b38241708992acaaf474d12782ce87a3cb7596 Mon Sep 17 00:00:00 2001 From: Julian Smith Date: Wed, 22 Dec 2021 22:51:02 +0000 Subject: [PATCH] simgear/props/props.*: added defaultValue arg to node get*Value() methods. Add defaultValue arg to get*Value() methods that previously took no args. We do this for getBoolValue(), getIntValue(), getLongValue(), getFloatValue() and getDoubleValue(). The default value is returned if the node's string is not convertible to the requested type. This can enable some calling code to be optimised where it previously checked for getStringValue() (which is slow now that it returns a std::string) returning an empty string, before calling getDoubleValue(). --- simgear/props/props.cxx | 76 ++++++++++++++++++++++++----------------- simgear/props/props.hxx | 14 ++++---- 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/simgear/props/props.cxx b/simgear/props/props.cxx index 517b08fe..f5dd9ca2 100755 --- a/simgear/props/props.cxx +++ b/simgear/props/props.cxx @@ -1162,10 +1162,10 @@ struct SGPropertyNodeImpl /* Get the value as a string. */ static std::string - make_string(SGPropertyLock& lock, const SGPropertyNode& node) + make_string(SGPropertyLock& lock, const SGPropertyNode& node, const char* defaultValue="") { if (!getAttribute(lock, node, SGPropertyNode::READ)) - return ""; + return defaultValue; switch (node._type) { case props::ALIAS: { @@ -1181,7 +1181,7 @@ struct SGPropertyNodeImpl case props::UNSPECIFIED: return get_string(lock, node); case props::NONE: - return ""; + return defaultValue; default: break; } @@ -1209,7 +1209,7 @@ struct SGPropertyNodeImpl } break; default: - return ""; + return defaultValue; } return sstr.str(); } @@ -1345,7 +1345,6 @@ struct SGPropertyNodeImpl static std::string getStringValue(SGPropertyLock& lock, const SGPropertyNode& node) { - // This is inherantly unsafe. // Shortcut for common case if (node._attr == (SGPropertyNode::READ|SGPropertyNode::WRITE) && node._type == props::STRING) return std::string(get_string(lock, node)); @@ -1358,7 +1357,7 @@ struct SGPropertyNodeImpl } static bool - getBoolValue(SGPropertyLock& lock, const SGPropertyNode& node) + getBoolValue(SGPropertyLock& lock, const SGPropertyNode& node, bool defaultValue=false) { // Shortcut for common case if (node._attr == (SGPropertyNode::READ|SGPropertyNode::WRITE) && node._type == props::BOOL) @@ -1367,13 +1366,13 @@ struct SGPropertyNodeImpl if (getAttribute(lock, node, SGPropertyNode::TRACE_READ)) trace_read(lock, node); // Releases+acquire . if (!getAttribute(lock, node, SGPropertyNode::READ)) - return SGRawValue::DefaultValue(); + return defaultValue; switch (node._type) { case props::ALIAS: { SGPropertyNode* p = node._value.alias; lock.release(); - return p->getBoolValue(); + return p->getBoolValue(defaultValue); } case props::BOOL: return get_bool(lock, node); @@ -1387,7 +1386,7 @@ struct SGPropertyNodeImpl return get_double(lock, node) == 0.0L ? false : true; case props::STRING: case props::UNSPECIFIED: - return (strings_equal(get_string(lock, node), "true") || getDoubleValue(lock, node) != 0.0L); + return (strings_equal(get_string(lock, node), "true") || getDoubleValue(lock, node, 0) != 0.0L); case props::NONE: default: return SGRawValue::DefaultValue(); @@ -1395,7 +1394,7 @@ struct SGPropertyNodeImpl } static int - getIntValue(SGPropertyLock& lock, const SGPropertyNode& node) + getIntValue(SGPropertyLock& lock, const SGPropertyNode& node, int defaultValue=0) { // Shortcut for common case if (node._attr == (SGPropertyNode::READ|SGPropertyNode::WRITE) && node._type == props::INT) @@ -1404,13 +1403,13 @@ struct SGPropertyNodeImpl if (getAttribute(lock, node, SGPropertyNode::TRACE_READ)) trace_read(lock, node); if (!getAttribute(lock, node, SGPropertyNode::READ)) - return SGRawValue::DefaultValue(); + return defaultValue; switch (node._type) { case props::ALIAS: { SGPropertyNode* p = node._value.alias; lock.release(); - return p->getIntValue(); + return p->getIntValue(defaultValue); } case props::BOOL: return int(get_bool(lock, node)); @@ -1424,6 +1423,7 @@ struct SGPropertyNodeImpl return int(get_double(lock, node)); case props::STRING: case props::UNSPECIFIED: + /* fixme: use strtol*/ return atoi(get_string(lock, node)); case props::NONE: default: @@ -1432,7 +1432,7 @@ struct SGPropertyNodeImpl } static long - getLongValue(SGPropertyLock& lock, const SGPropertyNode& node) + getLongValue(SGPropertyLock& lock, const SGPropertyNode& node, long defaultValue=0) { // Shortcut for common case if (node._attr == (SGPropertyNode::READ|SGPropertyNode::WRITE) && node._type == props::LONG) @@ -1441,7 +1441,7 @@ struct SGPropertyNodeImpl if (getAttribute(lock, node, SGPropertyNode::TRACE_READ)) trace_read(lock, node); if (!getAttribute(lock, node, SGPropertyNode::READ)) - return SGRawValue::DefaultValue(); + return defaultValue; switch (node._type) { case props::ALIAS: { @@ -1461,6 +1461,7 @@ struct SGPropertyNodeImpl return long(get_double(lock, node)); case props::STRING: case props::UNSPECIFIED: + /* fixme: check for error. */ return strtol(get_string(lock, node), 0, 0); case props::NONE: default: @@ -1469,7 +1470,7 @@ struct SGPropertyNodeImpl } static float - getFloatValue(SGPropertyLock& lock, const SGPropertyNode& node) + getFloatValue(SGPropertyLock& lock, const SGPropertyNode& node, float defaultValue=0) { // Shortcut for common case if (node._attr == (SGPropertyNode::READ|SGPropertyNode::WRITE) && node._type == props::FLOAT) @@ -1478,7 +1479,7 @@ struct SGPropertyNodeImpl if (getAttribute(lock, node, SGPropertyNode::TRACE_READ)) trace_read(lock, node); if (!getAttribute(lock, node, SGPropertyNode::READ)) - return SGRawValue::DefaultValue(); + return defaultValue; switch (node._type) { case props::ALIAS: { @@ -1498,6 +1499,7 @@ struct SGPropertyNodeImpl return float(get_double(lock, node)); case props::STRING: case props::UNSPECIFIED: + /* fixme: check for error. */ return atof(get_string(lock, node)); case props::NONE: default: @@ -1506,7 +1508,7 @@ struct SGPropertyNodeImpl } static double - getDoubleValue(SGPropertyLock& lock, const SGPropertyNode& node) + getDoubleValue(SGPropertyLock& lock, const SGPropertyNode& node, double defaultValue=0) { // Shortcut for common case if (node._attr == (SGPropertyNode::READ|SGPropertyNode::WRITE) && node._type == props::DOUBLE) @@ -1515,14 +1517,14 @@ struct SGPropertyNodeImpl if (getAttribute(lock, node, SGPropertyNode::TRACE_READ)) trace_read(lock, node); if (!getAttribute(lock, node, SGPropertyNode::READ)) - return SGRawValue::DefaultValue(); + return defaultValue; switch (node._type) { case props::ALIAS: { SGPropertyNode* p = node._value.alias; lock.release(); - return p->getDoubleValue(); + return p->getDoubleValue(defaultValue); } case props::BOOL: return double(get_bool(lock, node)); @@ -1536,7 +1538,19 @@ struct SGPropertyNodeImpl return get_double(lock, node); case props::STRING: case props::UNSPECIFIED: - return strtod(get_string(lock, node), 0); + { + char* end; + const char* s = get_string(lock, node); + double ret = strtod(s, &end); + if (end == s) + { + /* Unable to convert. Would prefer 'if (*end) ...' so + we don't return partial string conversion, but this is + backwards compatible. */ + return defaultValue; + } + return ret; + } case props::NONE: default: return SGRawValue::DefaultValue(); @@ -1544,7 +1558,7 @@ struct SGPropertyNodeImpl } static bool - setBoolValue(SGPropertyLockExclusive& exclusive, SGPropertyNode& node, bool value) + setBoolValue(SGPropertyLockExclusive& exclusive, SGPropertyNode& node, bool value=false) { // Shortcut for common case if (node._attr == (SGPropertyNode::READ|SGPropertyNode::WRITE) && node._type == props::BOOL) @@ -2836,38 +2850,38 @@ SGPropertyNode::getType() const bool -SGPropertyNode::getBoolValue() const +SGPropertyNode::getBoolValue(bool defaultValue) const { SGPropertyLockShared shared(*this); - return SGPropertyNodeImpl::getBoolValue(shared, *this); + return SGPropertyNodeImpl::getBoolValue(shared, *this, defaultValue); } int -SGPropertyNode::getIntValue() const +SGPropertyNode::getIntValue(int defaultValue) const { SGPropertyLockShared shared(*this); - return SGPropertyNodeImpl::getIntValue(shared, *this); + return SGPropertyNodeImpl::getIntValue(shared, *this, defaultValue); } long -SGPropertyNode::getLongValue() const +SGPropertyNode::getLongValue(long defaultValue) const { SGPropertyLockShared shared(*this); - return SGPropertyNodeImpl::getLongValue(shared, *this); + return SGPropertyNodeImpl::getLongValue(shared, *this, defaultValue); } float -SGPropertyNode::getFloatValue () const +SGPropertyNode::getFloatValue(float defaultValue) const { SGPropertyLockShared shared(*this); - return SGPropertyNodeImpl::getFloatValue(shared, *this); + return SGPropertyNodeImpl::getFloatValue(shared, *this, defaultValue); } double -SGPropertyNode::getDoubleValue() const +SGPropertyNode::getDoubleValue(double defaultValue) const { SGPropertyLockShared shared(*this); - return SGPropertyNodeImpl::getDoubleValue(shared, *this); + return SGPropertyNodeImpl::getDoubleValue(shared, *this, defaultValue); } diff --git a/simgear/props/props.hxx b/simgear/props/props.hxx index 6290a7c2..0fcd4106 100644 --- a/simgear/props/props.hxx +++ b/simgear/props/props.hxx @@ -1074,12 +1074,14 @@ public: /** Get the type of leaf value, if any, for this node. */ simgear::props::Type getType() const; - /** Get a value of this node. */ - bool getBoolValue() const; - int getIntValue() const; - long getLongValue() const; - float getFloatValue() const; - double getDoubleValue() const; + /** Get a value of this node. We return if node is not + readable or not the requested (or comaptible) type and its string value is + not convertible to the requested type. */ + bool getBoolValue(bool defaultValue=false) const; + int getIntValue(int defaultValue=0) const; + long getLongValue(long defaultValue=0) const; + float getFloatValue(float defaultValue=0) const; + double getDoubleValue(double defaultValue=0) const; std::string getStringValue() const; /** Set value of this node. */