thin-provisioning-tools/base/disk_units.cc

86 lines
1.5 KiB
C++

#include "base/disk_units.h"
#include <boost/lexical_cast.hpp>
#include <cmath>
#include <stdexcept>
using namespace std;
using namespace boost;
//----------------------------------------------------------------
unsigned long long
base::disk_unit_multiplier(disk_unit u)
{
switch (u) {
case UNIT_BYTE:
return 1;
case UNIT_SECTOR:
return 512;
case UNIT_kB:
return 1000;
case UNIT_MB:
return 1000000;
case UNIT_GB:
return 1000000000ull;
case UNIT_TB:
return 1000000000000ull;
case UNIT_PB:
return 1000000000000000ull;
case UNIT_KiB:
return 1024ull;
case UNIT_MiB:
return 1024ull * 1024ull;
case UNIT_GiB:
return 1024ull * 1024ull * 1024ull;
case UNIT_TiB:
return 1024ull * 1024ull * 1024ull * 1024ull;
case UNIT_PiB:
return 1024ull * 1024ull * 1024ull * 1024ull * 1024ull;
}
throw runtime_error("unknown unit type");
return 1;
}
namespace {
unsigned long long round_ull(unsigned long long n, unsigned long long d) {
return round(static_cast<double>(n) / static_cast<double>(d));
}
}
string
base::format_disk_unit(unsigned long long numerator, disk_unit u)
{
numerator *= disk_unit_multiplier(u);
unsigned i;
for (i = 0; numerator > 1024ull * 1024ull; i++)
numerator /= 1024ull;
if (numerator > 8 * 1024ull) {
numerator = round_ull(numerator, 1024ull);
i++;
}
char const *extensions[] = {
"", "KiB", "MiB", "GiB", "TiB", "PiB"
};
// FIXME: check subscript of i
return lexical_cast<string>(numerator) + extensions[i];
}
//----------------------------------------------------------------