Project

General

Profile

Bug #1358 ยป floatrendering.patch

Wim Dumon, 07/18/2012 11:39 AM

View differences:

src/web/WebUtils.C
#include <stdlib.h>
#endif // WIN32
#ifndef WT_NO_SPIRIT
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/karma.hpp>
#endif // WT_NO_SPIRIT
namespace Wt {
namespace Utils {
......
return result;
}
char *round_str(double d, int digits, char *buf) {
static const int exp[] = { 1, 10, 100, 1000, 10000, 100000, 1000000 };
long long i = static_cast<long long>(d * exp[digits] + (d > 0 ? 0.49 : -0.49));
lltoa(i, buf);
char *num = buf;
if (num[0] == '-')
++num;
int len = std::strlen(num);
if (len <= digits) {
int shift = digits + 1 - len;
for (int i = digits + 1; i >= 0; --i) {
if (i >= shift)
num[i] = num[i - shift];
else
num[i] = '0';
#ifndef WT_NO_SPIRIT
namespace {
using namespace boost::spirit;
using namespace boost::spirit::karma;
// adjust rendering of nan and infinity: nan -> NaN; inf -> Infinity
template <typename T>
struct JavaScriptPolicy : karma::real_policies<T>
{
template <typename CharEncoding, typename Tag, typename OutputIterator>
static bool nan (OutputIterator& sink, T n, bool force_sign)
{
return sign_inserter::call(
sink, false, traits::test_negative(n), force_sign) &&
string_inserter<CharEncoding, Tag>::call(sink, "NaN");
}
len = digits + 1;
}
int dotPos = (std::max)(len - digits, 0);
for (int i = digits + 1; i >= 0; --i)
num[dotPos + i + 1] = num[dotPos + i];
num[dotPos] = '.';
template <typename CharEncoding, typename Tag, typename OutputIterator>
static bool inf (OutputIterator& sink, T n, bool force_sign)
{
return sign_inserter::call(
sink, false, traits::test_negative(n), force_sign) &&
string_inserter<CharEncoding, Tag>::call(sink, "Infinity");
}
};
typedef real_generator<double, JavaScriptPolicy<double> > KarmaJavaScriptDouble;
}
static inline char *generic_double_to_str(double d, char *buf)
{
using namespace boost::spirit;
using namespace boost::spirit::karma;
char *p = buf;
generate(p, KarmaJavaScriptDouble(), d);
*p = '\0';
return buf;
}
#else
static inline char *generic_double_to_str(double d, char *buf)
{
sprintf(buf, "%f", (float)d);
return buf;
}
#endif
char *round_str(double d, int digits, char *buf) {
#ifndef WT_NO_SPIRIT
return generic_double_to_str(d, buf);
#else
if (((d > 1 && d < 1000000) || (d < -1 && d > -1000000)) && digits < 7) {
// range where a very fast float->string converter works
// mainly intended to render floats for 2D drawing canvas
static const int exp[] = { 1, 10, 100, 1000, 10000, 100000, 1000000 };
long long i = static_cast<long long>(d * exp[digits] + (d > 0 ? 0.49 : -0.49));
lltoa(i, buf);
char *num = buf;
if (num[0] == '-')
++num;
int len = std::strlen(num);
if (len <= digits) {
int shift = digits + 1 - len;
for (int i = digits + 1; i >= 0; --i) {
if (i >= shift)
num[i] = num[i - shift];
else
num[i] = '0';
}
len = digits + 1;
}
int dotPos = (std::max)(len - digits, 0);
for (int i = digits + 1; i >= 0; --i)
num[dotPos + i + 1] = num[dotPos + i];
num[dotPos] = '.';
return buf;
} else {
// an implementation that covers everything
return generic_double_to_str(d, buf);
}
#endif
}
std::string urlEncode(const std::string& url, const std::string& allowed)
{
    (1-1/1)