strfmt.h

Go to the documentation of this file.
00001 #ifndef __strfmt_h__
00002 #define __strfmt_h__
00003 
00004 #include "asserts.h"
00005 #include "types.h"
00006 #include "estring.h"
00007 #include "rmath.h"
00008 
00009 /** Given an integral number, return a string with the number formatted as a
00010         human-readable machine-type size.  (Ex: 10240 becomes "10Kb") */
00011 template<class T>
00012 std::string size_to_string(
00013         T a_t,
00014         const std::string& a_base_size_unit = "b",
00015         uint16 a_width = 8,
00016         uint16 a_precision = 1, 
00017         uint16 a_kilo = 1024
00018         )
00019 {
00020         enum {
00021                 ones = 0,
00022                 kilo,
00023                 mega,
00024                 giga,
00025                 tera,
00026                 peta,
00027                 exa,
00028                 zetta,
00029                 yotta
00030         };
00031         const char* units[] = {
00032                 " ",
00033                 "K",
00034                 "M",
00035                 "G",
00036                 "T",
00037                 "P",
00038                 "E",
00039                 "Z",
00040                 "Y"
00041         };
00042         std::string es;
00043         int resolution = ones;
00044         std::string str;
00045         safe_num<T> quotient = a_t;
00046         safe_num<T> remainder = 0;
00047         safe_num<T> rmul = 10;
00048         safe_num<T> tmp;
00049 
00050         TRY_nomem(es = "Could not generate size-string: \"");
00051         TRY_nomem(es += estring(a_t));
00052         TRY_nomem(es += "\"");
00053 
00054         for (tmp = 1; tmp < a_precision; ++tmp) {
00055                 rmul *= 10;
00056         }
00057         while ((quotient >= a_kilo) && (resolution < yotta)) {
00058                 TRY(
00059                         tmp = quotient;
00060                         tmp *= rmul;
00061                         //
00062                         // *** NOT SURE ABOUT THIS:
00063                         // This involves a conversion from uint16 to T
00064                         // for safe_num<T>(a_kilo)
00065                         //
00066                         remainder = (tmp / safe_num<T>(a_kilo)) % rmul;
00067                         quotient /= a_kilo;
00068                         ,es);
00069                         resolution++;
00070         }
00071 
00072         if (resolution > ones) {
00073                 TRY(
00074                         str += estring(quotient.value()).fmt_str(
00075                                 a_width-(a_precision+1)-2,estring::right,' ','x'),
00076                         es);
00077                 TRY_nomem(str += ".");
00078                 TRY(
00079                         str += estring(remainder.value()).fmt_str(a_precision,estring::right,'0','x'),
00080                         es);
00081         }
00082         else {
00083                 TRY(
00084                         str += estring(quotient.value()).fmt_str(a_width-2,estring::right,' ','x'),
00085                         es);
00086         }
00087         TRY_nomem(str += units[resolution]);
00088         TRY_nomem(str += a_base_size_unit);
00089 
00090         return(str);
00091 }
00092 
00093 /** Given an integral number, return a string with the number formatted in a
00094  generic, human-readable format.  (Ex: 10240 becomes "10,240") */
00095 template<class T>
00096 std::string num_to_string(T a_t, uint16 a_width = 0)
00097 {
00098         std::string es;
00099         std::string tstr;
00100         estring str;
00101         std::string::size_type n;
00102         
00103         TRY_nomem(tstr = estring(a_t));
00104         TRY_nomem(es = "Could not generate num-string: \"");
00105         TRY_nomem(es += tstr);
00106         TRY_nomem(es += "\"");
00107 
00108         if (tstr.size() == 0) {
00109                 return(tstr);
00110         }
00111         
00112         n = tstr.size();
00113         while (n > 0) {
00114                 if (str.size() > 0) {
00115                         TRY_nomem(str = "," + str);
00116                 }
00117                 str = tstr[(n--)-1] + str; if (n == 0) break;
00118                 str = tstr[(n--)-1] + str; if (n == 0) break;
00119                 str = tstr[(n--)-1] + str;
00120         }
00121 
00122         if (a_width == 0) {
00123                 return(str);
00124         }
00125         str.width(a_width);
00126         str.align(estring::right);
00127         TRY_nomem(tstr = str.fmt_str());
00128 
00129         return(tstr);
00130 }
00131 
00132 /** Given an integral number, return a string with the number formated as a
00133  number of machine-type size per second.  (Ex: 10240 becomes "10Kb/s") */
00134 template<class T>
00135 std::string throughput_to_string(
00136         T a_t,
00137         const std::string& a_base_size_unit = "b",
00138         const std::string& a_base_time_unit = "s",
00139         uint16 a_width = 10,
00140         uint16 a_precision = 1,
00141         uint16 a_kilo = 1024
00142         )
00143 {
00144         std::string str;
00145 
00146         TRY_nomem(
00147                 str = size_to_string(a_t, a_base_size_unit, a_width-2, a_precision, a_kilo)
00148                 );
00149         TRY_nomem(str += "/");
00150         TRY_nomem(str += a_base_time_unit);
00151 
00152         return(str);
00153 }
00154 
00155 /** Given a count complete and a count total, calculate a percentage */
00156 template<typename T>
00157 std::string percent_string(const T& a_complete, const T& a_total)
00158 {
00159         safe_num<double> percent;
00160         estring es;
00161         estring estr;
00162         std::string str;
00163 
00164         es = "Could not calculate percentage";
00165         if (a_complete == static_cast<T>(0)) {
00166                 percent = static_cast<T>(0);
00167         }
00168         else if (a_total == static_cast<T>(0)) {
00169                 TRY_nomem(str = "??.?%");
00170                 return(str);
00171         }
00172         else {
00173                 TRY (
00174                         percent = static_cast<double>(a_complete);
00175                         percent *= 100;
00176                         percent /= static_cast<double>(a_total);
00177                         ,es);
00178         }
00179         estr.width(5);
00180         estr.align(estring::right);
00181         estr.fillchar(' ');
00182         estr.precision(1);
00183         estr = percent.value();
00184         TRY_nomem(str = estr.fmt_str());
00185         TRY_nomem(str += "%");
00186 
00187         return(str);
00188 }
00189 
00190 #endif

Generated on Tue Jul 1 12:09:28 2008 for rvm by  doxygen 1.5.1