estring.cc

Go to the documentation of this file.
00001 #include "config.h"
00002 
00003 #include <iostream>
00004 #include <string>
00005 #include <cstdio>
00006 #include <cctype>
00007 #include <string.h>
00008 
00009 #include "asserts.h"
00010 #include "types.h"
00011 #include "error.h"
00012 #include "estring.h"
00013 
00014 //----------------------------------------------------------------------------
00015 
00016 estring_value::estring_value()
00017 {
00018         clear();
00019 }
00020 
00021 void estring_value::clear(void)
00022 {
00023         memset(static_cast<void*>(&value), 0, sizeof(value));
00024 }
00025 
00026 estring_value& estring_value::operator=(const estring_value& a_estring_value)
00027 {
00028         value = a_estring_value.value;
00029 
00030         return(*this);
00031 }
00032 
00033 //----------------------------------------------------------------------------
00034 
00035 /** Alphabet used for base number conversions
00036  */
00037 
00038 const char * estring::m_alphabet = "0123456789abcdefghijklmnopqrstuvwxyz";
00039 
00040 /** The length of the alphabet used for base number conversions
00041  */
00042 const size_t estring::m_alphabet_len = 36;
00043 
00044 /** Helper member template function to convert an integral type to an estring.
00045 
00046         Integrals are converted to string form using a default base of 10 unless
00047         specified otherwise through the base() member function.  For bases greater
00048         than ten the letters of the alphabet are used, starting with 'a' for eleven,
00049         'b' for twelve, etc.
00050 
00051         Variables:
00052                 - a_t - the integral type.  Usually uint8, uint16, uint32, or uint64.
00053                 - a_str - the std::string object in which to store the string converstion.
00054         
00055         Exceptions:
00056                 - An err_nomem is thrown for memory allocation failure.
00057  */
00058 template <class T>
00059 void estring::T_integral_to_string(const T& a_t, value_type& a_str)
00060 {
00061         T num = a_t;
00062         int digit;
00063         char ch;
00064 
00065         ASSERT(a_t >= 0);
00066         ASSERT(m_base >= 2);
00067         ASSERT(m_base <= m_alphabet_len);
00068 
00069         TRY_nomem(a_str = "");
00070         if (a_t == 0) {
00071                 TRY_nomem(a_str = "0");
00072                 return;
00073         }
00074         while (num > 0) {
00075                 digit = num % m_base;
00076                 ch = m_alphabet[digit];
00077                 TRY_nomem(a_str = ch + a_str);
00078                 num /= m_base;
00079         }
00080 }
00081 
00082 /** Helper member template function to convert a fractional type to an estring.
00083 
00084         Fractions are converted to string form using a default base of 10 unless
00085         specified otherwise through the base() member function.  For bases greater
00086         than ten the letters of the alphabet are used, starting with 'a' for eleven,
00087         'b' for twelve, etc.
00088 
00089         By default a precision of 1 digit to the right of the decimal point is used
00090         unless specified otherwise by the precision() member function.
00091 
00092         Variables:
00093                 - a_t - the fractional type: float or double.
00094                 - a_ws - the std::string object in which to store the whole part.
00095                 - a_fs - the std::string object in which to store the fractional part.
00096         
00097         Exceptions:
00098                 - An err_nomem is thrown for memory allocation failure.
00099  */
00100 template <class T>
00101 void estring::T_fraction_to_strings(const T& a_t,
00102         value_type& a_ws, value_type& a_fs)
00103 {
00104         T fraction = a_t;
00105         bool negative = false;
00106         uint64 whole_part;
00107         uint64 fractional_part;
00108         uint64 multiplier;
00109         size_type c;
00110         int digit;
00111         char ch;
00112 
00113         ASSERT(m_base >= 2);
00114         ASSERT(m_base <= m_alphabet_len);
00115 
00116         TRY_nomem(a_ws = "");
00117         TRY_nomem(a_fs = "");
00118 
00119         if (fraction < 0.0) {
00120                 negative = true;
00121                 fraction = -fraction;
00122         }
00123 
00124         whole_part = static_cast<uint64>(fraction);
00125         if (whole_part == 0) {
00126                 TRY_nomem(a_ws = "0");
00127         }
00128         else {
00129                 while (whole_part > 0) {
00130                         digit = whole_part % m_base;
00131                         ch = m_alphabet[digit];
00132                         TRY_nomem(a_ws = ch + a_ws);
00133                         whole_part /= m_base;
00134                 }
00135         }
00136 
00137         multiplier = m_base;
00138         for (c = 0; c < m_precision; c++)
00139                 multiplier *= m_base;
00140 
00141         fractional_part = static_cast<uint64>(
00142                 (fraction - static_cast<uint64>(fraction)) * multiplier);
00143         fractional_part += (m_base/2);
00144         fractional_part /= m_base;
00145 
00146         while (fractional_part > 0) {
00147                 digit = fractional_part % m_base;
00148                 ch = m_alphabet[digit];
00149                 TRY_nomem(a_fs = ch +a_fs);
00150                 fractional_part /= m_base;
00151         }
00152         if (a_fs.size() > m_precision) {
00153                 a_fs.erase(m_precision);
00154         }
00155         for (c = a_fs.size(); c < m_precision; c++) {
00156                 TRY_nomem(a_fs += "0");
00157         }
00158 
00159         if (negative) {
00160                 TRY_nomem(a_ws = "-" + a_ws);
00161         }
00162 }
00163 
00164 /** Helper member template function to convert a string to an integral type.
00165 
00166         Characters in the string are converted using a default base of 10 unless
00167         specified otherwise through the base() member function.  For bases greater
00168         than ten the letters of the alphabet will be assumed, starting with 'a' for
00169         eleven, 'b' for twelve, etc.
00170         
00171         Variables:
00172                 - a_str - the std::string object from which to convert.
00173                 - a_t - a variable of the integral type to which to convert.
00174         
00175         Exceptions:
00176                 - An err_nomem is thrown for memory allocation failure.
00177                 - If a symbol is encountered in the string that is not expected then an
00178                         invalid character or invalid base error is thrown.
00179                 - If the type to which to convert the string is not large enough to hold
00180                         the value of the converted string then an overflow error is thrown.
00181  */
00182 template<class T>
00183 void estring::T_string_to_integral(const value_type& a_str, T& a_t) const
00184 {
00185         value_type::const_iterator stri;
00186         T value = 0;
00187         T digit = 0;
00188         T overflow_check_1 = 0;
00189         T overflow_check_2 = 0;
00190         value_type es;
00191         value_type alphabet;
00192         size_type idx;
00193         const static size_t buffer_len = 256;
00194         char buffer[buffer_len] = { 0 };
00195         unsigned int index;
00196 
00197         ASSERT(m_base >= 2);
00198         ASSERT(m_base <= m_alphabet_len);
00199 
00200         TRY_nomem(alphabet = m_alphabet);
00201         for (stri = a_str.begin(), index = 0;
00202                 stri != a_str.end();
00203                 ++stri, ++index
00204                 )
00205         {
00206                 idx = alphabet.find(*stri);
00207                 if (idx > m_base) {
00208                         snprintf(buffer, buffer_len, "%u", index);
00209 
00210                         TRY_nomem(es = "Parse error at index ");
00211                         TRY_nomem(es += buffer);
00212                         TRY_nomem(es += " (char '");
00213                         TRY_nomem(es += *stri);
00214                         TRY_nomem(es += "')");
00215                         TRY_nomem(es += " converting \"");
00216                         TRY_nomem(es += (*this));
00217                         TRY_nomem(es += "\"");
00218                         if (idx == value_type::npos) {
00219                                 TRY_nomem(es += ", invalid character");
00220                         }
00221                         else {
00222                                 TRY_nomem(es += ", invalid base or invalid string");
00223                         }
00224                         throw(ERROR(0,es));
00225                 }
00226 
00227                 value *= m_base;
00228                 digit = static_cast<unsigned int>(idx);
00229                 value += digit;
00230 
00231                 overflow_check_1 *= m_base;
00232                 overflow_check_1 += 1;
00233                 if (overflow_check_1 == overflow_check_2) {
00234                         snprintf(buffer, buffer_len, "%u", index);
00235 
00236                         TRY_nomem(es = "Overflow error at index ");
00237                         TRY_nomem(es += buffer);
00238                         TRY_nomem(es += " (char '");
00239                         TRY_nomem(es += *stri);
00240                         TRY_nomem(es += "')");
00241                         TRY_nomem(es += " converting \"");
00242                         TRY_nomem(es += (*this));
00243                         TRY_nomem(es += "\" to unsigned int");
00244                         throw(ERROR(0,es));
00245                 }
00246                 overflow_check_2 = overflow_check_1;
00247         }
00248         a_t = value;
00249 }
00250 
00251 /** Helper member template function to convert a string to a signed integral.
00252 
00253         Variables:
00254                 - a_str - the std::string to convert from.
00255                 - a_t - a variable of the type to convert to.
00256         
00257         Exceptions:
00258                 - An err_nomem is thrown for memory allocation failure.
00259                 - Any exception thrown from the called member template function
00260                         T_string_to_integral().
00261  */
00262 template <class T>
00263 void estring::T_string_to_signed_integral(const value_type& a_str, T& a_t)
00264         const
00265 {
00266         value_type tmp;
00267         T value = 0;
00268         bool negative = false;
00269 
00270         if ((value_type::size() > 0) && (this->at(0) == '-')) {
00271                 negative = true;
00272                 TRY_nomem(tmp = (*this).substr(1));
00273         }
00274         else {
00275                 TRY_nomem(tmp = (*this));
00276         }
00277         T_string_to_integral(tmp,value);
00278         if (negative)
00279                 value = -value;
00280         a_t = value;
00281 }
00282 
00283 /** Helper member template function to convert a string to a fractional.
00284 
00285         Variables:
00286                 - a_str - the std::string to convert from.
00287                 - a_t - a variable of the type to convert to.
00288         
00289         Exceptions:
00290                 - An err_nomem is thrown for memory allocation failure.
00291                 - Any exception thrown by the member template function
00292                         T_string_to_integral().
00293                 - An overflow error is thrown if the wole part of the string is too large
00294                         for the type a_t.
00295                 - An underflow error is thrown if the fractional part of the string is too
00296                         large for the type a_t.
00297  */
00298 template <class T>
00299 void estring::T_string_to_fractional(const value_type& a_str, T& a_t) const
00300 {
00301         value_type es;
00302         value_type tmp;
00303         value_type whole_string;
00304         value_type fractional_string;
00305         size_type idx = 0;
00306         bool negative = false;;
00307         uint64 whole_part_converter = 0;
00308         uint64 fractional_part_converter = 0;
00309         uint64 fractional_check = 0;
00310         T whole_part = 0;
00311         T fractional_part = 0;
00312         T value =0;
00313         unsigned int divisor = 0;
00314         unsigned int c = 0;
00315 
00316         ASSERT(m_base >= 2);
00317         ASSERT(m_base <= m_alphabet_len);
00318 
00319         if ((value_type::size() > 0) && (this->at(0) == '-')) {
00320                 negative = true;
00321                 TRY_nomem(tmp = (*this).substr(1));
00322         }
00323         else {
00324                 TRY_nomem(tmp = (*this));
00325         }
00326 
00327         idx = tmp.find('.');
00328         if (idx != value_type::npos) {
00329                 TRY_nomem(whole_string = tmp.substr(0,idx));
00330                 TRY_nomem(fractional_string = tmp.substr(idx+1));
00331         }
00332         else {
00333                 TRY_nomem(whole_string = tmp);
00334                 TRY_nomem(fractional_string = "");
00335         }
00336 
00337         TRY_nomem(es = "Could not convert whole part of estring \"");
00338         TRY_nomem(es += a_str);
00339         TRY_nomem(es += "\"");
00340         TRY(T_string_to_integral(whole_string, whole_part_converter),es);
00341 
00342         TRY_nomem(es = "Could not convert fractional part of estring \"");
00343         TRY_nomem(es += a_str);
00344         TRY_nomem(es += "\"");
00345         TRY(T_string_to_integral(fractional_string, fractional_part_converter),es);
00346 
00347         divisor = 1;
00348         for (c = 0; c < fractional_string.size(); c++)
00349                 divisor *= m_base;
00350 
00351         whole_part = static_cast<T>(whole_part_converter);
00352         if (static_cast<uint64>(whole_part) != whole_part_converter) {
00353                 TRY_nomem(es = "Overflow error converting whole part of estring \"");
00354                 TRY_nomem(es += a_str);
00355                 TRY_nomem(es += "\"");
00356                 throw(ERROR(0,es));
00357         }
00358         fractional_part = static_cast<T>(fractional_part_converter)/divisor;
00359         fractional_check = static_cast<uint64>(fractional_part*divisor);
00360         if (fractional_check != fractional_part_converter) {
00361                 TRY_nomem(es = "Underflow error converting fractional part of estring \"");
00362                 TRY_nomem(es += a_str);
00363                 TRY_nomem(es += "\"");
00364                 throw(ERROR(0,es));
00365         }
00366 
00367         value = whole_part + fractional_part;
00368 
00369         if (negative) {
00370                 value = -value;
00371         }
00372         a_t = value;
00373 }
00374 
00375 //---------
00376 
00377 /** Initialize the estring object.
00378 
00379         Defaults:
00380                 - A precision of one digit to the right of the decimal.
00381                 - A base of 10.
00382                 - A width of 5 characters for formatted printing.
00383                 - A space as the fill character for padding the left of a string.
00384                 - A space as the fill character for padding the right of a string.
00385                 - Initialize the conversion type to type_unknown.
00386  */
00387 void estring::init(void)
00388 {
00389         m_precision = 1;
00390         m_base = 10;
00391         m_width = 5;
00392         m_alignment = left;
00393         m_left_fillchar = ' ';
00394         m_right_fillchar = ' ';
00395         m_type = type_unknown;
00396 }
00397 
00398 /** Erase the string value.
00399  */
00400 void estring::clear(void)
00401 {
00402         value_type::erase();
00403 }
00404 
00405 /** Erase and reinitialize.
00406  */
00407 void estring::reset(void)
00408 {
00409         clear();
00410         init();
00411 }
00412 
00413 //---------
00414 
00415 /** Default constructor
00416  */
00417 estring::estring()
00418 {
00419         init();
00420 }
00421 
00422 //---------
00423 
00424 /** Set the width of a formatted string.
00425 
00426         Variables:
00427                 - a_l - new width to use for formatting strings.
00428         
00429         Returns:
00430                 - size_type - the last width.
00431  */
00432 estring::size_type estring::width(const size_type a_l)
00433 {
00434         size_type old;
00435 
00436         old = m_width;
00437         m_width = a_l;
00438 
00439         return(old);
00440 }
00441 
00442 /** Retrieve the set width for formatted strings.
00443         
00444         Returns:
00445                 - size_type - the current width.
00446  */
00447 estring::size_type estring::width(void) const
00448 {
00449         return(m_width);
00450 }
00451 
00452 /** Set the alignment used for formatted strings.
00453 
00454         Vaiables:
00455                 - a_alignment - the type of alignment to use for formatting strings.
00456  */
00457 estring::alignment estring::align(const alignment a_alignment)
00458 {
00459         alignment old;
00460 
00461         old = m_alignment;
00462         m_alignment = a_alignment;
00463 
00464         return(old);
00465 }
00466 
00467 /** Retrieve the set alignment for formatted strings.
00468         
00469         Returns:
00470                 - enum alignment - the current alignment.
00471  */
00472 estring::alignment estring::align(void) const
00473 {
00474         return(m_alignment);
00475 }
00476 
00477 /** Set the precision used in converting to/from fractional types.
00478 
00479         Variables:
00480                 - a_p - the number of digits to use to the right of the decimal point when
00481                         converting fractional types.
00482         
00483         Returns:
00484                 - size_type - the last precision.
00485 
00486  */
00487 estring::size_type estring::precision(size_type a_p)
00488 {
00489         size_type old;
00490 
00491         old = m_precision;
00492         m_precision = a_p;
00493 
00494         if (m_type == type_float)
00495                 assign(m_value.value.f);
00496         else if (m_type == type_double)
00497                 assign(m_value.value.d);
00498 
00499         return(old);
00500 }
00501 
00502 /** Retrieve the set precision used in fractional conversions.
00503         
00504         Returns:
00505                 - size_type - the current precision.
00506  */
00507 estring::size_type estring::precision(void) const
00508 {
00509         return(m_precision);
00510 }
00511 
00512 /** Set the base used in numeric conversions.
00513 
00514         Variables:
00515                 - a_base - The base to use in converting numbers to/from strings.
00516 
00517         Return:
00518                 - const unsigned int - the last base.
00519 
00520         Exceptions:
00521                 - An err_nomem is thrown for memory allocation failure.
00522                 - An invalid base is thrown if the base is smaller than 2 (binary).
00523                 - A base too large is thrown if the base is larger than the alphabet of
00524                         usable symbols.
00525  */
00526 const unsigned int estring::base(const unsigned int a_base)
00527 {
00528         unsigned int old = m_base;
00529         value_type es;
00530         char str[255] = { 0 };
00531 
00532         if (a_base < 2) {
00533                 sprintf(str, "%u", a_base);
00534                 TRY_nomem(es = "Invalid base: ");
00535                 TRY_nomem(es += str);
00536                 throw(ERROR(0,es));
00537         }
00538         if (a_base > m_alphabet_len) {
00539                 sprintf(str, "%u", a_base);
00540                 TRY_nomem(es = "Base too large: ");
00541                 TRY_nomem(es += str);
00542                 throw(ERROR(0,es));
00543         }
00544         m_base = a_base;
00545 
00546         if (m_type == type_unsigned_int)
00547                 assign(m_value.value.ui);
00548         if (m_type == type_int)
00549                 assign(m_value.value.i);
00550         if (m_type == type_unsigned_short)
00551                 assign(m_value.value.us);
00552         if (m_type == type_short)
00553                 assign(m_value.value.s);
00554         if (m_type == type_unsigned_long)
00555                 assign(m_value.value.ul);
00556         if (m_type == type_long)
00557                 assign(m_value.value.l);
00558         if (m_type == type_unsigned_long_long)
00559                 assign(m_value.value.ull);
00560         if (m_type == type_long_long)
00561                 assign(m_value.value.ll);
00562         if (m_type == type_float)
00563                 assign(m_value.value.f);
00564         if (m_type == type_double)
00565                 assign(m_value.value.d);
00566 
00567         return(old);
00568 }
00569 
00570 /** Retrieve the base used in numeric conversions.
00571 
00572         Returns:
00573                 - const unsigned int - the current numeric base.
00574  */
00575 const unsigned int estring::base(void) const
00576 {
00577         return(m_base);
00578 }
00579 
00580 /** Set the fill character used to padd the left side of a formatted string.
00581 
00582         Variables:
00583                 - a_char - the character to use as the fill character.
00584         
00585         Returns:
00586                 - char - the last fill character.
00587 
00588  */
00589 char estring::left_fillchar(const char a_char)
00590 {
00591         char old;
00592 
00593         old = m_left_fillchar;
00594         m_left_fillchar = a_char;
00595 
00596         return(old);
00597 }
00598 
00599 /** Retrieve the fill character used to padd the left side of a formatted
00600                 string.
00601         
00602         Returns:
00603                 - char - the current fill character.
00604 
00605  */
00606 char estring::left_fillchar(void) const
00607 {
00608         return(m_left_fillchar);
00609 }
00610 
00611 /** Set the fill character used to padd the right side of a formatted string.
00612 
00613         Variables:
00614                 - a_char - the character to use as the fill character.
00615         
00616         Returns:
00617                 - char - the last fill character.
00618 
00619  */
00620 char estring::right_fillchar(const char a_char)
00621 {
00622         char old;
00623 
00624         old = m_right_fillchar;
00625         m_right_fillchar = a_char;
00626 
00627         return(old);
00628 }
00629 
00630 /** Retrieve the fill character used to padd the right side of a formatted
00631                 string.
00632         
00633         Returns:
00634                 - char - the current fill character.
00635 
00636  */
00637 char estring::right_fillchar(void) const
00638 {
00639         return(m_right_fillchar);
00640 }
00641 
00642 /** Set the fill character used for padding both the left and right side of a
00643                 formatted string.
00644         
00645         Variables:
00646                 - a_char - the character to use as the fill character.
00647  */
00648 void estring::fillchar(const char a_char)
00649 {
00650         left_fillchar(a_char);
00651         right_fillchar(a_char);
00652 }
00653 
00654 //---------
00655                 
00656 /** Generate a formatted string.
00657 
00658         Returns:
00659                 - value_type - a formatted rendition of the current string.
00660 
00661         If the string being printed is wider than the assigned width then as many as
00662         three periods are used ("...") to denote that the contents of the string
00663         have been truncated.  For strings that use left alignment these three
00664         periods are printed on the right-hand side of the string, while showing as
00665         many characters on the left as possible beginning with the left-most
00666         character.  For strings that use right alignment these three periods are
00667         printed on the left-hand side of the string, while showing as many
00668         characters on the right as possible includingn the right-most character.
00669         For strings that are center-aligned as many characters on both the left and
00670         the right are printed, including the left-most and the right-most
00671         characters, while characters in the center of the string are replaced with
00672         the three periods.
00673  */
00674 estring::value_type estring::fmt_str(void)
00675 {
00676         std::string str;
00677         std::string lstr;
00678         std::string rstr;
00679         std::string::size_type c = 0;
00680         std::string::size_type c_max = 0;
00681         std::string::size_type offset = 0;
00682         std::string::size_type length = 0;
00683         std::string::size_type l_offset = 0;
00684         std::string::size_type r_offset = 0;
00685         bool last = true;
00686 
00687         TRY_nomem(str = "");
00688         TRY_nomem(lstr = "");
00689         TRY_nomem(rstr = "");
00690 
00691         if (std::string::size() > m_width) {
00692                 if (m_alignment == left) {
00693                         if (m_width >= 3)
00694                                 length = m_width-3;
00695                         else
00696                                 length = 0;
00697                         TRY_nomem(str = std::string::substr(0,length) + "...");
00698                         TRY_nomem(str = str.substr(0,m_width));
00699                 }
00700                 else if (m_alignment == right) {
00701                         if (m_width >= 3)
00702                                 length = m_width-3;
00703                         else
00704                                 length = 0;
00705 
00706                         offset = std::string::size()-length;
00707                         TRY_nomem(str = "..." + std::string::substr(offset,length));
00708                         TRY_nomem(str = str.substr(str.size()-m_width,m_width));
00709                 }
00710                 else {
00711                         if (m_width < 4) {
00712                                 TRY_nomem(str = static_cast<std::string>("....").substr(0,m_width));
00713                                 return(str);
00714                         }
00715 
00716                         c_max = m_width-3;
00717                         r_offset = std::string::size()-1;
00718                         for (c = 0; c < c_max; c++) {
00719                                 if (last) {
00720                                         TRY_nomem(lstr += (*this)[l_offset++]);
00721                                 }
00722                                 else {
00723                                         TRY_nomem(rstr = (*this)[r_offset--] + rstr);
00724                                 }
00725                                 last = !last;
00726                         }
00727 
00728                         TRY_nomem(str = lstr);
00729                         TRY_nomem(str += "...");
00730                         TRY_nomem(str += rstr);
00731                 }
00732                 return(str);
00733         }
00734 
00735         TRY_nomem(str = (*this));
00736         c_max = m_width - std::string::size();
00737         for (c = 0; c < c_max; c++) {
00738                 if (m_alignment == right) {
00739                         TRY_nomem(str = m_left_fillchar + str);
00740                 }
00741                 else if (m_alignment == left) {
00742                         TRY_nomem(str += m_right_fillchar);
00743                 }
00744                 else {
00745                         if (last) {
00746                                 TRY_nomem(str += m_right_fillchar);
00747                         }
00748                         else {
00749                                 TRY_nomem(str = m_left_fillchar + str);
00750                         }
00751                         last = !last;
00752                 }
00753         }
00754 
00755         return(str);
00756 }
00757 
00758 /** Set all the formatting options.
00759 
00760         Variables:
00761                 - a_width - the width of the formatted string.
00762                 - a_alignment - the alignment used to format the string.
00763                 - a_left_fill - the character used for left-hand padding.
00764                 - a_right_fill - the character used for right-hand padding.
00765         
00766         Returns:
00767                 - value_type - a formatted rendition of the current string.
00768 
00769  */
00770 estring::value_type estring::fmt_str(
00771         const size_type a_width,
00772         const alignment a_alignment,
00773         const char a_left_fill,
00774         const char a_right_fill
00775         )
00776 {
00777         value_type str;
00778 
00779         width(a_width);
00780         align(a_alignment);
00781         left_fillchar(a_left_fill);
00782         right_fillchar(a_right_fill);
00783 
00784         str = fmt_str();
00785 
00786         return(str);
00787 }
00788 
00789 //---------
00790 
00791 /** Retrieve the type of value being held by this estring.
00792 
00793         Returns:
00794                 - set_from_type& - the enumeration of the type of value currently assigned.
00795  */
00796 const estring::set_from_type& estring::get_from_type(void) const
00797 {
00798         return(m_type);
00799 }
00800 
00801 /** Retrieve the typeless_value being held by this estring.
00802 
00803         Returns:
00804                 - typeless_value& - the union that holds the current value.
00805         
00806  */
00807 const estring_value& estring::get_from_value(void) const
00808 {
00809         return(m_value);
00810 }
00811 
00812 /** Copy constructor for estring objects.
00813         
00814         Variables:
00815                 - a_estr - the estring object to copy.
00816 
00817         Exceptions:
00818                 - Anything thrown by estring::assign(const estring& a_estr).
00819  */
00820 estring::estring(const estring& a_estr)
00821 {
00822         init();
00823         assign(a_estr);
00824 }
00825 
00826 /** Assignment for estring objects.
00827         
00828         Variables:
00829                 - a_estr - the estring object to copy.
00830 
00831         Returns:
00832                 - estring& - a reference to self.
00833         
00834         Exceptions:
00835                 - An err_nomem is thrown if memory allocation fails.
00836                 - It is possible that an "Invalid base" or "Base too large" may be thrown
00837                         if the estring object is corrupted, but this should never happen.
00838 */
00839 estring& estring::assign(const estring& a_estr)
00840 {
00841         TRY_nomem(std::string::assign(a_estr));
00842         m_precision = a_estr.m_precision;
00843         m_width = a_estr.m_width;
00844         m_alignment = a_estr.m_alignment;
00845         m_left_fillchar = a_estr.m_left_fillchar;
00846         m_right_fillchar = a_estr.m_right_fillchar;
00847         m_type = a_estr.m_type;
00848         m_value = a_estr.m_value;
00849 
00850         return(*this);
00851 }
00852 
00853 /** Assignment operator for estring objects.
00854 
00855         Variables:
00856                 - a_estr - the estring object to copy.
00857         
00858         Returns:
00859                 - estring& - a reference to self.
00860         
00861         Exceptions:
00862                 - Anything thrown by estring::assign(const estring& a_estr).
00863  */
00864 estring& estring::operator=(const estring& a_estr)
00865 {
00866         assign(a_estr);
00867 
00868         return(*this);
00869 }
00870 
00871 /** Convert all characters to lowercase.
00872 
00873         Returns:
00874                 - estring& - a reference to self.
00875         
00876  */
00877 estring& estring::lower(void)
00878 {
00879         std::string::iterator si;
00880 
00881         for (si = (*this).begin(); si != (*this).end(); ++si) {
00882                 (*si) = tolower((*si));
00883         }
00884 
00885         return(*this);
00886 }
00887 
00888 /** Convert all characters to uppercase.
00889 
00890         Returns:
00891                 - estring& - a reference to self.
00892         
00893  */
00894 estring& estring::upper(void)
00895 {
00896         std::string::iterator si;
00897 
00898         for (si = (*this).begin(); si != (*this).end(); ++si) {
00899                 (*si) = toupper((*si));
00900         }
00901 
00902         return(*this);
00903 }
00904 
00905 //---------
00906 
00907 /** Copy constructor for chars.
00908         
00909         Exceptions:
00910                 - Anything thrown by estring::assign(const char& a_char).
00911  */
00912 estring::estring(const char a_char)
00913 {
00914         init();
00915         assign(a_char);
00916 }
00917 
00918 /** Assignment for chars.
00919         
00920         Variables:
00921                 - a_char - the character to assign.
00922         
00923         Returns:
00924                 - estring& - a reference to self.
00925         
00926         Exceptions:
00927                 - An err_nomem is thrown if memory allocation fails.
00928  */
00929 estring& estring::assign(const char a_char)
00930 {
00931         std::string s;
00932 
00933         TRY_nomem(s = a_char);
00934         TRY_nomem(std::string::assign(s));
00935         m_type = type_string;
00936         
00937         return(*this);
00938 }
00939 
00940 /** Assignment operator for chars
00941         
00942         Variables:
00943                 - a_char - the character to assign.
00944         
00945         Returns:
00946                 - estring& - a reference to self.
00947         
00948         Exceptions:
00949                 - Anything thrown by estring::assign(const char& a_char).
00950  */
00951 estring& estring::operator=(const char a_char)
00952 {
00953         assign(a_char);
00954 
00955         return(*this);
00956 }
00957 
00958 //---------
00959 
00960 /** Copy constructor for std::string objects.
00961 
00962         Variables:
00963                 - a_string - the std::string object to copy.
00964 
00965         Exceptions:
00966                 - Anything thrown by estring::assign(const value_type& a_string).
00967  */
00968 estring::estring(const value_type& a_string)
00969 {
00970         init();
00971         assign(a_string);
00972 }
00973 
00974 /** Assignment for std::string objects.
00975         
00976         Variables:
00977                 - a_string - the std::string object to assign.
00978         
00979         Returns:
00980                 - estring& - a reference to self.
00981 
00982         Exceptions:
00983                 - An err_nomem is thrown if memory allocation fails.
00984  */
00985 estring& estring::assign(const value_type& a_string)
00986 {
00987         TRY_nomem(std::string::assign(a_string));
00988         m_type = type_string;
00989 
00990         return(*this);
00991 }
00992 
00993 /** Assignment operator for std::string objects.
00994 
00995         Variables:
00996                 - a_string - the std::string object to copy.
00997         
00998         Returns:
00999                 - estring& - a reference to self.
01000         
01001         Exceptions:
01002                 - An err_nomem is thrown if memory allocation fails.
01003  */
01004 estring& estring::operator=(const value_type& a_string)
01005 {
01006         assign(a_string);
01007 
01008         return(*this);
01009 }
01010 
01011 //---------
01012 
01013 /** Copy constructor for unsigned ints.
01014 
01015         Variables:
01016                 - a_int - unsigned int to copy.
01017         
01018         Exceptions:
01019                 - Anything thrown by estring::assign(const unsigned int& a_int).
01020  */
01021 estring::estring(const unsigned int a_int)
01022 {
01023         init();
01024         assign(a_int);
01025 }
01026 
01027 /** Assignment for unsigned ints.
01028 
01029         Variables:
01030                 - a_int - unsigned int to assign.
01031 
01032         Returns:
01033                 - estring& - a reference to self.
01034 
01035         Exceptions:
01036                 - err_nomem on memory allocation failure.
01037                 - Anything thrown by 
01038                         T_integral_to_string(const T& a_t, value_type& a_str).
01039  */
01040 estring& estring::assign(const unsigned int a_int)
01041 {
01042         std::string s;
01043 
01044         TRY(T_integral_to_string(a_int,s),
01045                 "Could not convert unsigned int to string");
01046         TRY_nomem(std::string::assign(s));
01047         m_type = type_unsigned_int;
01048         m_value.clear();
01049         m_value.value.ui = a_int;
01050 
01051         return(*this);
01052 }
01053 
01054 /** Assignment operator for unsigned ints.
01055  */
01056 estring& estring::operator=(const unsigned int a_int)
01057 {
01058         assign(a_int);
01059 
01060         return(*this);
01061 }
01062 
01063 /** Implicit conversion operator to an unsigned int.
01064  */
01065 estring::operator unsigned int() const
01066 {
01067         unsigned int value = 0;
01068 
01069         TRY(T_string_to_integral((*this),value),
01070                 "Cannot convert string to unsigned int");
01071 
01072         return(value);
01073 }
01074 
01075 //---------
01076 
01077 estring::estring(const int a_int)
01078 {
01079         init();
01080         assign(a_int);
01081 }
01082 
01083 estring& estring::assign(const int a_int)
01084 {
01085         if (a_int < 0) {
01086                 TRY(assign(static_cast<unsigned int>(-a_int)),
01087                         "Coud not convert signed int to string");
01088                 TRY_nomem(std::string::insert(0,"-"));
01089         }
01090         else {
01091                 TRY(assign(static_cast<unsigned int>(a_int)),
01092                         "Could not convert signed int to string");
01093         }
01094         m_type = type_int;
01095         m_value.clear();
01096         m_value.value.i = a_int;
01097 
01098         return(*this);
01099 }
01100 
01101 estring& estring::operator=(const int a_int)
01102 {
01103         assign(a_int);
01104 
01105         return(*this);
01106 }
01107 
01108 estring::operator int() const
01109 {
01110         int value = 0;
01111 
01112         TRY(T_string_to_signed_integral((*this),value),
01113                 "Cannot convert string to signed int");
01114 
01115         return(value);
01116 }
01117 
01118 //---------
01119 
01120 estring::estring(const unsigned short a_short)
01121 {
01122         init();
01123         assign(a_short);
01124 }
01125 
01126 estring& estring::assign(const unsigned short a_short)
01127 {
01128         std::string s;
01129 
01130         TRY(T_integral_to_string(a_short,s),
01131                 "Could not convert unsigned short to string");
01132         TRY_nomem(std::string::assign(s));
01133         m_type = type_unsigned_short;
01134         m_value.clear();
01135         m_value.value.us = a_short;
01136 
01137         return(*this);
01138 }
01139 
01140 estring& estring::operator=(const unsigned short a_short)
01141 {
01142         assign(a_short);
01143 
01144         return(*this);
01145 }
01146 
01147 estring::operator unsigned short() const
01148 {
01149         unsigned short value = 0;
01150 
01151         TRY(T_string_to_integral((*this),value),
01152                 "Cannot convert string to unsigned short");
01153 
01154         return(value);
01155 }
01156 
01157 //---------
01158 
01159 estring::estring(const short a_short)
01160 {
01161         init();
01162         assign(a_short);
01163 }
01164 
01165 estring& estring::assign(const short a_short)
01166 {
01167         if (a_short < 0) {
01168                 TRY(assign(static_cast<unsigned short>(-a_short)),
01169                         "Could not convert signed short to string");
01170                 TRY_nomem(std::string::insert(0,"-"));
01171         }
01172         else {
01173                 TRY(assign(static_cast<unsigned short>(a_short)),
01174                         "Could not convert signed short to string");
01175         }
01176         m_type = type_short;
01177         m_value.clear();
01178         m_value.value.s = a_short;
01179 
01180         return(*this);
01181 }
01182 
01183 estring& estring::operator=(const short a_short)
01184 {
01185         assign(a_short);
01186 
01187         return(*this);
01188 }
01189 
01190 estring::operator short() const
01191 {
01192         short value = 0;
01193 
01194         TRY(T_string_to_signed_integral((*this),value),
01195                 "Cannot convert string to signed short");
01196 
01197         return(value);
01198 }
01199 
01200 //---------
01201 
01202 estring::estring(const unsigned long a_long)
01203 {
01204         init();
01205         assign(a_long);
01206 }
01207 
01208 estring& estring::assign(const unsigned long a_long)
01209 {
01210         std::string s;
01211 
01212         TRY(T_integral_to_string(a_long,s),
01213                 "Could not convert unsigned long to string");
01214         TRY_nomem(std::string::assign(s));
01215         m_type = type_unsigned_long;
01216         m_value.clear();
01217         m_value.value.ul = a_long;
01218 
01219         return(*this);
01220 }
01221 
01222 estring& estring::operator=(const unsigned long a_long)
01223 {
01224         assign(a_long);
01225 
01226         return(*this);
01227 }
01228 
01229 estring::operator unsigned long() const
01230 {
01231         unsigned long value = 0;
01232 
01233         TRY(T_string_to_integral((*this),value),
01234                 "Cannot convert string to unsigned long");
01235 
01236         return(value);
01237 }
01238 
01239 //---------
01240 
01241 estring::estring(const long a_long)
01242 {
01243         init();
01244         assign(a_long);
01245 }
01246 
01247 estring& estring::assign(const long a_long)
01248 {
01249         if (a_long < 0) {
01250                 TRY(assign(static_cast<unsigned long>(-a_long)),
01251                         "Could not convert signed long to string");
01252                 TRY_nomem(std::string::insert(0,"-"));
01253         }
01254         else {
01255                 TRY(assign(static_cast<unsigned long>(a_long)),
01256                         "Could not convert signed long to string");
01257         }
01258         m_type = type_long;
01259         m_value.clear();
01260         m_value.value.l = a_long;
01261 
01262         return(*this);
01263 }
01264 
01265 estring& estring::operator=(const long a_long)
01266 {
01267         assign(a_long);
01268 
01269         return(*this);
01270 }
01271 
01272 estring::operator long() const
01273 {
01274         long value = 0;
01275 
01276         TRY(T_string_to_signed_integral((*this),value),
01277                 "Cannot convert string to signed long");
01278 
01279         return(value);
01280 }
01281 
01282 //---------
01283 
01284 estring::estring(const unsigned long long a_long)
01285 {
01286         init();
01287         assign(a_long);
01288 }
01289 
01290 estring& estring::assign(const unsigned long long a_long)
01291 {
01292         std::string s;
01293 
01294         TRY(T_integral_to_string(a_long,s),
01295                 "Could not convert unsigned long long to string");
01296         TRY_nomem(std::string::assign(s));
01297         m_type = type_unsigned_long_long;
01298         m_value.clear();
01299         m_value.value.ull = a_long;
01300 
01301         return(*this);
01302 }
01303 
01304 estring& estring::operator=(const unsigned long long a_long)
01305 {
01306         assign(a_long);
01307 
01308         return(*this);
01309 }
01310 
01311 estring::operator unsigned long long() const
01312 {
01313         unsigned long long value = 0;
01314 
01315         TRY(T_string_to_integral((*this),value),
01316                 "Cannot convert string to unsigned long long");
01317 
01318         return(value);
01319 }
01320 
01321 //---------
01322 
01323 estring::estring(const long long a_long)
01324 {
01325         init();
01326         assign(a_long);
01327 }
01328 
01329 estring& estring::assign(const long long a_long)
01330 {
01331         if (a_long < 0) {
01332                 TRY(assign(static_cast<unsigned long long>(-a_long)),
01333                         "Could not convert unsigned long long to string");
01334                 TRY_nomem(insert(0,"-"));
01335         }
01336         else {
01337                 TRY(assign(static_cast<unsigned long long>(a_long)),
01338                         "Could not convert unsigned long long to string");
01339         }
01340         m_type = type_long_long;
01341         m_value.clear();
01342         m_value.value.ll = a_long;
01343 
01344         return(*this);
01345 }
01346 
01347 estring& estring::operator=(const long long a_long)
01348 {
01349         assign(a_long);
01350 
01351         return(*this);
01352 }
01353 
01354 estring::operator long long() const
01355 {
01356         long long value = 0;
01357 
01358         TRY(T_string_to_signed_integral((*this),value),
01359                 "Cannot convert string to signed long long");
01360 
01361         return(value);
01362 }
01363 
01364 //---------
01365 
01366 estring::estring(char* const a_ptr)
01367 {
01368         init();
01369         assign(a_ptr);
01370 }
01371 
01372 estring& estring::assign(char* const a_ptr)
01373 {
01374         std::string str;
01375 
01376         TRY_nomem(str = a_ptr);
01377         TRY_nomem(assign(str));
01378         m_type = type_char_ptr;
01379         m_value.clear();
01380         m_value.value.char_ptr = a_ptr;
01381 
01382         return(*this);
01383 }
01384 
01385 estring& estring::operator=(char* const a_ptr)
01386 {
01387         assign(a_ptr);
01388 
01389         return(*this);
01390 }
01391 
01392 estring::operator char*()const
01393 {
01394         char * value = 0;
01395 
01396         if ((m_type != type_char_ptr) && (m_type != type_void_ptr)) {
01397                 throw(ERROR(0,"Value type is not a pointer"));
01398         }
01399 
01400         value = m_value.value.char_ptr;
01401 
01402         return(value);
01403 }
01404 
01405 //---------
01406 
01407 estring::estring(void* const a_ptr)
01408 {
01409         init();
01410         assign(a_ptr);
01411 }
01412 
01413 estring& estring::assign(void* const a_ptr)
01414 {
01415         static const size_t buffer_len = 32;
01416         char buffer[buffer_len] = { 0 };
01417         
01418         snprintf(buffer, buffer_len, "%p", a_ptr);
01419         TRY_nomem(std::string::assign(buffer));
01420         m_type = type_void_ptr;
01421         m_value.clear();
01422         m_value.value.void_ptr = a_ptr;
01423 
01424         return(*this);
01425 }
01426 
01427 estring& estring::operator=(void* const a_ptr)
01428 {
01429         assign(a_ptr);
01430 
01431         return(*this);
01432 }
01433 
01434 estring::operator void*()const
01435 {
01436         void * value = 0;
01437 
01438         if ((m_type != type_void_ptr) && (m_type != type_char_ptr)) {
01439                 throw(ERROR(0,"Value type is not a pointer"));
01440         }
01441 
01442         value = m_value.value.void_ptr;
01443 
01444         return(value);
01445 }
01446 
01447 //---------
01448 
01449 estring::estring(const float a_float)
01450 {
01451         init();
01452         assign(a_float);
01453 }
01454 
01455 estring& estring::assign(const float a_float)
01456 {
01457         std::string ws;
01458         std::string fs;
01459         std::string s;
01460 
01461         TRY(T_fraction_to_strings(a_float,ws,fs),
01462                 "Cannot convert float to string");
01463         TRY_nomem(s = ws);
01464         if (fs.size() > 0) {
01465                 TRY_nomem(s += ".");
01466                 TRY_nomem(s += fs);
01467         }
01468         TRY_nomem(std::string::assign(s));
01469         m_type = type_float;
01470         m_value.clear();
01471         m_value.value.f = a_float;
01472 
01473         return(*this);
01474 }
01475 
01476 estring& estring::operator=(const float a_float)
01477 {
01478         assign(a_float);
01479 
01480         return(*this);
01481 }
01482 
01483 estring::estring(const float a_float, unsigned a_precision,
01484         unsigned int a_base)
01485 {
01486         init();
01487         assign(a_float, a_precision, a_base);
01488 }
01489 
01490 estring& estring::assign(const float a_float, unsigned a_precision,
01491         unsigned int a_base)
01492 {
01493         std::string ws;
01494         std::string fs;
01495         std::string s;
01496 
01497         precision(a_precision);
01498         base(a_base);
01499         assign(a_float);
01500 
01501         return(*this);
01502 }
01503 
01504 estring::operator float() const
01505 {
01506         float value = 0.0;
01507 
01508         TRY(T_string_to_fractional((*this), value),
01509                 "Cannot convert string to float");
01510 
01511         return(value);
01512 }
01513 
01514 //---------
01515 
01516 estring::estring(const double a_double)
01517 {
01518         init();
01519         assign(a_double);
01520 }
01521 
01522 estring& estring::assign(const double a_double)
01523 {
01524         std::string ws;
01525         std::string fs;
01526         std::string s;
01527 
01528         TRY(T_fraction_to_strings(a_double,ws,fs),
01529                 "Cannot convert double to string");
01530         TRY_nomem(s = ws);
01531         if (fs.size() > 0) {
01532                 TRY_nomem(s += ".");
01533                 TRY_nomem(s += fs);
01534         }
01535         TRY_nomem(std::string::assign(s));
01536         m_type = type_double;
01537         m_value.clear();
01538         m_value.value.d = a_double;
01539 
01540         return(*this);
01541 }
01542 
01543 estring& estring::operator=(const double a_double)
01544 {
01545         assign(a_double);
01546 
01547         return(*this);
01548 }
01549 
01550 estring::estring(const double a_double, unsigned a_precision,
01551         unsigned int a_base)
01552 {
01553         init();
01554         assign(a_double, a_precision, a_base);
01555 }
01556 
01557 estring& estring::assign(const double a_double, unsigned a_precision,
01558         unsigned int a_base)
01559 {
01560         std::string ws;
01561         std::string fs;
01562         std::string s;
01563 
01564         precision(a_precision);
01565         assign(a_base);
01566         assign(a_double);
01567 
01568         return(*this);
01569 }
01570 
01571 estring::operator double() const
01572 {
01573         double value = 0.0;
01574 
01575         TRY(T_string_to_fractional((*this), value),
01576                 "Cannot convert string to double");
01577 
01578         return(value);
01579 }
01580 

Generated on Fri Jun 23 16:46:30 2006 for rvm by  doxygen 1.4.2