From d44b4f5749b07dde98a9b34edb7fc05a3aaef3c1 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 9 Jan 2013 11:06:22 -0800 Subject: [PATCH] copy numeric2string function to pgsql2sqlite code (no need to keep in sql_utils.hpp) and fix compile --- utils/pgsql2sqlite/pgsql2sqlite.hpp | 115 +++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/utils/pgsql2sqlite/pgsql2sqlite.hpp b/utils/pgsql2sqlite/pgsql2sqlite.hpp index 3874ead7a..47f62962c 100644 --- a/utils/pgsql2sqlite/pgsql2sqlite.hpp +++ b/utils/pgsql2sqlite/pgsql2sqlite.hpp @@ -44,6 +44,119 @@ #include #include +static std::string numeric2string(const char* buf) +{ + boost::int16_t ndigits = int2net(buf); + boost::int16_t weight = int2net(buf+2); + boost::int16_t sign = int2net(buf+4); + boost::int16_t dscale = int2net(buf+6); + + boost::scoped_array digits(new boost::int16_t[ndigits]); + for (int n=0; n < ndigits ;++n) + { + digits[n] = int2net(buf+8+n*2); + } + + std::ostringstream ss; + + if (sign == 0x4000) ss << "-"; + + int i = std::max(weight,boost::int16_t(0)); + int d = 0; + + // Each numeric "digit" is actually a value between 0000 and 9999 stored in a 16 bit field. + // For example, the number 1234567809990001 is stored as four digits: [1234] [5678] [999] [1]. + // Note that the last two digits show that the leading 0's are lost when the number is split. + // We must be careful to re-insert these 0's when building the string. + + while ( i >= 0) + { + if (i <= weight && d < ndigits) + { + // All digits after the first must be padded to make the field 4 characters long + if (d != 0) + { +#ifdef _WINDOWS + int dig = digits[d]; + if (dig < 10) + { + ss << "000"; // 0000 - 0009 + } + else if (dig < 100) + { + ss << "00"; // 0010 - 0099 + } + else + { + ss << "0"; // 0100 - 0999; + } +#else + switch(digits[d]) + { + case 0 ... 9: + ss << "000"; // 0000 - 0009 + break; + case 10 ... 99: + ss << "00"; // 0010 - 0099 + break; + case 100 ... 999: + ss << "0"; // 0100 - 0999 + break; + } +#endif + } + ss << digits[d++]; + } + else + { + if (d == 0) + ss << "0"; + else + ss << "0000"; + } + + i--; + } + if (dscale > 0) + { + ss << '.'; + // dscale counts the number of decimal digits following the point, not the numeric digits + while (dscale > 0) + { + int value; + if (i <= weight && d < ndigits) + value = digits[d++]; + else + value = 0; + + // Output up to 4 decimal digits for this value + if (dscale > 0) { + ss << (value / 1000); + value %= 1000; + dscale--; + } + if (dscale > 0) { + ss << (value / 100); + value %= 100; + dscale--; + } + if (dscale > 0) { + ss << (value / 10); + value %= 10; + dscale--; + } + if (dscale > 0) { + ss << value; + dscale--; + } + + i--; + } + } + return ss.str(); +} + + namespace mapnik { template @@ -262,7 +375,7 @@ void pgsql2sqlite(Connection conn, } case 1700: { - std::string str = mapnik::sql_utils::numeric2string(buf); + std::string str = numeric2string(buf); try { double val = boost::lexical_cast(str);