double-conversion floating-point conversions

- using double-conversion library for floating-point numeric/string
conversions
- added string replace[InPlace], remove[InPlace]
- reverted overwritten FileChannel purge age and count features
- file size value checks in SMTPClient
This commit is contained in:
aleks-f
2012-12-01 14:02:51 -06:00
parent 9dd1482a02
commit 134558f926
13 changed files with 372 additions and 293 deletions

View File

@@ -327,12 +327,23 @@ void FileChannel::setCompress(const std::string& compress)
void FileChannel::setPurgeAge(const std::string& age)
{
delete _pPurgeStrategy;
_pPurgeStrategy = 0;
_purgeAge = "none";
if (age.empty() || 0 == icompare(age, "none"))
return;
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++;
@@ -349,8 +360,7 @@ void FileChannel::setPurgeAge(const std::string& age)
factor = 30*Timespan::DAYS;
else if (unit != "seconds")
throw InvalidArgumentException("purgeAge", age);
delete _pPurgeStrategy;
_pPurgeStrategy = new PurgeByAgeStrategy(Timespan(factor*n));
_purgeAge = age;
}
@@ -358,11 +368,20 @@ void FileChannel::setPurgeAge(const std::string& age)
void FileChannel::setPurgeCount(const std::string& count)
{
delete _pPurgeStrategy;
_pPurgeStrategy = 0;
_purgeAge = "none";
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;

View File

@@ -206,8 +206,7 @@ double NumberParser::parseFloat(const std::string& s, char decSep, char thSep)
bool NumberParser::tryParseFloat(const std::string& s, double& value, char decSep, char thSep)
{
char eu;
return strToFloat(s.c_str(), value, eu, decSep, thSep);
return strToDouble(s.c_str(), value, decSep, thSep);
}

View File

@@ -33,21 +33,22 @@
// DEALINGS IN THE SOFTWARE.
//
// +++ double conversion +++
#include "diy-fp.cc"
#include "cached-powers.cc"
#include "bignum-dtoa.cc"
#include "bignum.cc"
#include "cached-powers.cc"
#include "diy-fp.cc"
#include "double-conversion.cc"
#include "fast-dtoa.cc"
#include "fixed-dtoa.cc"
#include "strtod.cc"
#include "double-conversion.cc"
// --- double conversion ---
#include "Poco/NumericString.h"
#include "Poco/String.h"
#include <cctype>
namespace {
@@ -78,7 +79,7 @@ void insertThousandSep(std::string& str, char thSep, char decSep = '.')
while (it != begin)
{
--it;
if (*it == 'e') break;
if ((*it == 'e') || (*it == 'E')) break;
}
}
if (decPos != std::string::npos)
@@ -115,7 +116,7 @@ void floatToStr(char* buffer, int bufferSize, float value, int lowDec, int highD
StringBuilder builder(buffer, bufferSize);
int flags = DoubleToStringConverter::UNIQUE_ZERO |
DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN;
DoubleToStringConverter dc(flags, "inf", "nan", 'e', lowDec, highDec, 0, 0);
DoubleToStringConverter dc(flags, POCO_FLT_INF, POCO_FLT_NAN, POCO_FLT_EXP, lowDec, highDec, 0, 0);
dc.ToShortestSingle(value, &builder);
builder.Finalize();
}
@@ -143,7 +144,7 @@ void doubleToStr(char* buffer, int bufferSize, double value, int lowDec, int hig
StringBuilder builder(buffer, bufferSize);
int flags = DoubleToStringConverter::UNIQUE_ZERO |
DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN;
DoubleToStringConverter dc(flags, "inf", "nan", 'e', lowDec, highDec, 0, 0);
DoubleToStringConverter dc(flags, POCO_FLT_INF, POCO_FLT_NAN, POCO_FLT_EXP, lowDec, highDec, 0, 0);
dc.ToShortest(value, &builder);
builder.Finalize();
}
@@ -166,32 +167,59 @@ std::string& doubleToStr(std::string& str, double value, int precision, int widt
}
float strToFloatDC(const char* str)
float strToFloat(const char* str)
{
using namespace double_conversion;
double empty_string_value = 0.0;
int processed;
int flags = StringToDoubleConverter::ALLOW_LEADING_SPACES |
StringToDoubleConverter::ALLOW_TRAILING_SPACES;
StringToDoubleConverter converter(flags, empty_string_value, Single::NaN(), 0, 0);
StringToDoubleConverter converter(flags, 0.0, Single::NaN(), POCO_FLT_INF, POCO_FLT_NAN);
float result = converter.StringToFloat(str, strlen(str), &processed);
return result;
}
double strToDoubleDC(const char* str)
double strToDouble(const char* str)
{
using namespace double_conversion;
double empty_string_value = 0.0;
int processed;
int flags = StringToDoubleConverter::ALLOW_LEADING_SPACES |
StringToDoubleConverter::ALLOW_TRAILING_SPACES;
StringToDoubleConverter converter(flags, empty_string_value, Double::NaN(), 0, 0);
StringToDoubleConverter converter(flags, 0.0, Double::NaN(), POCO_FLT_INF, POCO_FLT_NAN);
double result = converter.StringToDouble(str, strlen(str), &processed);
return result;
}
bool strToFloat(const std::string& str, float& result, char decSep, char thSep)
{
using namespace double_conversion;
std::string tmp(str);
removeInPlace(tmp, thSep);
removeInPlace(tmp, 'f');
replaceInPlace(tmp, decSep, '.');
result = strToFloat(tmp.c_str());
return !FPEnvironment::isInfinite(result) &&
!FPEnvironment::isNaN(result);
}
bool strToDouble(const std::string& str, double& result, char decSep, char thSep)
{
if (str.empty()) return false;
using namespace double_conversion;
std::string tmp(str);
removeInPlace(tmp, thSep);
replaceInPlace(tmp, decSep, '.');
removeInPlace(tmp, 'f');
result = strToDouble(tmp.c_str());
return !FPEnvironment::isInfinite(result) &&
!FPEnvironment::isNaN(result);
}
} // namespace Poco

View File

@@ -165,6 +165,22 @@ std::string replace(const std::string& str, const std::string::value_type* from,
return result;
}
std::string replace(const std::string& str, const std::string::value_type from, const std::string::value_type to, std::string::size_type start)
{
std::string result(str);
replaceInPlace(result, from, to, start);
return result;
}
std::string remove(const std::string& str, const std::string::value_type ch, std::string::size_type start)
{
std::string result(str);
replaceInPlace(result, ch, 0, start);
return result;
}
std::string& replaceInPlace(std::string& str, const std::string& from, const std::string& to, std::string::size_type start)
{
@@ -215,6 +231,31 @@ std::string& replaceInPlace(std::string& str, const std::string::value_type* fro
}
std::string& replaceInPlace(std::string& str, const std::string::value_type from, const std::string::value_type to, std::string::size_type start)
{
if (from == to) return str;
std::string::size_type pos = 0;
do
{
pos = str.find(from, start);
if (pos != std::string::npos)
{
if (to) str[pos] = to;
else str.erase(pos, 1);
}
} while (pos != std::string::npos);
return str;
}
std::string& removeInPlace(std::string& str, const std::string::value_type ch, std::string::size_type start)
{
return replaceInPlace(str, ch, 0, start);
}
#endif