Merge branch 'proxy-time-profiles'
authorThomas Jarosch <thomas.jarosch@intra2net.com>
Thu, 3 Mar 2011 09:36:52 +0000 (10:36 +0100)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Thu, 3 Mar 2011 09:36:52 +0000 (10:36 +0100)
Conflicts:
generate/test/Makefile.am

src/stringfunc.cpp
src/stringfunc.hxx
test/stringfunc.cpp

index 16cd6bd..995b71f 100644 (file)
@@ -892,60 +892,94 @@ string to_upper(const string &src)
 }
 #endif
 
-string nice_unit_format(int input)
+const int MAX_UNIT_FORMAT_SYMBOLS = 6;
+
+const string shortUnitFormatSymbols[MAX_UNIT_FORMAT_SYMBOLS] = {
+        " B",
+        " KB",
+        " MB",
+        " GB",
+        " TB",
+        " PB"
+};
+
+const string longUnitFormatSymbols[MAX_UNIT_FORMAT_SYMBOLS] = {
+        i18n_noop(" Bytes"),
+        i18n_noop(" KBytes"),
+        i18n_noop(" MBytes"),
+        i18n_noop(" GBytes"),
+        i18n_noop(" TBytes"),
+        i18n_noop(" PBytes")
+};
+
+
+long double rounding_upwards(
+        long double number,
+        const int rounding_multiplier
+)
 {
-   float size = input;
-   int sizecount = 0;
+    long double rounded_number;
+    rounded_number = number * rounding_multiplier;
+    rounded_number += 0.5;
+    rounded_number = (int64_t) (rounded_number);
+    rounded_number = (long double) (rounded_number) / (long double) (rounding_multiplier);
+
+    return rounded_number;
+}
 
-   while (size > 1000)
+
+string nice_unit_format(
+        const int64_t input,
+        const UnitFormat format,
+        const UnitBase base
+)
+{
+   // select the system of units (decimal or binary)
+   int multiple = 0;
+   if (base == UnitBase1000)
    {
-      size = size / 1000;
-      sizecount++;
+       multiple = 1000;
+   }
+   else
+   {
+       multiple = 1024;
    }
 
-   float tmp;                       // round
-   tmp = size*10;
-   tmp += 0.5;
-   tmp = int (tmp);
-   tmp = float (tmp) /float (10);
-   size = tmp;
+   long double size = input;
 
-   ostringstream out;
+   // check the size of the input number to fit in the appropriate symbol
+   int sizecount = 0;
+   while (size > multiple)
+   {
+       size = size / multiple;
+       sizecount++;
+
+       // rollback to the previous values and stop the loop when cannot
+       // represent the number length.
+       if (sizecount >= MAX_UNIT_FORMAT_SYMBOLS)
+       {
+           size = size * multiple;
+           sizecount--;
+           break;
+       }
+   }
+
+   // round the input number "half up" to multiples of 10
+   const int rounding_multiplier = 10;
+   size = rounding_upwards(size, rounding_multiplier);
 
+   // format the input number, placing the appropriate symbol
+   ostringstream out;
    out.setf (ios::fixed);
-   out.precision (2);
-   switch (sizecount)
+   if (format == ShortUnitFormat)
    {
-      case 0:
-         out << size << i18n (" Bytes");
-         break;
-      case 1:
-         out << size << i18n (" KBytes");
-         break;
-      case 2:
-         out << size << i18n (" MBytes");
-         break;
-      case 3:
-         out << size << i18n (" GBytes");
-         break;
-      case 4:
-         out << size << i18n (" TBytes");
-         break;
-      case 5:
-         out << size << i18n (" PBytes");
-         break;
-      case 6:
-         out << size << i18n (" EBytes");
-         break;
-      case 7:
-         out << size << i18n (" ZBytes");
-         break;
-      case 8:
-         out << size << i18n (" YBytes");
-         break;
-      default:
-         out << size << "*10^" << (sizecount*3)<< i18n (" Bytes");
-         break;
+       out.precision(1);
+       out << size << i18n( shortUnitFormatSymbols[sizecount].c_str() );
+   }
+   else
+   {
+       out.precision (2);
+       out << size << i18n( longUnitFormatSymbols[sizecount].c_str() );
    }
 
    return out.str();
index b211a17..3ee7a0b 100644 (file)
@@ -21,6 +21,7 @@
 #include <string>
 #include <sstream>
 #include <stdexcept>
+#include <sys/types.h>
 
 namespace I2n
 {
@@ -190,7 +191,22 @@ using I2n::to_lower;
 using I2n::to_upper;
 #endif
 
-std::string nice_unit_format(int input);
+
+enum UnitBase {
+    UnitBase1000, // SI decimal, composed by multiples of 1000 (KB, MB, etc.)
+    UnitBase1024 // IEC binary, composed by multiples of 1024 (KiB, MiB, etc. )
+};
+
+enum UnitFormat {
+    ShortUnitFormat, // B, KB, MB, ...
+    LongUnitFormat // Byte, KByte, MByte, ...
+};
+
+std::string nice_unit_format(
+        const int64_t input,
+        const UnitFormat format = ShortUnitFormat,
+        const UnitBase base = UnitBase1024
+);
 
 bool replace_all(std::string &base, const std::string *ist, const std::string *soll);
 bool replace_all(std::string &base, const char *ist, const char *soll);
index de9db50..749db12 100644 (file)
@@ -85,6 +85,8 @@ BOOST_AUTO_TEST_CASE(strip_html_tags2)
     BOOST_CHECK_EQUAL(string("Was für ein schöner Tag, finden Sie nicht?"), output);
 }
 
+
+
 BOOST_AUTO_TEST_CASE(html_entities1)
 {
     string output = html_entities("\xC3\xA4\xC3\xB6\xC3\xBC");
@@ -103,6 +105,147 @@ BOOST_AUTO_TEST_CASE(html_entities3)
     BOOST_CHECK_EQUAL(string("&#270; &#3889; &#32904;"), output);
 }
 
+
+
+BOOST_AUTO_TEST_CASE(nice_unit_format1)
+{
+    const int64_t two_bytes = 2;
+
+    string output = nice_unit_format(two_bytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2.00 Bytes"), output);
+
+    output = nice_unit_format(two_bytes);
+    BOOST_CHECK_EQUAL(string("2.0 B"), output);
+}
+
+BOOST_AUTO_TEST_CASE(nice_unit_format2)
+{
+    const int64_t two_kilobytes = 2000;
+
+    string output = nice_unit_format(two_kilobytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2.00 KBytes"), output);
+
+    output = nice_unit_format(two_kilobytes);
+    BOOST_CHECK_EQUAL(string("2.0 KB"), output);
+
+    const int64_t two_and_half_kilobytes = 2500;
+
+    output = nice_unit_format(two_and_half_kilobytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2.50 KBytes"), output);
+
+    output = nice_unit_format(two_and_half_kilobytes);
+    BOOST_CHECK_EQUAL(string("2.4 KB"), output);
+}
+
+BOOST_AUTO_TEST_CASE(nice_unit_format3)
+{
+    const int64_t two_megabytes = 2000000;
+
+    string output = nice_unit_format(two_megabytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2.00 MBytes"), output);
+
+    output = nice_unit_format(two_megabytes);
+    BOOST_CHECK_EQUAL(string("1.9 MB"), output);
+
+    const int64_t two_and_half_megabytes = 2500000;
+
+    output = nice_unit_format(two_and_half_megabytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2.50 MBytes"), output);
+
+    output = nice_unit_format(two_and_half_megabytes);
+    BOOST_CHECK_EQUAL(string("2.4 MB"), output);
+
+}
+
+BOOST_AUTO_TEST_CASE(nice_unit_format4)
+{
+    const int64_t two_gigabytes = 2000000000LL;
+
+    string output = nice_unit_format(two_gigabytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2.00 GBytes"), output);
+
+    output = nice_unit_format(two_gigabytes);
+    BOOST_CHECK_EQUAL(string("1.9 GB"), output);
+
+    const int64_t two_and_half_gigabytes = 2500000000LL;
+
+    output = nice_unit_format(two_and_half_gigabytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2.50 GBytes"), output);
+
+    output = nice_unit_format(two_and_half_gigabytes);
+    BOOST_CHECK_EQUAL(string("2.3 GB"), output);
+}
+
+BOOST_AUTO_TEST_CASE(nice_unit_format5)
+{
+    const int64_t two_terabytes = 2000000000000LL;
+
+    string output = nice_unit_format(two_terabytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2.00 TBytes"), output);
+
+    output = nice_unit_format(two_terabytes);
+    BOOST_CHECK_EQUAL(string("1.8 TB"), output);
+
+    const int64_t two_and_half_terabytes = 2500000000000LL;
+
+    output = nice_unit_format(two_and_half_terabytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2.50 TBytes"), output);
+
+    output = nice_unit_format(two_and_half_terabytes);
+    BOOST_CHECK_EQUAL(string("2.3 TB"), output);
+}
+
+BOOST_AUTO_TEST_CASE(nice_unit_format6)
+{
+    const int64_t two_petabytes = 2000000000000000LL;
+
+    string output = nice_unit_format(two_petabytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2.00 PBytes"), output);
+
+    output = nice_unit_format(two_petabytes);
+    BOOST_CHECK_EQUAL(string("1.8 PB"), output);
+
+    const int64_t two_and_half_petabytes = 2500000000000000LL;
+
+    output = nice_unit_format(two_and_half_petabytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2.50 PBytes"), output);
+
+    output = nice_unit_format(two_and_half_petabytes);
+    BOOST_CHECK_EQUAL(string("2.2 PB"), output);
+}
+
+BOOST_AUTO_TEST_CASE(nice_unit_format7)
+{
+    const int64_t two_exabytes = 2000000000000000000LL;
+
+    string output = nice_unit_format(two_exabytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2000.00 PBytes"), output);
+
+    output = nice_unit_format(two_exabytes);
+    BOOST_CHECK_EQUAL(string("1776.4 PB"), output);
+
+    const int64_t two_and_half_exabytes = 2500000000000000000LL;
+
+    output = nice_unit_format(two_and_half_exabytes, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("2500.00 PBytes"), output);
+
+    output = nice_unit_format(two_and_half_exabytes);
+    BOOST_CHECK_EQUAL(string("2220.4 PB"), output);
+}
+
+BOOST_AUTO_TEST_CASE(nice_unit_format8)
+{
+    const int64_t max_representable_64bits_number = 9223372036854775807LL;
+
+    string output = nice_unit_format(max_representable_64bits_number, LongUnitFormat, UnitBase1000);
+    BOOST_CHECK_EQUAL(string("9223.40 PBytes"), output);
+
+    output = nice_unit_format(max_representable_64bits_number);
+    BOOST_CHECK_EQUAL(string("8192.0 PB"), output);
+}
+
+
+
 BOOST_AUTO_TEST_CASE(imaputf7_to_utf8)
 {
     string output = utf7imap_to_utf8("Sp&AOQ-m");