Add a si_string function to string_utils.

Make the add-on manager and screenshot hotkey use it.
This commit is contained in:
Alexander van Gessel 2011-09-01 21:09:26 +01:00
parent e8f6531a86
commit 8cac75d2bc
4 changed files with 87 additions and 28 deletions

View File

@ -408,34 +408,8 @@ namespace {
*/
static std::string format_file_size(double size)
{
const double k = 1024;
if(size > 0.0) {
std::string size_postfix = _("B"); // bytes
if(size > k) {
size /= k;
size_postfix = _("KB"); // kilobytes
if(size > k) {
size /= k;
size_postfix = _("MB"); // megabytes
if(size > k) {
size /= k;
size_postfix = _("GB"); // gigabytes
}
}
}
std::ostringstream stream;
#ifdef _MSC_VER
// Visual C++ makes 'precision' set the number of decimal places.
// Other platforms make it set the number of significant figures
stream.precision(1);
stream << std::fixed << size << size_postfix;
#else
if (size < 100) stream.precision(3);
else size = trunc(size);
stream << size << size_postfix;
#endif
return stream.str();
return utils::si_string(size);
} else {
return "";
}

View File

@ -1179,7 +1179,7 @@ void execute_command(display& disp, HOTKEY_COMMAND command, command_executor* ex
int size = disp.screenshot(filename, map_screenshot);
if (size > 0) {
std::stringstream res;
res << filename << " ( " << size/1000000 <<" "<< (size/1000)%1000 << " kB )";
res << filename << " ( " << utils::si_string(size, true, "B") << " )";
gui2::show_message(disp.video(), _("Screenshot done"), res.str());
} else
gui2::show_message(disp.video(), _("Screenshot done"), "");

View File

@ -26,6 +26,7 @@
#include "log.hpp"
#include "serialization/string_utils.hpp"
#include "../util.hpp"
#include <boost/array.hpp>
static lg::log_domain log_engine("engine");
#define ERR_GENERAL LOG_STREAM(err, lg::general)
@ -259,6 +260,82 @@ std::string signed_value(int val)
return oss.str();
}
template <typename T>
void si_string_impl_stream_write(std::stringstream &ss, T input) {
#ifdef _MSC_VER
// Visual C++ makes 'precision' set the number of decimal places.
// Other platforms make it set the number of significant figures
ss.precision(1);
ss << std::fixed
<< input;
#else
ss.precision(3);
ss << input;
#endif
}
template <> void si_string_impl_stream_write(std::stringstream &ss, int input) {
ss << input;
}
template <> void si_string_impl_stream_write(std::stringstream &ss, long input) {
ss << input;
}
template <> void si_string_impl_stream_write(std::stringstream &ss, long long input) {
ss << input;
}
template <typename T>
std::string si_string_impl(T input, bool base2, std::string unit) {
const int multiplier = base2 ? 1024 : 1000;
// (input == -input) can happen if we're at the minimum of the native signed integer type, so make sure we don't recurse infinitely
// It will still give bad output, but it won't overflow the stack
if (input < 0 && input != -input)
return unicode_minus + si_string(-input, base2, unit);
typedef boost::array<std::string, 9> strings9;
strings9 prefixes;
strings9::const_iterator prefix;
if (input < 1.0) {
strings9 tmp = { { "", "m", "μ", "n", "p", "f", "a", "z", "y" } };
prefixes = tmp;
prefix = prefixes.begin();
while (input < 1.0 && *prefix != prefixes.back()) {
input *= multiplier;
++prefix;
}
} else {
strings9 tmp = { { "", "k", "M", "G", "T", "P", "E", "Z", "Y" } };
prefixes = tmp;
prefix = prefixes.begin();
while (input > multiplier && *prefix != prefixes.back()) {
input /= multiplier;
++prefix;
}
}
std::stringstream ss;
si_string_impl_stream_write(ss, input);
ss << ' '
<< *prefix
<< (base2 ? "i" : "")
<< unit;
return ss.str();
}
std::string si_string(double input, bool base2, std::string unit) {
return si_string_impl(input, base2, unit);
}
std::string si_string(int input, bool base2, std::string unit) {
return si_string_impl(input, base2, unit);
}
std::string si_string(long input, bool base2, std::string unit) {
return si_string_impl(input, base2, unit);
}
std::string si_string(long long input, bool base2, std::string unit) {
return si_string_impl(input, base2, unit);
}
std::string si_string(long double input, bool base2, std::string unit) {
return si_string_impl(input, base2, unit);
}
static bool is_username_char(char c) {
return ((c == '_') || (c == '-'));
}

View File

@ -138,6 +138,14 @@ std::string signed_value(int val);
/** Convert into a percentage (using the Unicode "" and +0% convention */
inline std::string signed_percent(int val) {return signed_value(val) + "%";}
/** Convert into a string with an SI-postfix */
std::string si_string(double input, bool base2=true, std::string unit="B");
std::string si_string(int input, bool base2=true, std::string unit="B");
/* Some extra-long versions */
std::string si_string(long input, bool base2=true, std::string unit="B");
std::string si_string(long long input, bool base2=true, std::string unit="B");
std::string si_string(long double input, bool base2=true, std::string unit="B");
/**
* Try to complete the last word of 'text' with the 'wordlist'.
*