From 2b2a3629269e8088a689fd57b42ec2766a5b356f Mon Sep 17 00:00:00 2001 From: Aleksandar Fabijanic Date: Tue, 21 Aug 2012 02:42:57 +0000 Subject: [PATCH] SF #3544720: AbstractConfigurator to support 64bit values --- CHANGELOG | 13 ++-- .../include/Poco/Util/AbstractConfiguration.h | 53 +++++++++++++++ Util/src/AbstractConfiguration.cpp | 67 ++++++++++++++++++- .../src/AbstractConfigurationTest.cpp | 41 ++++++++---- .../testsuite/src/AbstractConfigurationTest.h | 4 ++ .../src/IniFileConfigurationTest.cpp | 4 +- 6 files changed, 159 insertions(+), 23 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0d21d16fe..725fe5c2d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -26,12 +26,13 @@ Release 1.5.0 (2012-08-??) - UTF portability improvements - fixed SF#3556186: Linux shouldn't use in Net/SocketDefs.h - added IPAddress RFC 4291 compatible site-local prefix support -- fixed SF# 3012166: IPv6 patch -- added SF# 3558085: Add formatter to MACAddress object -- fixed SF# 3535990: POCO_HAVE_IPv6 without POCO_WIN32_UTF8 conflict -- fixed SF #3552774: Don't hide default target in subordinate makefile -- fixed SF #3534307: Building IPv6 for Linux by default -- fixed SF #3516844: poco missing symbols with external >=lipcre-8.13 +- fixed SF#3012166: IPv6 patch +- added SF#3558085: Add formatter to MACAddress object +- fixed SF#3535990: POCO_HAVE_IPv6 without POCO_WIN32_UTF8 conflict +- fixed SF#3552774: Don't hide default target in subordinate makefile +- fixed SF#3534307: Building IPv6 for Linux by default +- fixed SF#3516844: poco missing symbols with external >=lipcre-8.13 +- added SF#3544720: AbstractConfigurator to support 64bit values Release 1.4.4 (2012-08-??) ========================== diff --git a/Util/include/Poco/Util/AbstractConfiguration.h b/Util/include/Poco/Util/AbstractConfiguration.h index e518e4bca..b3c856ce2 100644 --- a/Util/include/Poco/Util/AbstractConfiguration.h +++ b/Util/include/Poco/Util/AbstractConfiguration.h @@ -173,6 +173,15 @@ public: /// If the value contains references to other properties (${}), these /// are expanded. + unsigned int getUInt(const std::string& key) const; + /// Returns the unsigned int value of the property with the given name. + /// Throws a NotFoundException if the key does not exist. + /// Throws a SyntaxException if the property can not be converted + /// to an unsigned int. + /// Numbers starting with 0x are treated as hexadecimal. + /// If the value contains references to other properties (${}), these + /// are expanded. + int getInt(const std::string& key, int defaultValue) const; /// If a property with the given key exists, returns the property's int value, /// otherwise returns the given default value. @@ -181,6 +190,15 @@ public: /// Numbers starting with 0x are treated as hexadecimal. /// If the value contains references to other properties (${}), these /// are expanded. + + unsigned int getUInt(const std::string& key, unsigned int defaultValue) const; + /// If a property with the given key exists, returns the property's unsigned int + /// value, otherwise returns the given default value. + /// Throws a SyntaxException if the property can not be converted + /// to an unsigned int. + /// Numbers starting with 0x are treated as hexadecimal. + /// If the value contains references to other properties (${}), these + /// are expanded. #if defined(POCO_HAVE_INT64) @@ -193,6 +211,15 @@ public: /// If the value contains references to other properties (${}), these /// are expanded. + UInt64 getUInt64(const std::string& key) const; + /// Returns the UInt64 value of the property with the given name. + /// Throws a NotFoundException if the key does not exist. + /// Throws a SyntaxException if the property can not be converted + /// to an UInt64. + /// Numbers starting with 0x are treated as hexadecimal. + /// If the value contains references to other properties (${}), these + /// are expanded. + Int64 getInt64(const std::string& key, Int64 defaultValue) const; /// If a property with the given key exists, returns the property's Int64 value, /// otherwise returns the given default value. @@ -202,6 +229,15 @@ public: /// If the value contains references to other properties (${}), these /// are expanded. + UInt64 getUInt64(const std::string& key, UInt64 defaultValue) const; + /// If a property with the given key exists, returns the property's UInt64 + /// value, otherwise returns the given default value. + /// Throws a SyntaxException if the property can not be converted + /// to an UInt64. + /// Numbers starting with 0x are treated as hexadecimal. + /// If the value contains references to other properties (${}), these + /// are expanded. + #endif // defined(POCO_HAVE_INT64) double getDouble(const std::string& key) const; @@ -247,6 +283,10 @@ public: virtual void setInt(const std::string& key, int value); /// Sets the property with the given key to the given value. /// An already existing value for the key is overwritten. + + virtual void setUInt(const std::string& key, unsigned int value); + /// Sets the property with the given key to the given value. + /// An already existing value for the key is overwritten. #if defined(POCO_HAVE_INT64) @@ -254,6 +294,10 @@ public: /// Sets the property with the given key to the given value. /// An already existing value for the key is overwritten. + virtual void setUInt64(const std::string& key, UInt64 value); + /// Sets the property with the given key to the given value. + /// An already existing value for the key is overwritten. + #endif // defined(POCO_HAVE_INT64) virtual void setDouble(const std::string& key, double value); @@ -322,6 +366,15 @@ protected: /// implementation throws a Poco::NotImplementedException. static int parseInt(const std::string& value); + static int parseUInt(const std::string& value); + +#if defined(POCO_HAVE_INT64) + + static Int64 parseInt64(const std::string& value); + static UInt64 parseUInt64(const std::string& value); + +#endif // defined(POCO_HAVE_INT64) + static bool parseBool(const std::string& value); void setRawWithEvent(const std::string& key, std::string value); diff --git a/Util/src/AbstractConfiguration.cpp b/Util/src/AbstractConfiguration.cpp index 0d7c70d0d..6b979236e 100644 --- a/Util/src/AbstractConfiguration.cpp +++ b/Util/src/AbstractConfiguration.cpp @@ -174,6 +174,18 @@ Int64 AbstractConfiguration::getInt64(const std::string& key) const } +UInt64 AbstractConfiguration::getUInt64(const std::string& key) const +{ + FastMutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return NumberParser::parseUnsigned64(internalExpand(value)); + else + throw NotFoundException(key); +} + + Int64 AbstractConfiguration::getInt64(const std::string& key, Int64 defaultValue) const { FastMutex::ScopedLock lock(_mutex); @@ -185,6 +197,18 @@ Int64 AbstractConfiguration::getInt64(const std::string& key, Int64 defaultValue return defaultValue; } + +UInt64 AbstractConfiguration::getUInt64(const std::string& key, UInt64 defaultValue) const +{ + FastMutex::ScopedLock lock(_mutex); + + std::string value; + if (getRaw(key, value)) + return NumberParser::parseUnsigned64(internalExpand(value)); + else + return defaultValue; +} + #endif // defined(POCO_HAVE_INT64) @@ -247,6 +271,12 @@ void AbstractConfiguration::setInt(const std::string& key, int value) setRawWithEvent(key, NumberFormatter::format(value)); } + +void AbstractConfiguration::setUInt(const std::string& key, unsigned int value) +{ + setRawWithEvent(key, NumberFormatter::format(value)); +} + #if defined(POCO_HAVE_INT64) @@ -254,7 +284,15 @@ void AbstractConfiguration::setInt64(const std::string& key, Int64 value) { FastMutex::ScopedLock lock(_mutex); - setRaw(key, NumberFormatter::format(value)); + setRawWithEvent(key, NumberFormatter::format(value)); +} + + +void AbstractConfiguration::setUInt64(const std::string& key, UInt64 value) +{ + FastMutex::ScopedLock lock(_mutex); + + setRawWithEvent(key, NumberFormatter::format(value)); } #endif // defined(POCO_HAVE_INT64) @@ -419,6 +457,33 @@ int AbstractConfiguration::parseInt(const std::string& value) } +int AbstractConfiguration::parseUInt(const std::string& value) +{ + if (value.compare(0, 2, "0x") == 0) + return NumberParser::parseHex(value.substr(2)); + else + return NumberParser::parseUnsigned(value); +} + + +Int64 AbstractConfiguration::parseInt64(const std::string& value) +{ + if (value.compare(0, 2, "0x") == 0) + return NumberParser::parseHex64(value.substr(2)); + else + return NumberParser::parse64(value); +} + + +UInt64 AbstractConfiguration::parseUInt64(const std::string& value) +{ + if (value.compare(0, 2, "0x") == 0) + return NumberParser::parseHex64(value.substr(2)); + else + return NumberParser::parseUnsigned64(value); +} + + bool AbstractConfiguration::parseBool(const std::string& value) { int n; diff --git a/Util/testsuite/src/AbstractConfigurationTest.cpp b/Util/testsuite/src/AbstractConfigurationTest.cpp index ae1c1573f..bc16f1802 100644 --- a/Util/testsuite/src/AbstractConfigurationTest.cpp +++ b/Util/testsuite/src/AbstractConfigurationTest.cpp @@ -36,14 +36,20 @@ #include "Poco/AutoPtr.h" #include "Poco/Exception.h" #include "Poco/Delegate.h" +#include "Poco/NumberFormatter.h" #include "Poco/Types.h" #include +#undef min +#undef max +#include using Poco::Util::AbstractConfiguration; using Poco::Util::MapConfiguration; +using Poco::NumberFormatter; using Poco::AutoPtr; using Poco::Int64; +using Poco::UInt64; AbstractConfigurationTest::AbstractConfigurationTest(const std::string& name): CppUnit::TestCase(name) @@ -125,8 +131,9 @@ void AbstractConfigurationTest::testGetInt64() #if defined(POCO_HAVE_INT64) AutoPtr pConf = createConfiguration(); - assert (pConf->getInt64("prop4.bigint1") == 420000000000L); - assert (pConf->getInt64("prop4.bigint2") == -420000000000L); + assert (pConf->getInt64("prop4.bigint1") == std::numeric_limits::max()); + assert (pConf->getInt64("prop4.bigint2") == std::numeric_limits::min()); + assert (pConf->getUInt64("prop4.biguint") == std::numeric_limits::max()); assert (pConf->getInt64("ref2") == 42); try @@ -139,9 +146,10 @@ void AbstractConfigurationTest::testGetInt64() { } - assert (pConf->getInt64("prop4.bigint1", 100) == 420000000000L); - assert (pConf->getInt64("prop4.bigint2", 100) == -420000000000L); -#endif //defined(POCO_HAVE_INT64) + assert (pConf->getInt64("prop4.bigint1", 100) == std::numeric_limits::max()); + assert (pConf->getInt64("prop4.bigint2", 100) == std::numeric_limits::min()); + assert (pConf->getUInt64("prop4.biguint", 100) == std::numeric_limits::max()); +#endif } @@ -252,10 +260,12 @@ void AbstractConfigurationTest::testSetInt64() #if defined(POCO_HAVE_INT64) AutoPtr pConf = createConfiguration(); - pConf->setInt64("set.bigint1", 440000000000L); - pConf->setInt64("set.bigint2", -440000000000L); - assert (pConf->getInt64("set.int1") == 440000000000L); - assert (pConf->getInt64("set.int2") == -440000000000L); + pConf->setInt64("set.bigint1", std::numeric_limits::max()); + pConf->setInt64("set.bigint2", std::numeric_limits::min()); + pConf->setInt64("set.biguint", std::numeric_limits::max()); + assert (pConf->getInt64("set.bigint1") == std::numeric_limits::max()); + assert (pConf->getInt64("set.bigint2") == std::numeric_limits::min()); + assert (pConf->getInt64("set.biguint") == std::numeric_limits::max()); #endif //defined(POCO_HAVE_INT64) } @@ -374,7 +384,7 @@ void AbstractConfigurationTest::testRemove() pConf->keys(keys); assert (keys.size() == 13); pConf->keys("prop4", keys); - assert (keys.size() == 15); + assert (keys.size() == 17); pConf->remove("prop4.bool1"); assert (!pConf->hasProperty("prop4.bool1")); @@ -383,7 +393,7 @@ void AbstractConfigurationTest::testRemove() pConf->keys(keys); assert (keys.size() == 13); pConf->keys("prop4", keys); - assert (keys.size() == 14); + assert (keys.size() == 16); pConf->remove("prop4"); assert (!pConf->hasProperty("prop4.bool1")); @@ -411,8 +421,10 @@ Poco::AutoPtr AbstractConfigurationTest::createConfigurat pConfig->setString("prop3.string2", "bar"); pConfig->setString("prop4.int1", "42"); pConfig->setString("prop4.int2", "-42"); - pConfig->setString("prop4.bigint1", "420000000000"); - pConfig->setString("prop4.bigint2", "-420000000000"); + pConfig->setString("prop4.uint", NumberFormatter::format(std::numeric_limits::max())); + pConfig->setString("prop4.bigint1", NumberFormatter::format(std::numeric_limits::max())); + pConfig->setString("prop4.bigint2", NumberFormatter::format(std::numeric_limits::min())); + pConfig->setString("prop4.biguint", NumberFormatter::format(std::numeric_limits::max())); pConfig->setString("prop4.hex", "0x1f"); pConfig->setString("prop4.double1", "1"); pConfig->setString("prop4.double2", "-1.5"); @@ -439,7 +451,7 @@ Poco::AutoPtr AbstractConfigurationTest::createConfigurat pConfig->setString("ref7", "${ref1}"); pConfig->setString("dollar.atend", "foo$"); pConfig->setString("dollar.middle", "foo$bar"); - + return pConfig; } @@ -484,3 +496,4 @@ void AbstractConfigurationTest::onPropertyRemoved(const void*, const std::string { _removedKey = key; } + diff --git a/Util/testsuite/src/AbstractConfigurationTest.h b/Util/testsuite/src/AbstractConfigurationTest.h index 6db597dd1..d00327935 100644 --- a/Util/testsuite/src/AbstractConfigurationTest.h +++ b/Util/testsuite/src/AbstractConfigurationTest.h @@ -57,7 +57,9 @@ public: void testExpand(); void testSetString(); void testSetInt(); + void testSetUInt(); void testSetInt64(); + void testSetUInt64(); void testSetDouble(); void testSetBool(); void testKeys(); @@ -91,11 +93,13 @@ protected: CppUnit_addTest(suite, cls, testHasProperty); \ CppUnit_addTest(suite, cls, testGetString); \ CppUnit_addTest(suite, cls, testGetInt); \ + CppUnit_addTest(suite, cls, testGetInt64); \ CppUnit_addTest(suite, cls, testGetDouble); \ CppUnit_addTest(suite, cls, testGetBool); \ CppUnit_addTest(suite, cls, testExpand); \ CppUnit_addTest(suite, cls, testSetString); \ CppUnit_addTest(suite, cls, testSetInt); \ + CppUnit_addTest(suite, cls, testSetInt64); \ CppUnit_addTest(suite, cls, testSetDouble); \ CppUnit_addTest(suite, cls, testSetBool); \ CppUnit_addTest(suite, cls, testKeys); \ diff --git a/Util/testsuite/src/IniFileConfigurationTest.cpp b/Util/testsuite/src/IniFileConfigurationTest.cpp index 9029f9801..27f074505 100644 --- a/Util/testsuite/src/IniFileConfigurationTest.cpp +++ b/Util/testsuite/src/IniFileConfigurationTest.cpp @@ -124,7 +124,7 @@ void IniFileConfigurationTest::testCaseInsensitiveRemove() pConf->keys(keys); assert (keys.size() == 13); pConf->keys("prop4", keys); - assert (keys.size() == 15); + assert (keys.size() == 17); pConf->remove("PROP4.Bool1"); assert (pConf->hasProperty("Prop1")); @@ -134,7 +134,7 @@ void IniFileConfigurationTest::testCaseInsensitiveRemove() pConf->keys(keys); assert (keys.size() == 13); pConf->keys("PROP4", keys); - assert (keys.size() == 14); + assert (keys.size() == 16); pConf->remove("Prop4"); assert (pConf->hasProperty("Prop1"));