00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <ctype.h>
00018 #include <stdio.h>
00019
00020 #include <spl/types.h>
00021
00022 #ifdef _WINDOWS
00023 #include <spl/configwin32.h>
00024 #else
00025 #include <spl/autoconf/config.h>
00026 #endif
00027
00028 #ifdef HAVE_LIMITS_H
00029 #include <limits.h>
00030 #include <limits>
00031 #endif
00032
00033 #include <spl/Char.h>
00034 #include <spl/Exception.h>
00035 #include <spl/Numeric.h>
00036 #include <spl/Double.h>
00037 #include <spl/IConvertable.h>
00038 #include <spl/Int32.h>
00039 #include <spl/Int64.h>
00040 #include <spl/math/Math.h>
00041 #include <spl/text/StringBuffer.h>
00042 #include <spl/UInt32.h>
00043 #include <spl/UInt64.h>
00044
00045 char *int32toa( int32 i, char *buf, const int buflen )
00046 {
00047 int pos = 0;
00048 if ( 0 == i )
00049 {
00050 buf[pos++] = '0';
00051 }
00052 else
00053 {
00054 while ( i > 0 && pos < buflen-1 )
00055 {
00056 buf[pos++] = (char)((i % 10) + (int)'0');
00057 i /= 10;
00058 }
00059 for ( i = 0; i < pos-1; i++ )
00060 {
00061 char ch = buf[i];
00062 buf[i] = buf[pos-1-i];
00063 buf[pos-1-i] = ch;
00064 }
00065 }
00066 buf[pos] = '\0';
00067 return buf;
00068 }
00069
00070 static char *int64toa( int64 i, char *buf, const int buflen )
00071 {
00072 int pos = 0;
00073 if ( 0 == i )
00074 {
00075 buf[pos++] = '0';
00076 }
00077 else
00078 {
00079 while ( i > 0 && pos < buflen-1 )
00080 {
00081 buf[pos++] = (char)((i % 10) + (int)'0');
00082 i /= 10;
00083 }
00084 for ( i = 0; i < pos-1; i++ )
00085 {
00086 char ch = buf[i];
00087 buf[i] = buf[pos-1-i];
00088 buf[pos-1-i] = ch;
00089 }
00090 }
00091 buf[pos] = '\0';
00092 return buf;
00093 }
00094
00095 static bool isint( const char *cstr, const int len )
00096 {
00097 int x = 0;
00098 if ( cstr[0] == '-' || cstr[0] == '+' )
00099 {
00100 x = 1;
00101 }
00102 for ( ; x < len; x++ )
00103 {
00104 if ( ! isdigit( cstr[x] ) )
00105 {
00106 return false;
00107 }
00108 }
00109 return true;
00110 }
00111
00112 static const int base10 = 10;
00113 static char cHexa[] = { 'A', 'B', 'C', 'D', 'E', 'F' };
00114 static int iHexaNumeric[] = { 10, 11, 12, 13, 14, 15 };
00115 static int iHexaIndices[] = { 0, 1, 2, 3, 4, 5 };
00116 static const int asciiDiff = 48;
00117
00118 static uint64 _baseToInt(const char *sbase, int numbase)
00119 {
00120 int i;
00121 uint64 dec = 0;
00122 int b;
00123 int iProduct = 1;
00124 int sbaselen = (int)strlen(sbase);
00125 int stopAt = 0;
00126
00127 if ( sbase[0] == '0' && (sbase[1] == 'x' || sbase[1] == 'X') )
00128 {
00129 stopAt = 2;
00130 }
00131
00132 for ( i = sbaselen - 1; i >= stopAt; i--, iProduct *= numbase )
00133 {
00134 char ch = sbase[i];
00135 if ( numbase > base10 && isalpha(ch) )
00136 {
00137 ASSERT( 'A' > 'a' );
00138 if ( ch >= 'A' )
00139 {
00140 b = iHexaNumeric[ch-'A'];
00141 }
00142 else
00143 {
00144 b = iHexaNumeric[ch-'a'];
00145 }
00146 }
00147 else
00148 {
00149 b = (int) sbase[i] - asciiDiff;
00150 }
00151 dec += (b * iProduct);
00152 }
00153 return dec;
00154 }
00155
00156 static void FormatHex( byte b, char *buf )
00157 {
00158 int nibble = b & 0xF;
00159 if ( nibble > 9 )
00160 {
00161 buf[1] = nibble - 10 + 'A';
00162 }
00163 else
00164 {
00165 buf[1] = nibble + '0';
00166 }
00167 nibble = b >> 4;
00168 if ( nibble > 9 )
00169 {
00170 buf[0] = nibble - 10 + 'A';
00171 }
00172 else
00173 {
00174 buf[0] = nibble + '0';
00175 }
00176 buf[2] = '\0';
00177 }
00178
00179 Numeric::Numeric()
00180 {
00181 }
00182
00183 Numeric::~Numeric()
00184 {
00185 }
00186
00187 bool Numeric::IsNumeric(const char *cp, const int cplen)
00188 {
00189 int x = 0;
00190 bool sawdot = false;
00191 bool sawe = false;
00192
00193 if (cplen == 0)
00194 {
00195 return false;
00196 }
00197 if ( cp[0] == '-' || cp[x] == '+' )
00198 {
00199 x = 1;
00200 }
00201 for ( ; x < cplen && cp[x] != '\0'; x++ )
00202 {
00203 if ( ! isdigit( cp[x] ) )
00204 {
00205 if ( cp[x] == '.' )
00206 {
00207 if ( sawdot )
00208 {
00209 return false;
00210 }
00211 sawdot = true;
00212 }
00213 else if ( cp[x] == 'e' || cp[x] == 'E' )
00214 {
00215 if ( sawe )
00216 {
00217 return false;
00218 }
00219 sawe = true;
00220 }
00221 else if ( cp[x] == '-' )
00222 {
00223 if ( ! sawe )
00224 {
00225 return false;
00226 }
00227 if ( cp[x-1] != 'e' && cp[x] != 'E' )
00228 {
00229 return false;
00230 }
00231 }
00232 else
00233 {
00234 return false;
00235 }
00236 }
00237 }
00238 if (sawdot && cplen == 1)
00239 {
00240 return false;
00241 }
00242 return true;
00243 }
00244
00245 Int32::~Int32()
00246 {
00247 }
00248
00249 int32 Int32::HashCode() const
00250 {
00251 return Math::Hash(m_val);
00252 }
00253
00254 bool Int32::Equals(const IComparable *a) const
00255 {
00256 if (a->MajicNumber() != MajicNumber())
00257 {
00258 return false;
00259 }
00260 const Int32 *vp = static_cast<const Int32 *>(a);
00261 vp->ValidateMem();
00262 return m_val == vp->m_val;
00263 }
00264
00265 int Int32::Compare(const IComparable *a) const
00266 {
00267 if (a->MajicNumber() != MajicNumber())
00268 {
00269 return 1;
00270 }
00271 const Int32 *vp = static_cast<const Int32 *>(a);
00272 vp->ValidateMem();
00273 return m_val - vp->m_val;
00274 }
00275
00276 bool Int32::Equals(const IComparable& a) const
00277 {
00278 if (a.MajicNumber() != MajicNumber())
00279 {
00280 return false;
00281 }
00282 const Int32& vp = static_cast<const Int32&>(a);
00283 vp.ValidateMem();
00284 return m_val == vp.m_val;
00285 }
00286
00287 int Int32::Compare(const IComparable& a) const
00288 {
00289 if (a.MajicNumber() != MajicNumber())
00290 {
00291 return 1;
00292 }
00293 const Int32& vp = static_cast<const Int32&>(a);
00294 vp.ValidateMem();
00295 return m_val - vp.m_val;
00296 }
00297
00298 int32 Int32::MajicNumber() const
00299 {
00300 return INT32_MAJIC;
00301 }
00302
00303 int Int32::ToInt() const
00304 {
00305 return m_val;
00306 }
00307
00308 double Int32::ToDouble() const
00309 {
00310 return (double)m_val;
00311 }
00312
00313 StringPtr Int32::ToString() const
00314 {
00315 return ToString(m_val);
00316 }
00317
00318 #ifdef DEBUG
00319 void Int32::ValidateMem() const
00320 {
00321 }
00322
00323 void Int32::CheckMem() const
00324 {
00325 }
00326 #endif
00327
00328 int32 Int32::Parse(const char *cp, const int cplen, int radix)
00329 {
00330 if (radix == 10)
00331 {
00332 return atoi(cp);
00333 }
00334 return (int32)_baseToInt(cp, radix);
00335 }
00336
00337 bool Int32::IsInt(const char *cp, const int cplen, int radix)
00338 {
00339 if (radix == 10)
00340 {
00341 return isint(cp, cplen);
00342 }
00343 if (radix != 16)
00344 {
00345 throw new InvalidArgumentException("Unsupported number base in Int32::IsInt().");
00346 }
00347 int pos = 0;
00348
00349 if (cp[0] == '0' && (cp[1] == 'x' || cp[1] == 'X'))
00350 {
00351 pos = 2;
00352 }
00353 char ch;
00354 for ( int x = pos; x < cplen && cp[x] != '\0'; x++ )
00355 {
00356 ch = cp[x];
00357 if (Char::IsDigit(ch))
00358 {
00359 continue;
00360 }
00361 if (!isalpha(ch))
00362 {
00363 return false;
00364 }
00365 if (!((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')))
00366 {
00367 return false;
00368 }
00369 }
00370 return true;
00371 }
00372
00373 StringPtr Int32::ToString(int32 i, int radix)
00374 {
00375 if (10 == radix)
00376 {
00377 char buf[128];
00378 bool neg = i < 0;
00379 int bufpos = neg ? 1 : 0;
00380 if (neg)
00381 {
00382 i *= -1;
00383 buf[0] = '-';
00384 }
00385
00386 int32toa(i, &buf[bufpos], 128);
00387
00388 return StringPtr(new String( buf ));
00389 }
00390 if (16 != radix)
00391 {
00392 throw new InvalidArgumentException("Unsupported radix in Int32::IsInt().");
00393 }
00394
00395 char buf[3];
00396 StringBuffer hex;
00397 FormatHex( ((byte *)&i)[3], &buf[0] );
00398 hex.Append(buf);
00399 FormatHex( ((byte *)&i)[2], &buf[0] );
00400 hex.Append(buf);
00401 FormatHex( ((byte *)&i)[1], &buf[0] );
00402 hex.Append(buf);
00403 FormatHex( ((byte *)&i)[0], &buf[0] );
00404 hex.Append(buf);
00405
00406 return hex.ToString()->LTrim('0');
00407 }
00408
00409
00410 Int64::Int64()
00411 : m_val(0)
00412 {
00413 }
00414
00415 Int64::Int64(const int64 i)
00416 : m_val(i)
00417 {
00418 }
00419
00420 Int64::Int64(const Int64& i)
00421 : m_val(i.m_val)
00422 {
00423 }
00424
00425 Int64::~Int64()
00426 {
00427 }
00428
00429 int32 Int64::HashCode() const
00430 {
00431 return Math::Hash(m_val);
00432 }
00433
00434 bool Int64::Equals(const IComparable *a) const
00435 {
00436 if (a->MajicNumber() != MajicNumber())
00437 {
00438 return false;
00439 }
00440 const Int64 *vp = static_cast<const Int64 *>(a);
00441 vp->ValidateMem();
00442 return m_val == vp->m_val;
00443 }
00444
00445 int Int64::Compare(const IComparable *a) const
00446 {
00447 if (a->MajicNumber() != MajicNumber())
00448 {
00449 return 1;
00450 }
00451 const Int64 *vp = static_cast<const Int64 *>(a);
00452 vp->ValidateMem();
00453 return (int)(m_val - vp->m_val);
00454 }
00455
00456 bool Int64::Equals(const IComparable& a) const
00457 {
00458 if (a.MajicNumber() != MajicNumber())
00459 {
00460 return false;
00461 }
00462 const Int64& vp = static_cast<const Int64&>(a);
00463 vp.ValidateMem();
00464 return m_val == vp.m_val;
00465 }
00466
00467 int Int64::Compare(const IComparable& a) const
00468 {
00469 if (a.MajicNumber() != MajicNumber())
00470 {
00471 return 1;
00472 }
00473 const Int64& vp = static_cast<const Int64&>(a);
00474 vp.ValidateMem();
00475 return (int)(m_val - vp.m_val);
00476 }
00477
00478 int32 Int64::MajicNumber() const
00479 {
00480 return INT64_MAJIC;
00481 }
00482
00483 int Int64::ToInt() const
00484 {
00485 return (int)m_val;
00486 }
00487
00488 double Int64::ToDouble() const
00489 {
00490 return (double)m_val;
00491 }
00492
00493 StringPtr Int64::ToString() const
00494 {
00495 return ToString(m_val);
00496 }
00497
00498 #ifdef DEBUG
00499 void Int64::ValidateMem() const
00500 {
00501 }
00502
00503 void Int64::CheckMem() const
00504 {
00505 }
00506 #endif
00507
00508 int64 Int64::Parse(const char *cp, const int cplen)
00509 {
00510 return atol(cp);
00511 }
00512
00513 bool Int64::IsInt(const char *cp, const int cplen)
00514 {
00515 return isint(cp, cplen);
00516 }
00517
00518 StringPtr Int64::ToString(int64 i, int radix)
00519 {
00520 if (10 == radix)
00521 {
00522 char buf[128];
00523 bool neg = i < 0;
00524 int bufpos = neg ? 1 : 0;
00525 if (neg)
00526 {
00527 i *= -1;
00528 buf[0] = '-';
00529 }
00530 int64toa(i, &buf[bufpos], 128);
00531 return StringPtr(new String( buf ));
00532 }
00533 if (16 != radix)
00534 {
00535 throw new InvalidArgumentException("Unsupported radix in Int32::IsInt().");
00536 }
00537
00538 char buf[3];
00539 StringBuffer hex;
00540 FormatHex( ((byte *)&i)[7], &buf[0] );
00541 hex.Append(buf);
00542 FormatHex( ((byte *)&i)[6], &buf[0] );
00543 hex.Append(buf);
00544 FormatHex( ((byte *)&i)[5], &buf[0] );
00545 hex.Append(buf);
00546 FormatHex( ((byte *)&i)[4], &buf[0] );
00547 hex.Append(buf);
00548 FormatHex( ((byte *)&i)[3], &buf[0] );
00549 hex.Append(buf);
00550 FormatHex( ((byte *)&i)[2], &buf[0] );
00551 hex.Append(buf);
00552 FormatHex( ((byte *)&i)[1], &buf[0] );
00553 hex.Append(buf);
00554 FormatHex( ((byte *)&i)[0], &buf[0] );
00555 hex.Append(buf);
00556
00557 return hex.ToString()->LTrim('0');
00558 }
00559
00560
00561 UInt32::UInt32()
00562 : m_val(0)
00563 {
00564 }
00565
00566 UInt32::UInt32(const uint32 i)
00567 : m_val(i)
00568 {
00569 }
00570
00571 UInt32::UInt32(const UInt32& i)
00572 : m_val(i.m_val)
00573 {
00574 }
00575
00576 UInt32::~UInt32()
00577 {
00578 }
00579
00580 int32 UInt32::HashCode() const
00581 {
00582 return Math::Hash(m_val);
00583 }
00584
00585 bool UInt32::Equals(const IComparable *a) const
00586 {
00587 if (a->MajicNumber() != MajicNumber())
00588 {
00589 return false;
00590 }
00591 const UInt32 *vp = static_cast<const UInt32 *>(a);
00592 vp->ValidateMem();
00593 return m_val == vp->m_val;
00594 }
00595
00596 int UInt32::Compare(const IComparable *a) const
00597 {
00598 if (a->MajicNumber() != MajicNumber())
00599 {
00600 return 1;
00601 }
00602 const UInt32 *vp = static_cast<const UInt32 *>(a);
00603 vp->ValidateMem();
00604 return m_val - vp->m_val;
00605 }
00606
00607 bool UInt32::Equals(const IComparable& a) const
00608 {
00609 if (a.MajicNumber() != MajicNumber())
00610 {
00611 return false;
00612 }
00613 const UInt32& vp = static_cast<const UInt32&>(a);
00614 vp.ValidateMem();
00615 return m_val == vp.m_val;
00616 }
00617
00618 int UInt32::Compare(const IComparable& a) const
00619 {
00620 if (a.MajicNumber() != MajicNumber())
00621 {
00622 return 1;
00623 }
00624 const UInt32& vp = static_cast<const UInt32&>(a);
00625 vp.ValidateMem();
00626 return m_val - vp.m_val;
00627 }
00628
00629 int32 UInt32::MajicNumber() const
00630 {
00631 return UINT32_MAJIC;
00632 }
00633
00634 int UInt32::ToInt() const
00635 {
00636 return (int)m_val;
00637 }
00638
00639 double UInt32::ToDouble() const
00640 {
00641 return (double)m_val;
00642 }
00643
00644 StringPtr UInt32::ToString() const
00645 {
00646 return ToString(m_val);
00647 }
00648
00649 #ifdef DEBUG
00650 void UInt32::ValidateMem() const
00651 {
00652 }
00653
00654 void UInt32::CheckMem() const
00655 {
00656 }
00657 #endif
00658
00659 uint32 UInt32::Parse(const char *cp, const int cplen, int radix)
00660 {
00661 if (radix == 10)
00662 {
00663 return atoi(cp);
00664 }
00665 return (uint32)_baseToInt(cp, radix);
00666 }
00667
00668 StringPtr UInt32::ToString(uint32 i, int radix)
00669 {
00670 return Int64::ToString((int64)i, radix);
00671 }
00672
00673
00674 UInt64::UInt64()
00675 : m_val(0)
00676 {
00677 }
00678
00679 UInt64::UInt64(const uint64 i)
00680 : m_val(i)
00681 {
00682 }
00683
00684 UInt64::UInt64(const UInt64& i)
00685 : m_val(i.m_val)
00686 {
00687 }
00688
00689 UInt64::~UInt64()
00690 {
00691 }
00692
00693 int32 UInt64::HashCode() const
00694 {
00695 return Math::Hash(m_val);
00696 }
00697
00698 bool UInt64::Equals(const IComparable *a) const
00699 {
00700 if (a->MajicNumber() != MajicNumber())
00701 {
00702 return false;
00703 }
00704 const UInt64 *vp = static_cast<const UInt64 *>(a);
00705 vp->ValidateMem();
00706 return m_val == vp->m_val;
00707 }
00708
00709 int UInt64::Compare(const IComparable *a) const
00710 {
00711 if (a->MajicNumber() != MajicNumber())
00712 {
00713 return 1;
00714 }
00715 const UInt64 *vp = static_cast<const UInt64 *>(a);
00716 vp->ValidateMem();
00717 return (int)(m_val - vp->m_val);
00718 }
00719
00720 bool UInt64::Equals(const IComparable& a) const
00721 {
00722 if (a.MajicNumber() != MajicNumber())
00723 {
00724 return false;
00725 }
00726 const UInt64& vp = static_cast<const UInt64&>(a);
00727 vp.ValidateMem();
00728 return m_val == vp.m_val;
00729 }
00730
00731 int UInt64::Compare(const IComparable& a) const
00732 {
00733 if (a.MajicNumber() != MajicNumber())
00734 {
00735 return 1;
00736 }
00737 const UInt64& vp = static_cast<const UInt64&>(a);
00738 vp.ValidateMem();
00739 return (int)(m_val - vp.m_val);
00740 }
00741
00742 int32 UInt64::MajicNumber() const
00743 {
00744 return UINT64_MAJIC;
00745 }
00746
00747 int UInt64::ToInt() const
00748 {
00749 return (int)m_val;
00750 }
00751
00752 double UInt64::ToDouble() const
00753 {
00754 return (double)(int64)m_val;
00755 }
00756
00757 StringPtr UInt64::ToString() const
00758 {
00759 return ToString(m_val);
00760 }
00761
00762 #ifdef DEBUG
00763 void UInt64::ValidateMem() const
00764 {
00765 }
00766
00767 void UInt64::CheckMem() const
00768 {
00769 }
00770 #endif
00771
00772 uint64 UInt64::Parse(const char *cp, const int cplen, int radix)
00773 {
00774 if (radix == 10)
00775 {
00776 return atoi(cp);
00777 }
00778 return _baseToInt(cp, radix);
00779 }
00780
00781 StringPtr UInt64::ToString(uint64 i, int radix)
00782 {
00783 return Int64::ToString((int64)i, radix);
00784 }
00785
00786
00787 Double::Double()
00788 : m_val(0)
00789 {
00790 }
00791
00792 Double::Double(const double d)
00793 : m_val(d)
00794 {
00795 }
00796
00797 Double::Double(const Double& d)
00798 : m_val(d.m_val)
00799 {
00800 }
00801
00802 Double::~Double()
00803 {
00804 }
00805
00806 int32 Double::HashCode() const
00807 {
00808 return Math::Hash(m_val);
00809 }
00810
00811 bool Double::Equals(const IComparable *a) const
00812 {
00813 if (a->MajicNumber() != MajicNumber())
00814 {
00815 return false;
00816 }
00817 const Double *vp = static_cast<const Double *>(a);
00818 vp->ValidateMem();
00819 return m_val == vp->m_val;
00820 }
00821
00822 int Double::Compare(const IComparable *a) const
00823 {
00824 if (a->MajicNumber() != MajicNumber())
00825 {
00826 return 1;
00827 }
00828 const Double *vp = static_cast<const Double *>(a);
00829 vp->ValidateMem();
00830 return (int)(m_val - vp->m_val);
00831 }
00832
00833 bool Double::Equals(const IComparable& a) const
00834 {
00835 if (a.MajicNumber() != MajicNumber())
00836 {
00837 return false;
00838 }
00839 const Double& vp = static_cast<const Double&>(a);
00840 vp.ValidateMem();
00841 return m_val == vp.m_val;
00842 }
00843
00844 int Double::Compare(const IComparable& a) const
00845 {
00846 if (a.MajicNumber() != MajicNumber())
00847 {
00848 return 1;
00849 }
00850 const Double& vp = static_cast<const Double&>(a);
00851 vp.ValidateMem();
00852 return (int)(m_val - vp.m_val);
00853 }
00854
00855 int32 Double::MajicNumber() const
00856 {
00857 return DOUBLE_MAJIC;
00858 }
00859
00860 int Double::ToInt() const
00861 {
00862 return (int)m_val;
00863 }
00864
00865 double Double::ToDouble() const
00866 {
00867 return (double)m_val;
00868 }
00869
00870 StringPtr Double::ToString() const
00871 {
00872 return ToString(m_val);
00873 }
00874
00875 bool Double::IsNaN(double d)
00876 {
00877 return std::numeric_limits<double>::quiet_NaN() == d;
00878 }
00879
00880 bool Double::IsPositiveZero(double d)
00881 {
00882 return d == 0.0;
00883 }
00884
00885 bool Double::IsNegativeZero(double d)
00886 {
00887 return d == -0.0;
00888 }
00889
00890 double Double::PositiveInfinity()
00891 {
00892 return HUGE_VAL;
00893 }
00894
00895 double Double::NegativeInfinity()
00896 {
00897 return -HUGE_VAL;
00898 }
00899
00900 #ifdef DEBUG
00901 void Double::ValidateMem() const
00902 {
00903 }
00904
00905 void Double::CheckMem() const
00906 {
00907 }
00908 #endif
00909
00910 float64 Double::Parse(const char *cp, const int cplen)
00911 {
00912 return atof(cp);
00913 }
00914
00915 bool Double::IsDouble(const char *cp, const int cplen)
00916 {
00917 return Numeric::IsNumeric(cp, cplen);
00918 }
00919
00920 StringPtr Double::ToString(float64 d)
00921 {
00922 char buf[256];
00923 sprintf(buf, "%f", d);
00924 StringPtr ret = String( buf ).RTrim('0');
00925 if (ret->EndsWith('.'))
00926 {
00927 return ret->Substring(0, ret->Length()-1);
00928 }
00929 return ret;
00930 }
00931
00932 Char::Char()
00933 : m_val(0)
00934 {
00935 }
00936
00937 Char::Char(const Char& i)
00938 : m_val(i.m_val)
00939 {
00940 }
00941
00942 Char::Char(const int i)
00943 : m_val(i)
00944 {
00945 }
00946
00947 Char::~Char()
00948 {
00949 }
00950
00951 bool Char::IsWhiteSpace(const int32 c)
00952 {
00953 switch(c)
00954 {
00955 case 0x0020:
00956 case 0x1680:
00957 case 0x180E:
00958 case 0x2000:
00959 case 0x2001:
00960 case 0x2002:
00961 case 0x2003:
00962 case 0x2004:
00963 case 0x2005:
00964 case 0x2006:
00965 case 0x2007:
00966 case 0x2008:
00967 case 0x2009:
00968 case 0x200A:
00969 case 0x202F:
00970 case 0x205F:
00971 case 0x3000:
00972 case 0x2028:
00973 case 0x2029:
00974 case 0x0009:
00975 case 0x000A:
00976 case 0x000B:
00977 case 0x000C:
00978 case 0x000D:
00979 case 0x0085:
00980 case 0x0000A0:
00981 return true;
00982 }
00983 return false;
00984 }
00985
00986 int32 Char::HashCode() const
00987 {
00988 if (m_val < 256)
00989 {
00990 return Math::Hash((char)m_val);
00991 }
00992 return Math::Hash(m_val);
00993 }
00994
00995 bool Char::Equals(const IComparable *a) const
00996 {
00997 if (a->MajicNumber() != MajicNumber())
00998 {
00999 return false;
01000 }
01001 const Char *c = static_cast<const Char *>(a);
01002 return m_val == c->m_val;
01003 }
01004
01005 int Char::Compare(const IComparable *a) const
01006 {
01007 if (a->MajicNumber() != MajicNumber())
01008 {
01009 return 1;
01010 }
01011 const Char *c = static_cast<const Char *>(a);
01012 return m_val - c->m_val;
01013 }
01014
01015 bool Char::Equals(const IComparable& a) const
01016 {
01017 if (a.MajicNumber() != MajicNumber())
01018 {
01019 return false;
01020 }
01021 const Char& c = static_cast<const Char&>(a);
01022 return m_val == c.m_val;
01023 }
01024
01025 int Char::Compare(const IComparable& a) const
01026 {
01027 if (a.MajicNumber() != MajicNumber())
01028 {
01029 return 1;
01030 }
01031 const Char& c = static_cast<const Char&>(a);
01032 return m_val - c.m_val;
01033 }
01034
01035 int32 Char::MajicNumber() const
01036 {
01037 return CHAR_MAJIC;
01038 }
01039
01040 int Char::ToInt() const
01041 {
01042 return m_val;
01043 }
01044
01045 double Char::ToDouble() const
01046 {
01047 return (double)m_val;
01048 }
01049
01050 StringPtr Char::ToString() const
01051 {
01052 return Char::ToString(m_val);
01053 }
01054
01055 StringPtr Char::ToString(char c)
01056 {
01057 return Char::ToString((int32)c);
01058 }
01059
01060 StringPtr Char::ToString(int32 c)
01061 {
01062 char buf[5];
01063 buf[0] = 0xFF & c;
01064 if (c < 256)
01065 {
01066 buf[1] = '\0';
01067 }
01068 else
01069 {
01070 buf[1] = 0xFF & (c >> 8);
01071 buf[2] = 0xFF & (c >> 16);
01072 buf[3] = 0xFF & (c >> 24);
01073 buf[4] = '\0';
01074 }
01075 return StringPtr(new String(buf));
01076 }
01077
01078 #ifdef DEBUG
01079 void Char::ValidateMem() const
01080 {
01081 }
01082
01083 void Char::CheckMem() const
01084 {
01085 }
01086 #endif
01087
01088 IConvertable::IConvertable()
01089 {
01090 }
01091
01092 IConvertable::~IConvertable()
01093 {
01094 }