Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

helpers.cpp

Go to the documentation of this file.
00001 /*
00002     toxic - A Global Illumination Renderer
00003     Copyright (C) 2003-2004 Francois Beaune
00004     Contact: http://toxicengine.sourceforge.net/
00005 
00006     This file is part of toxic.
00007 
00008     toxic is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     toxic is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with toxic; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 #include "helpers.h"    // include first
00024 #include "common/misc/stringutils.h"
00025 
00026 #include <cassert>
00027 #include <cmath>    // std::ceil()
00028 #include <iomanip>  // std::setprecision()
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 /*= 2*/) {
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 //!\todo Implement for floating point arguments, then use it in
00101 //! the Ratio() function (in this file).
00102 string toxic::ConvertNumberToString(int64 n) {
00103     //!\todo Rewrite using std::vector<> (or better, std::string).
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     // Handle negative numbers.
00111     bool is_neg = n < 0;
00112     if(is_neg)
00113         n = -n;
00114 
00115     // Counter to insert commas at the right places.
00116     int ndigits = 0;
00117 
00118     // Build the string in reverse order.
00119     do {
00120         if(ndigits == 3) {
00121             // Make sure there's still room in the buffer.
00122             assert(p - buf < BUFSIZE);
00123             *p++ = ',';
00124             ndigits = 0;
00125         }
00126 
00127         // Make sure there's still room in the buffer.
00128         assert(p - buf < BUFSIZE);
00129         *p++ = digits[n % 10];
00130         ++ndigits;
00131 
00132         // Next digit.
00133         n /= 10;
00134     } while(n > 0);
00135 
00136     // Make sure the resulting string contains at least one character.
00137     assert(p - buf > 0);
00138 
00139     // Allocate the final string.
00140     string s;
00141     s.reserve(p - buf + is_neg ? 1 : 0);
00142 
00143     // Insert unary minus if input number was negative.
00144     if(is_neg)
00145         s += '-';
00146 
00147     // Copy the C-string to the final string.
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 /*= false*/) {
00162     assert(size >= 0);
00163 
00164     string s = "";
00165 
00166     const int64 KB = 1024;
00167 //  const int64 MB = 1024 * KB;
00168 //  const int64 GB = 1024 * MB;
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 /*if(size < MB)*/ {
00177         int64 n = static_cast<int64>(ceil(ratio(size, KB)));
00178         s += ConvertNumberToString(n) + " KB";
00179     } /*else if(size < GB) {
00180         int64 n = static_cast<int64>(ceil(ratio(size, MB)));
00181         s += ConvertNumberToString(n) + " MB";
00182     } else {
00183         int64 n = static_cast<int64>(ceil(ratio(size, GB)));
00184         s += ConvertNumberToString(n) + " GB";
00185     }*/
00186 
00187     if(size >= KB && !omit_details)
00188         s += " (" + ConvertNumberToString(size) + " bytes)";
00189 
00190     return s;
00191 }

Generated on Tue May 11 01:31:50 2004 for toxic by doxygen 1.3.6