# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlCore/Say.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    00029 /*                                                                                    */
    00030 /**************************************************************************************/
    00031
    00032 #include <vlCore/Say.hpp>
    00033 #include <cmath>
    00034
    00035 using namespace vl;
    00036
    00037 SayArg::SayArg()
    00038 {
    00039   init();
    00040 }
    00041
    00042 SayArg::SayArg(void* d)
    00043 {
    00044   init();
    00045   ulonglong = reinterpret_cast<unsigned long long>(d);
    00046   type = ULONGLONG;
    00047 }
    00048
    00049 SayArg::SayArg(const std::string& d)
    00050 {
    00051   init();
    00052   str = d.c_str();
    00053   type = STRING;
    00054 }
    00055
    00056 SayArg::SayArg(const unsigned char* d)
    00057 {
    00058   init();
    00059   if (d)
    00060     str = (const char*)d;
    00061   type = STRING;
    00062 }
    00063
    00064 SayArg::SayArg(const char* d)
    00065 {
    00066   init();
    00067   if (d)
    00068     str = d;
    00069   type = STRING;
    00070 }
    00071
    00072 SayArg::SayArg(const String& d)
    00073 {
    00074   init();
    00075   str = d;
    00076   type = STRING;
    00077 }
    00078
    00079 SayArg::SayArg(double d)
    00080 {
    00081   init();
    00082   float64 = d;
    00083   type = FLOAT64;
    00084 }
    00085
    00086 SayArg::SayArg(float d)
    00087 {
    00088   init();
    00089   float64 = d;
    00090   type = FLOAT64;
    00091 }
    00092
    00093 SayArg::SayArg(unsigned char d)
    00094 {
    00095   init();
    00096   ulonglong = d;
    00097   type = ULONGLONG;
    00098 }
    00099
    00100 SayArg::SayArg(signed char d)
    00101 {
    00102   init();
    00103   slonglong = d;
    00104   type = SLONGLONG;
    00105 }
    00106
    00107 SayArg::SayArg(unsigned short d)
    00108 {
    00109   init();
    00110   ulonglong = d;
    00111   type = ULONGLONG;
    00112 }
    00113
    00114 SayArg::SayArg(signed short d)
    00115 {
    00116   init();
    00117   slonglong = d;
    00118   type = SLONGLONG;
    00119 }
    00120
    00121 SayArg::SayArg(unsigned int d)
    00122 {
    00123   init();
    00124   ulonglong = d;
    00125   type = ULONGLONG;
    00126 }
    00127
    00128 SayArg::SayArg(signed int d)
    00129 {
    00130   init();
    00131   slonglong = d;
    00132   type = SLONGLONG;
    00133 }
    00134
    00135 SayArg::SayArg(unsigned long d)
    00136 {
    00137   init();
    00138   ulonglong = d;
    00139   type = ULONGLONG;
    00140 }
    00141
    00142 SayArg::SayArg(signed long d)
    00143 {
    00144   init();
    00145   slonglong = d;
    00146   type = SLONGLONG;
    00147 }
    00148
    00149 SayArg::SayArg(unsigned long long d)
    00150 {
    00151   init();
    00152   ulonglong = d;
    00153   type = ULONGLONG;
    00154 }
    00155
    00156 SayArg::SayArg(signed long long d)
    00157 {
    00158   init();
    00159   slonglong = d;
    00160   type = SLONGLONG;
    00161 }
    00162
    00163 void SayArg::init()
    00164 {
    00165   type = NO_TYPE;
    00166   float64 = 0;
    00167   ulonglong = 0;
    00168   slonglong = 0;
    00169 }
    00170
    00171 String Say::parse( const Say& pset ) const
    00172 {
    00173   String out;
    00174   String fmt = pset.format_string;
    00175
    00176   int param_idx = 0;
    00177
    00178   int eur = -1;
    00179   int base = -1;
    00180   int field = -1;
    00181   int decimals = -1;
    00182   int align = -1;
    00183   int fill = -1;
    00184   int plus = -1;
    00185
    00186   int fmtstart = -1;
    00187
    00188   // %H+014.5n
    00189   bool fmtdata = false;
    00190   for(int i=0; i<(int)fmt.length(); ++i)
    00191   {
    00192     int ch       = (i<(int)fmt.length())   ? (int)fmt[i+0] : -1;
    00193     int next_ch  = (i<(int)fmt.length()-1) ? (int)fmt[i+1] : -1;
    00194     int nnext_ch = (i<(int)fmt.length()-2) ? (int)fmt[i+2] : -1;
    00195
    00196     if (!fmtdata)
    00197     {
    00198       if (ch == '%' && next_ch == '%')
    00199       {
    00200         out += '%';
    00201         ++i;
    00202       }
    00203       else
    00204       if (ch == '%')
    00205       {
    00206         if (param_idx < (int)pset.size())
    00207         {
    00208           fmtdata = true;
    00209           fmtstart = i;
    00210         }
    00211         else
    00212         {
    00213           out += " !!!too few parameters: %";
    00214         }
    00215       }
    00216       else
    00217       if (ch >= 0)
    00218       {
    00219         out += (unsigned short)ch;
    00220       }
    00221     }
    00222     else
    00223     {
    00224
    00225       if(eur == -1)
    00226       {
    00227         if (ch == '$')
    00228         {
    00229           eur = 1;
    00230           continue;
    00231         }
    00232       }
    00233
    00234       if (base == -1)
    00235       {
    00236         switch(ch)
    00237         {
    00238         case 'b': base = 2;  break;
    00239         case 'o': base = 8;  break;
    00240         case 'd': base = 10; break;
    00241         case 'h': base = 16; break;
    00242         }
    00243         if (base != -1)
    00244         {
    00245           if (eur == -1)
    00246             eur = 0;
    00247           continue;
    00248         }
    00249       }
    00250
    00251       if (plus == -1)
    00252       {
    00253         switch(ch)
    00254         {
    00255         case '+': plus = 1; break;
    00256         }
    00257         if (plus != -1)
    00258         {
    00259           if (base == -1)
    00260             base = 10;
    00261           if (eur == -1)
    00262             eur = 0;
    00263           continue;
    00264         }
    00265       }
    00266
    00267       if (fill == -1)
    00268       {
    00269         switch(ch)
    00270         {
    00271         case '0': fill = '0'; break;
    00272         case ' ': fill = ' '; break;
    00273         }
    00274         if (fill != -1)
    00275         {
    00276           if (base == -1)
    00277             base = 10;
    00278           if (plus == -1)
    00279             plus = 0;
    00280           if (eur == -1)
    00281             eur = 0;
    00282           continue;
    00283         }
    00284       }
    00285
    00286       if (field == -1)
    00287       {
    00288         if (ch >= '0' && ch <= '9')
    00289         {
    00290           field = ch - '0';
    00291           if (next_ch >= '0' && next_ch <= '9')
    00292           {
    00293             field = field*10 + next_ch - '0';
    00294             ++i;
    00295           }
    00296         }
    00297
    00298         if (field != -1)
    00299         {
    00300           if (base == -1)
    00301             base = 10;
    00302           if (plus == -1)
    00303             plus = 0;
    00304           if (fill == -1)
    00305             fill = ' ';
    00306           if (eur == -1)
    00307             eur = 0;
    00308           continue;
    00309         }
    00310       }
    00311
    00312       if (decimals == -1)
    00313       {
    00314         if(ch == '.')
    00315         {
    00316           if (next_ch >= '0' && next_ch <= '9')
    00317           {
    00318             decimals = next_ch - '0';
    00319             ++i;
    00320             if (nnext_ch >= '0' && nnext_ch <= '9')
    00321             {
    00322               decimals = decimals*10 + nnext_ch - '0';
    00323               ++i;
    00324             }
    00325           }
    00326         }
    00327
    00328         if (decimals != -1)
    00329         {
    00330           if (base == -1)
    00331             base = 10;
    00332           if (plus == -1)
    00333             plus = 0;
    00334           if (fill == -1)
    00335             fill = ' ';
    00336           if (field == -1)
    00337             field = 0;
    00338           if (eur == -1)
    00339             eur = 0;
    00340           continue;
    00341         }
    00342       }
    00343
    00344       if (align == -1)
    00345       {
    00346         if(ch == '=')
    00347           align = 0;
    00348         if(ch == '<')
    00349           align = 1;
    00350         if(ch == '>')
    00351           align = 2;
    00352
    00353         if (align != -1)
    00354         {
    00355           if (base == -1)
    00356             base = 10;
    00357           if (plus == -1)
    00358             plus = 0;
    00359           if (fill == -1)
    00360             fill = ' ';
    00361           if (field == -1)
    00362             field = 0;
    00363           if (eur == -1)
    00364             eur = 0;
    00365           if (decimals == -1)
    00366           {
    00367             switch(pset[param_idx].type)
    00368             {
    00369             case SayArg::FLOAT64: decimals = 6; break;
    00370             default: decimals = 0; break;
    00371             }
    00372           }
    00373           continue;
    00374         }
    00375       }
    00376
    00377       // generate formatted string
    00378
    00379       // output parameter
    00380       const SayArg& p = pset[param_idx];
    00381
    00382       if (ch == 'c')
    00383       {
    00384         if (fmtstart != i-1)
    00385           out += " !!! '%c' does not need arguments !!! ";
    00386
    00387         switch(p.type)
    00388         {
    00389         case SayArg::FLOAT64: out += (char)p.float64; break;
    00390         case SayArg::SLONGLONG: out += (char)p.slonglong; break;
    00391         case SayArg::ULONGLONG: out += (char)p.ulonglong; break;
    00392         default:
    00393           out += " !!! wrong argument type for '%c' !!! ";
    00394           break;
    00395         }
    00396
    00397       }
    00398       else
    00399       if (ch == 's')
    00400       {
    00401         if (fmtstart != i-1)
    00402           out += " !!! '%s' does not need arguments !!! ";
    00403
    00404         switch(p.type)
    00405         {
    00406         case SayArg::STRING: out += p.str; break;
    00407         default:
    00408           out += " !!! wrong argument type for '%s' !!! ";
    00409           break;
    00410         }
    00411
    00412       }
    00413       else
    00414       if (ch == 'n' || ch == 'N' || ch == 'e' || ch == 'E')
    00415       {
    00416
    00417         if (param_idx<(int)pset.size())
    00418         {
    00419           if (decimals == -1)
    00420           {
    00421             switch(p.type)
    00422             {
    00423             case SayArg::FLOAT64: decimals = 6; break;
    00424             default: decimals = 0; break;
    00425             }
    00426           }
    00427
    00428           if (base == -1)
    00429             base = 10;
    00430           if (field == -1)
    00431             field = 0;
    00432           if (decimals == -1)
    00433             decimals = 0;
    00434           if (fill == -1)
    00435             fill = ' ';
    00436           if (plus == -1)
    00437             plus = 0;
    00438           if (align == -1)
    00439             align = 2;
    00440           if (eur == -1)
    00441             eur = 0;
    00442
    00443           switch(p.type)
    00444           {
    00445           case SayArg::FLOAT64:   out += format(p.float64, base, field, decimals, align, fill, plus, ch, eur); break;
    00446           case SayArg::SLONGLONG: out += format(p.slonglong, base, field, decimals, align, fill, plus, ch, eur); break;
    00447           case SayArg::ULONGLONG: out += format(p.ulonglong, base, field, decimals, align, fill, plus, ch, eur); break;
    00448           default:
    00449             out += " !!! wrong argument type for '%n' !!! ";
    00450             break;
    00451           }
    00452         }
    00453         else
    00454         {
    00455           out += " !!!missing parameter!!! ";
    00456           if (ch != -1)
    00457             i--;
    00458         }
    00459       }
    00460       else
    00461       {
    00462         out += " !!!format error: unexpected '";
    00463         out += (char)ch;
    00464         out += "' !!! ";
    00465       }
    00466
    00467       fmtdata = false;
    00468       align = -1;
    00469       base = -1;
    00470       field = -1;
    00471       decimals = -1;
    00472       align = -1;
    00473       fill = -1;
    00474       plus = -1;
    00475       eur = -1;
    00476
    00477       param_idx++;
    00478     }
    00479   }
    00480
    00481   if (fmtdata)
    00482   {
    00483     out += " !!!truncated format!!! ";
    00484     param_idx++;
    00485   }
    00486
    00487   if (param_idx < (int)pset.size())
    00488     out += " !!!too many parameters!!! ";
    00489
    00490   return out;
    00491   // ... fare in modo che l'output venga generato anche quando non c'e' il carattere finale ...
    00492 }
    00493
    00494 String Say::euronotation(const String& str, int base) const
    00495 {
    00496   String tmp;
    00497   int pos = (int)str.length();
    00498   if ( str.contains('.') )
    00499   {
    00500     while(pos--)
    00501     {
    00502       if (str[pos] == '.')
    00503       {
    00504         tmp.insert(0, ',');
    00505         break;
    00506       }
    00507       tmp.insert(0, str[pos]);
    00508     }
    00509     if (pos < 0)
    00510       pos = (int)str.length();
    00511   }
    00512
    00513   int count = 0;
    00514   int wait = 3;
    00515   if (base == 2)
    00516     wait = 4;
    00517   if (base == 16)
    00518     wait = 2;
    00519   while(pos--)
    00520   {
    00521     if (count && count % wait == 0)
    00522     {
    00523       tmp.insert(0, '.');
    00524     }
    00525     tmp.insert(0, str[pos]);
    00526     count ++;
    00527   }
    00528
    00529   return tmp;
    00530 }
    00531
    00532 String Say::format(unsigned long long n, int base, int field, int decimals, int align, int fill, int plus, int finalizer, int eur) const
    00533 {
    00534   if (field < 0)
    00535     field = -field;
    00536
    00537   if (field > 1024)
    00538     field = 1024;
    00539
    00540   if (decimals < 0)
    00541     decimals = -decimals;
    00542   if (decimals > 20)
    00543     decimals = 20;
    00544
    00545   if (align != 0 && align != 1 && align != 2)
    00546     align = 0;
    00547
    00548   if (base > 16)
    00549     base = 16;
    00550
    00551   if (base < 2)
    00552     base = 2;
    00553
    00554   String str;
    00555
    00556   const char* hex = "0123456789abcdef";
    00557
    00558   // UNSIGNED INT ALGORITHM
    00559
    00560   int k = base;
    00561   do
    00562   {
    00563     int x = (int)(n % base);
    00564     int c = x/(k/base);
    00565     str.insert(0, hex[c]);
    00566     n = n  / base;
    00567   }
    00568   while(n);
    00569
    00570   if (decimals)
    00571   {
    00572     str += '.';
    00573     int i = decimals;
    00574     while(i--)
    00575       str += '0';
    00576   }
    00577
    00578   bool negative = false;
    00579
    00580   return pipeline(str, base, field, decimals, finalizer, align, eur, fill, negative, plus);
    00581 }
    00582
    00583 String Say::format(signed long long nn, int base, int field, int decimals, int align, int fill, int plus, int finalizer, int eur) const
    00584 {
    00585   if (field < 0)
    00586     field = -field;
    00587
    00588   if (field > 1024)
    00589     field = 1024;
    00590
    00591   if (decimals < 0)
    00592     decimals = -decimals;
    00593   if (decimals > 20)
    00594     decimals = 20;
    00595
    00596   if (align != 0 && align != 1 && align != 2)
    00597     align = 0;
    00598
    00599   if (base > 16)
    00600     base = 16;
    00601
    00602   if (base < 2)
    00603     base = 2;
    00604
    00605   String str;
    00606
    00607   const char* hex = "0123456789abcdef";
    00608
    00609   // SIGNED INT ALGORITHM
    00610
    00611   bool negative = nn < 0;
    00612   unsigned long long n;
    00613
    00614   if (nn<0 && -nn<0) // overflow
    00615     n = (unsigned long long)nn;
    00616   else
    00617   if (nn<0)
    00618     n = - nn;
    00619   else
    00620     n = nn;
    00621
    00622   //if (n < 0)
    00623   // n = 0;
    00624
    00625   int k = base;
    00626   do
    00627   {
    00628     int x = (int)(n % base);
    00629     int c = x/(k/base);
    00630     str.insert(0, hex[c]);
    00631     n = n  / base;
    00632   }
    00633   while(n);
    00634
    00635   if (decimals)
    00636   {
    00637     str += '.';
    00638     int i = decimals;
    00639     while(i--)
    00640       str += '0';
    00641   }
    00642
    00643   return pipeline(str, base, field, decimals, finalizer, align, eur, fill, negative, plus);
    00644 }
    00645
    00646 String Say::format(double num, int base, int field, int decimals, int align, int fill, int plus, int finalizer, int eur) const
    00647 {
    00648   if (field < 0)
    00649     field = -field;
    00650   if (field > 1024)
    00651     field = 1024;
    00652
    00653   if (decimals < 0)
    00654     decimals = -decimals;
    00655   if (decimals > 20)
    00656     decimals = 20;
    00657
    00658   if (align != 0 && align != 1 && align != 2)
    00659     align = 0;
    00660
    00661   if (base > 16)
    00662     base = 16;
    00663
    00664   if (base < 2)
    00665     base = 2;
    00666
    00667   String str;
    00668
    00669   const char* hex = "0123456789abcdef";
    00670
    00671   double f = num;
    00672
    00673   // INDEFINITE = - 127 192 0 0
    00674   // -INFINITE  = - 127 128 0 0
    00675   // +INFINITE  = + 127 128 0 0
    00676   float tmp = (float)f;
    00677   unsigned char *nan= (unsigned char*)&tmp;
    00678   const char* sign = nan[3] >= 128 ? "-" : "+";
    00679   unsigned char exp = (nan[3] << 1) + (nan[2] >> 7);
    00680   nan[2] &= 127;
    00681   unsigned int frac = nan[0] + (nan[1] << 8) + (nan[2] << 16);
    00682
    00683   bool negative = false;
    00684   if (exp == 255 && frac == 0)
    00685   {
    00686     return String(sign) + "#INF";
    00687   }
    00688   else
    00689   if (exp == 255 && frac != 0)
    00690   {
    00691     return "#NAN";
    00692   }
    00693   else
    00694   {
    00695     // ROUNDING FOR FRACTIONAL PART
    00696
    00697     if (finalizer == 'n' || finalizer == 'N')
    00698     {
    00699       double fp = f - floor(f);
    00700       double eps = base/2;
    00701       int dec = decimals;
    00702       do
    00703       {
    00704         if ( !(dec--) )
    00705           break;
    00706
    00707         int c = (int)(fp * base);
    00708         fp = fp * base - c;
    00709
    00710         eps /= base;
    00711
    00712         if (c<0 || c>15)
    00713         {
    00714           return "#ERR";
    00715         }
    00716
    00717         if (dec == 0) // round only if all the decimals are here
    00718         {
    00719           // program rounded fp
    00720           f += eps/base;
    00721           break;
    00722         }
    00723       }
    00724       while(fp>0);
    00725     }
    00726
    00727     if (f < 0)
    00728     {
    00729       f = -f;
    00730       negative = true;
    00731     }
    00732     double n = floor(f);
    00733
    00734     // INTEGER PART
    00735
    00736     int count = 0;
    00737     unsigned int base2 = base*base;
    00738     unsigned int base3 = base*base*base;
    00739     unsigned int base4 = base*base*base*base;
    00740     unsigned int base5 = base*base*base*base*base;
    00741     unsigned int base6 = base*base*base*base*base*base;
    00742     unsigned int base7 = base*base*base*base*base*base*base; // maximum number in base 16
    00743     while (floor(n))
    00744     {
    00745       if (n>=base7)
    00746       {
    00747         n /= base7;
    00748         count+=7;
    00749       }
    00750       else
    00751       if (n>=base6)
    00752       {
    00753         n /= base6;
    00754         count+=6;
    00755       }
    00756       else
    00757       if (n>=base5)
    00758       {
    00759         n /= base5;
    00760         count+=5;
    00761       }
    00762       else
    00763       if (n>=base4)
    00764       {
    00765         n /= base4;
    00766         count+=4;
    00767       }
    00768       else
    00769       if (n>=base3)
    00770       {
    00771         n /= base3;
    00772         count+=3;
    00773       }
    00774       else
    00775       if (n>=base2)
    00776       {
    00777         n /= base2;
    00778         count+=2;
    00779       }
    00780       else
    00781       {
    00782         n = n / base;
    00783         count++;
    00784       }
    00785     }
    00786
    00787     // prevents rounding errors
    00788     double eps = (base / 2.0) / base;
    00789     for(int i=0; i<count; ++i)
    00790     {
    00791       eps /= base;
    00792     }
    00793     n+=eps;
    00794
    00795     if (count)
    00796     {
    00797       do
    00798       {
    00799         int c = (int)(n * (double)base);
    00800         n = n * (double)base - floor(n * (double)base);
    00801         int next = (int)(n * base);
    00802
    00803         if (c<0 || c>15 || next<0 || next>15)
    00804         {
    00805           return "#ERR";
    00806         }
    00807
    00808         str += hex[c];
    00809       }
    00810       while(--count);
    00811     }
    00812     else
    00813       str += '0';
    00814
    00815     str += '.';
    00816
    00817     // FRACTIONAL PART
    00818
    00819     double fp = f - floor(f);
    00820     do
    00821     {
    00822       int c = (int)(fp * base);
    00823       fp = fp * base - c;
    00824
    00825       if (c<0 || c>15)
    00826       {
    00827         return "#ERR";
    00828       }
    00829
    00830       str += hex[c];
    00831     }
    00832     while(fp>0);
    00833
    00834     // COMMON PIPELINE
    00835
    00836     // (1) EXPONENTIAL SHIFT
    00837     // (2) CLIP & FILL DECIMALS
    00838     // (3) EXPONENTIAL DECORATIONS
    00839     // (4) EURO NOTATION
    00840     // (5) FIELD, ALIGN AND SIGN
    00841     // (6) CASE TRANSFORM
    00842
    00843     return pipeline(str, base, field, decimals, finalizer, align, eur, fill, negative, plus);
    00844   }
    00845 }
    00846
    00847 String Say::pipeline(const String& in_str, int base, int field, int decimals, int finalizer, int align, int eur, int fill, int negative, int plus) const
    00848 {
    00849   String str = in_str;
    00850   // EXPONENTIAL SHIFT
    00851
    00852   int shift = 0;
    00853   // exponential notation
    00854   if (finalizer == 'e' || finalizer == 'E')
    00855   {
    00856     int ptpos = (int)str.length(); // point position
    00857     int nzpos = -1; // non zero position
    00858     for(int i=0; i<(int)str.length(); ++i)
    00859     {
    00860       if(str[i] != '0' && nzpos == -1 && str[i] != '.')
    00861         nzpos = i;
    00862       else
    00863       if (str[i] == '.')
    00864         ptpos = i;
    00865     }
    00866
    00867     if (nzpos == -1)
    00868       shift = 0;
    00869     else
    00870       shift = ptpos - nzpos - ( (ptpos > nzpos) ? 1 : 0 );
    00871
    00872     // remove the point
    00873     str.remove( ptpos, 1 );
    00874
    00875     // remove all the zeros on the left
    00876     while( str.length() && str[0] == '0' )
    00877       str.remove(0);
    00878
    00879     // reinsert the point at the 2-nd position
    00880     // with up to 2 zero if needed.
    00881     if (str.length() == 1)
    00882       str += '0';
    00883     if (str.length() == 0)
    00884       str = "00";
    00885
    00886     str.insert(1, '.');
    00887   }
    00888
    00889   // CLIP AND FILL DECIMALS
    00890
    00891   // position of the dot
    00892   if ( !str.contains('.') )
    00893     str += ".0";
    00894   int pos = str.find('.');
    00895   // number of decimals
    00896   int decs = (int)str.length() - pos -1;
    00897   // trim decimals
    00898   if (decs > decimals)
    00899   {
    00900     // remove also the dot
    00901     int dot = decimals == 0 ? 1 : 0;
    00902     str.resize(str.length() - (decs - decimals + dot));
    00903   }
    00904   else
    00905   {
    00906     // add missing decimals
    00907     int i = decimals - decs;
    00908     while(i--)
    00909       str += '0';
    00910   }
    00911
    00912   // EXPONENTIAL DECORATION
    00913
    00914   if (finalizer == 'e' || finalizer == 'E')
    00915   {
    00916     str += 'e';
    00917     str += format((signed long long)shift, base, 0, 0, 2, 0, 1, 0,0);
    00918   }
    00919   else
    00920   // EURO NOTATION
    00921
    00922   if (eur)
    00923     str = euronotation(str, base);
    00924
    00925   // FIELD, SIGN, ALIGN
    00926
    00927   int right = (field - (int)str.length()) / 2;
    00928   right = right < 0 ? 0 : right;
    00929
    00930   int left =  (field - (int)str.length()) - right;
    00931   left = left < 0 ? 0 : left;
    00932
    00933   if (align == 1) // left
    00934   {
    00935     right += left;
    00936     left = 0;
    00937   }
    00938   else
    00939   if (align == 2) // right
    00940   {
    00941     left += right;
    00942     right = 0;
    00943   }
    00944
    00945   // fill left
    00946   str.insert(0, fill, left);
    00947
    00948   // fill right
    00949   str.append(fill, right);
    00950
    00951   if (negative)
    00952   {
    00953     if (left)
    00954       str.remove(0);
    00955     else
    00956     if (right)
    00957       str.resize(str.length()-1);
    00958
    00959     str.insert(0, '-');
    00960   }
    00961   else
    00962   if(plus)
    00963   {
    00964     if (left)
    00965       str.remove(0);
    00966     else
    00967     if (right)
    00968       str.resize(str.length()-1);
    00969
    00970     str.insert(0, '+');
    00971   }
    00972
    00973   // CASE TRANSFORM
    00974
    00975   if (finalizer == 'N' || finalizer == 'E')
    00976   {
    00977     for(int i=0; i<(int)str.length(); ++i)
    00978       if (str[i] >= 'a' && str[i] <= 'z')
    00979         str[i] = str[i] - 'a' + 'A';
    00980   }
    00981
    00982   return str;
    00983 }
    00984

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:21.
Permission is granted to use this page to write and publish articles regarding Visualization Library.