[core] refactor util::toString to use RapidJSON's stringification

This commit is contained in:
Konstantin Käfer
2018-10-18 21:02:17 +02:00
parent 59c5754fa8
commit 7692be5d15
4 changed files with 116 additions and 55 deletions

View File

@@ -1,27 +1,14 @@
#pragma once
#include <string>
#include <cassert>
#include <cstdlib>
#include <exception>
#include <type_traits>
// Polyfill needed by Qt when building for Android with GCC
#if defined(__ANDROID__) && defined(__GLIBCXX__)
// TODO: remove use std::to_string to avoid using <sstream>
#include <sstream>
namespace std {
template <typename T>
std::string to_string(T value)
{
std::ostringstream oss;
oss << value;
return oss.str();
}
inline int stoi(const std::string &str)
{
return atoi(str.c_str());
@@ -38,44 +25,70 @@ inline float stof(const std::string &str) {
namespace mbgl {
namespace util {
template <class T>
inline std::string toString(T t) {
return std::to_string(t);
}
inline std::string toString(int8_t num) {
return std::to_string(int(num));
}
inline std::string toString(uint8_t num) {
return std::to_string(unsigned(num));
}
std::string toString(float, bool decimal = false);
std::string toString(int64_t);
std::string toString(uint64_t);
std::string toString(int32_t);
std::string toString(uint32_t);
std::string toString(double, bool decimal = false);
std::string toString(long double, bool decimal = false);
inline std::string toString(int16_t t) {
return toString(static_cast<int32_t>(t));
}
inline std::string toString(uint16_t t) {
return toString(static_cast<uint32_t>(t));
}
inline std::string toString(int8_t t) {
return toString(static_cast<int32_t>(t));
}
inline std::string toString(uint8_t t) {
return toString(static_cast<uint32_t>(t));
}
template <typename = std::enable_if<!std::is_same<uint64_t, unsigned long>::value>>
inline std::string toString(unsigned long t) {
return toString(static_cast<uint64_t>(t));
}
template <typename = std::enable_if<!std::is_same<uint64_t, unsigned long long>::value>>
inline std::string toString(unsigned long long t) {
return toString(static_cast<uint64_t>(t));
}
inline std::string toString(float t, bool decimal = false) {
return toString(static_cast<double>(t), decimal);
}
inline std::string toString(long double t, bool decimal = false) {
return toString(static_cast<double>(t), decimal);
}
std::string toString(std::exception_ptr);
template <class T>
std::string toString(T) = delete;
std::string toHex(size_t);
inline std::string toString(std::exception_ptr error) {
assert(error);
if (!error) {
return "(null)";
}
try {
std::rethrow_exception(error);
} catch (const std::exception& ex) {
return ex.what();
} catch (...) {
return "Unknown exception type";
}
}
inline float stof(const std::string& str) {
return std::stof(str);
}
} // namespace util
} // namespace mbgl
// Android's libstdc++ doesn't have std::to_string()
#if defined(__ANDROID__) && defined(__GLIBCXX__)
namespace std {
template <typename T>
inline std::string to_string(T value) {
return mbgl::util::toString(value);
}
} // namespace std
#endif

View File

@@ -33,7 +33,7 @@ class FeatureIdVisitor {
public:
template<class T>
std::string operator()(const T& i) const {
return std::to_string(i);
return util::toString(i);
}
std::string operator()(const std::string& i) const {

View File

@@ -151,9 +151,9 @@ void HTTPRequest::onResponse(jni::JNIEnv& env, int code,
}
response.error = std::make_unique<Error>(Error::Reason::RateLimit, "HTTP status code 429", http::parseRetryHeaders(retryAfter, xRateLimitReset));
} else if (code >= 500 && code < 600) {
response.error = std::make_unique<Error>(Error::Reason::Server, std::string{ "HTTP status code " } + std::to_string(code));
response.error = std::make_unique<Error>(Error::Reason::Server, std::string{ "HTTP status code " } + util::toString(code));
} else {
response.error = std::make_unique<Error>(Error::Reason::Other, std::string{ "HTTP status code " } + std::to_string(code));
response.error = std::make_unique<Error>(Error::Reason::Other, std::string{ "HTTP status code " } + util::toString(code));
}
async.send();

View File

@@ -1,19 +1,67 @@
#include <mbgl/util/string.hpp>
#include <mbgl/util/dtoa.hpp>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
#include <cassert>
namespace mbgl {
namespace util {
std::string toString(float num, bool decimal) {
return dtoa(num, decimal);
std::string toString(int32_t t) {
rapidjson::StringBuffer s;
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
writer.Int(t);
return s.GetString();
}
std::string toString(double num, bool decimal) {
return dtoa(num, decimal);
std::string toString(uint32_t t) {
rapidjson::StringBuffer s;
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
writer.Uint(t);
return s.GetString();
}
std::string toString(long double num, bool decimal) {
return dtoa(num, decimal);
std::string toString(int64_t t) {
rapidjson::StringBuffer s;
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
writer.Int64(t);
return s.GetString();
}
std::string toString(uint64_t t) {
rapidjson::StringBuffer s;
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
writer.Uint64(t);
return s.GetString();
}
std::string toString(double t, bool decimal) {
rapidjson::StringBuffer s;
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
writer.Double(t);
std::string data = s.GetString();
if (!decimal && data.length() >= 3 && data[data.length() - 1] == '0' && data[data.length() - 2] == '.') {
// Remove trailing ".0" for integers
data.resize(data.length() - 2);
}
return data;
}
std::string toString(std::exception_ptr error) {
assert(error);
if (!error) {
return "(null)";
}
try {
std::rethrow_exception(error);
} catch (const std::exception& ex) {
return ex.what();
} catch (...) {
return "Unknown exception type";
}
}
namespace {