00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "helpers.h"
00024 #include "common/misc/stringutils.h"
00025
00026 #include <cassert>
00027 #include <cmath>
00028 #include <iomanip>
00029 #include <sstream>
00030
00031 using namespace sheep;
00032 using namespace std;
00033 using namespace toxic;
00034
00035 PrefixStack::PrefixStack() {}
00036
00037 PrefixStack::PrefixStack(const string &s) {
00038 Push(s);
00039 }
00040
00041 void PrefixStack::Push(const string &s) {
00042 push_back(m_prefix);
00043 m_prefix += s;
00044 }
00045
00046 void PrefixStack::Pop() {
00047 m_prefix = back();
00048 pop_back();
00049 }
00050
00051 const string &PrefixStack::operator()() const {
00052 return m_prefix;
00053 }
00054
00055 void Indenter::Indent(int spaces ) {
00056 push_back(m_indent_string);
00057 m_indent_string += string(spaces, ' ');
00058 }
00059
00060 void Indenter::Unindent() {
00061 m_indent_string = back();
00062 pop_back();
00063 }
00064
00065 const string &Indenter::operator()() const {
00066 return m_indent_string;
00067 }
00068
00069 string toxic::Ratio(int64 n, int64 d) {
00070 if(d == 0)
00071 return "not available";
00072
00073 stringstream ss;
00074
00075 ss << fixed << setprecision(1);
00076 ss << static_cast<float>(n) / d;
00077
00078 return ss.str();
00079 }
00080
00081 string toxic::Percentage(int64 n, int64 d) {
00082 if(d == 0)
00083 return "not available";
00084
00085 const float p = (100.0f * n) / d;
00086
00087 if(p > 0.0f && p < 0.1f)
00088 return "<0.1%";
00089 else {
00090 stringstream ss;
00091
00092 ss << fixed << setprecision(1);
00093 ss << p;
00094 ss << '%';
00095
00096 return ss.str();
00097 }
00098 }
00099
00100
00101
00102 string toxic::ConvertNumberToString(int64 n) {
00103
00104
00105 static char digits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
00106 const int BUFSIZE = 1000;
00107 char buf[BUFSIZE];
00108 char *p = buf;
00109
00110
00111 bool is_neg = n < 0;
00112 if(is_neg)
00113 n = -n;
00114
00115
00116 int ndigits = 0;
00117
00118
00119 do {
00120 if(ndigits == 3) {
00121
00122 assert(p - buf < BUFSIZE);
00123 *p++ = ',';
00124 ndigits = 0;
00125 }
00126
00127
00128 assert(p - buf < BUFSIZE);
00129 *p++ = digits[n % 10];
00130 ++ndigits;
00131
00132
00133 n /= 10;
00134 } while(n > 0);
00135
00136
00137 assert(p - buf > 0);
00138
00139
00140 string s;
00141 s.reserve(p - buf + is_neg ? 1 : 0);
00142
00143
00144 if(is_neg)
00145 s += '-';
00146
00147
00148 while(p > buf)
00149 s += *(--p);
00150
00151 return s;
00152 }
00153
00154 namespace {
00155 inline
00156 float ratio(int64 n, int64 d) {
00157 return static_cast<float>(n) / d;
00158 }
00159 }
00160
00161 string toxic::ConvertSizeToString(int64 size, bool omit_details ) {
00162 assert(size >= 0);
00163
00164 string s = "";
00165
00166 const int64 KB = 1024;
00167
00168
00169
00170 if(size == 0)
00171 s += "0 byte";
00172 else if(size == 1)
00173 s += "1 byte";
00174 else if(size < KB)
00175 s += ConvertNumberToString(size) + " bytes";
00176 else {
00177 int64 n = static_cast<int64>(ceil(ratio(size, KB)));
00178 s += ConvertNumberToString(n) + " KB";
00179 }
00180
00181
00182
00183
00184
00185
00186
00187 if(size >= KB && !omit_details)
00188 s += " (" + ConvertNumberToString(size) + " bytes)";
00189
00190 return s;
00191 }