From 3066e66f3283e9effa58ac66e61112da74bf5ca9 Mon Sep 17 00:00:00 2001 From: aaron0x Date: Sat, 26 Sep 2015 23:31:30 +0800 Subject: [PATCH] Enhance FileChannel purge setting. --- Foundation/include/Poco/FileChannel.h | 6 + Foundation/src/FileChannel.cpp | 125 +++++++++++-------- Foundation/testsuite/src/FileChannelTest.cpp | 29 +++++ Foundation/testsuite/src/FileChannelTest.h | 1 + 4 files changed, 110 insertions(+), 51 deletions(-) diff --git a/Foundation/include/Poco/FileChannel.h b/Foundation/include/Poco/FileChannel.h index 374c622a3..12b745869 100644 --- a/Foundation/include/Poco/FileChannel.h +++ b/Foundation/include/Poco/FileChannel.h @@ -23,6 +23,7 @@ #include "Poco/Foundation.h" #include "Poco/Channel.h" #include "Poco/Timestamp.h" +#include "Poco/Timespan.h" #include "Poco/Mutex.h" @@ -243,6 +244,11 @@ protected: void purge(); private: + bool setNoPurge(const std::string& value); + int extractDigit(const std::string& value, std::string::const_iterator* nextToDigit = NULL) const; + void setPurgeStrategy(PurgeStrategy* strategy); + Timespan::TimeDiff extractFactor(const std::string& value, std::string::const_iterator start) const; + std::string _path; std::string _times; std::string _rotation; diff --git a/Foundation/src/FileChannel.cpp b/Foundation/src/FileChannel.cpp index ad73d9a17..52fdc6f44 100644 --- a/Foundation/src/FileChannel.cpp +++ b/Foundation/src/FileChannel.cpp @@ -24,7 +24,6 @@ #include "Poco/DateTime.h" #include "Poco/LocalDateTime.h" #include "Poco/String.h" -#include "Poco/Timespan.h" #include "Poco/Exception.h" #include "Poco/Ascii.h" @@ -314,65 +313,22 @@ void FileChannel::setCompress(const std::string& compress) void FileChannel::setPurgeAge(const std::string& age) { - delete _pPurgeStrategy; - _pPurgeStrategy = 0; - _purgeAge = "none"; + if (setNoPurge(age)) return; - if (age.empty() || 0 == icompare(age, "none")) - return; + std::string::const_iterator nextToDigit; + int num = extractDigit(age, &nextToDigit); + Timespan::TimeDiff factor = extractFactor(age, nextToDigit); - std::string::const_iterator it = age.begin(); - std::string::const_iterator end = age.end(); - int n = 0; - while (it != end && Ascii::isSpace(*it)) ++it; - while (it != end && Ascii::isDigit(*it)) { n *= 10; n += *it++ - '0'; } - if (0 == n) - throw InvalidArgumentException("Zero is not valid purge age."); - - while (it != end && Ascii::isSpace(*it)) ++it; - - std::string unit; - while (it != end && Ascii::isAlpha(*it)) unit += *it++; - - Timespan::TimeDiff factor = Timespan::SECONDS; - if (unit == "minutes") - factor = Timespan::MINUTES; - else if (unit == "hours") - factor = Timespan::HOURS; - else if (unit == "days") - factor = Timespan::DAYS; - else if (unit == "weeks") - factor = 7*Timespan::DAYS; - else if (unit == "months") - factor = 30*Timespan::DAYS; - else if (unit != "seconds") - throw InvalidArgumentException("purgeAge", age); - - _pPurgeStrategy = new PurgeByAgeStrategy(Timespan(factor*n)); + setPurgeStrategy(new PurgeByAgeStrategy(Timespan(num * factor))); _purgeAge = age; } void FileChannel::setPurgeCount(const std::string& count) { - delete _pPurgeStrategy; - _pPurgeStrategy = 0; - _purgeAge = "none"; + if (setNoPurge(count)) return; - if (count.empty() || 0 == icompare(count, "none")) - return; - - std::string::const_iterator it = count.begin(); - std::string::const_iterator end = count.end(); - int n = 0; - while (it != end && Ascii::isSpace(*it)) ++it; - while (it != end && Ascii::isDigit(*it)) { n *= 10; n += *it++ - '0'; } - if (0 == n) - throw InvalidArgumentException("Zero is not valid purge count."); - while (it != end && Ascii::isSpace(*it)) ++it; - - delete _pPurgeStrategy; - _pPurgeStrategy = new PurgeByCountStrategy(n); + setPurgeStrategy(new PurgeByCountStrategy(extractDigit(count))); _purgeCount = count; } @@ -404,4 +360,71 @@ void FileChannel::purge() } +bool FileChannel::setNoPurge(const std::string& value) +{ + if (value.empty() || 0 == icompare(value, "none")) + { + delete _pPurgeStrategy; + _pPurgeStrategy = 0; + _purgeAge = "none"; + return true; + } + else return false; +} + + +int FileChannel::extractDigit(const std::string& value, std::string::const_iterator* nextToDigit) const +{ + std::string::const_iterator it = value.begin(); + std::string::const_iterator end = value.end(); + int digit = 0; + + while (it != end && Ascii::isSpace(*it)) ++it; + while (it != end && Ascii::isDigit(*it)) + { + digit *= 10; + digit += *it++ - '0'; + } + + if (digit == 0) + throw InvalidArgumentException("Zero is not valid purge age."); + + if (nextToDigit) *nextToDigit = it; + return digit; +} + + +void FileChannel::setPurgeStrategy(PurgeStrategy* strategy) +{ + delete _pPurgeStrategy; + _pPurgeStrategy = strategy; +} + + +Timespan::TimeDiff FileChannel::extractFactor(const std::string& value, std::string::const_iterator start) const +{ + while (start != value.end() && Ascii::isSpace(*start)) ++start; + + std::string unit; + while (start != value.end() && Ascii::isAlpha(*start)) unit += *start++; + + if (unit == "seconds") + return Timespan::SECONDS; + if (unit == "minutes") + return Timespan::MINUTES; + else if (unit == "hours") + return Timespan::HOURS; + else if (unit == "days") + return Timespan::DAYS; + else if (unit == "weeks") + return 7 * Timespan::DAYS; + else if (unit == "months") + return 30 * Timespan::DAYS; + else throw InvalidArgumentException("purgeAge", value); + + return Timespan::TimeDiff(); +} + + + } // namespace Poco diff --git a/Foundation/testsuite/src/FileChannelTest.cpp b/Foundation/testsuite/src/FileChannelTest.cpp index 9bfa94e15..bb0c86643 100644 --- a/Foundation/testsuite/src/FileChannelTest.cpp +++ b/Foundation/testsuite/src/FileChannelTest.cpp @@ -518,6 +518,34 @@ void FileChannelTest::testPurgeCount() } +void FileChannelTest::testWrongPurgeOption() +{ + std::string name = filename(); + AutoPtr pChannel = new FileChannel(name); + pChannel->setProperty(FileChannel::PROP_PURGEAGE, "5 seconds"); + + try + { + pChannel->setProperty(FileChannel::PROP_PURGEAGE, "peace"); + fail("must fail"); + } catch (InvalidArgumentException) + { + assert(pChannel->getProperty(FileChannel::PROP_PURGEAGE) == "5 seconds"); + } + + try + { + pChannel->setProperty(FileChannel::PROP_PURGECOUNT, "peace"); + fail("must fail"); + } catch (InvalidArgumentException) + { + assert(pChannel->getProperty(FileChannel::PROP_PURGEAGE) == "5 seconds"); + } + + remove(name); +} + + void FileChannelTest::setUp() { } @@ -620,6 +648,7 @@ CppUnit::Test* FileChannelTest::suite() CppUnit_addTest(pSuite, FileChannelTest, testCompress); CppUnit_addTest(pSuite, FileChannelTest, testPurgeAge); CppUnit_addTest(pSuite, FileChannelTest, testPurgeCount); + CppUnit_addTest(pSuite, FileChannelTest, testWrongPurgeOption); return pSuite; } diff --git a/Foundation/testsuite/src/FileChannelTest.h b/Foundation/testsuite/src/FileChannelTest.h index 8b2168a96..d70d67069 100644 --- a/Foundation/testsuite/src/FileChannelTest.h +++ b/Foundation/testsuite/src/FileChannelTest.h @@ -45,6 +45,7 @@ public: void testCompress(); void testPurgeAge(); void testPurgeCount(); + void testWrongPurgeOption(); void setUp(); void tearDown();