Home | History | Annotate | Download | only in Common
      1 // Common/StringToInt.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "StringToInt.h"
      6 
      7 static const UInt32 k_UInt32_max = 0xFFFFFFFF;
      8 static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF);
      9 // static const UInt64 k_UInt64_max = (UInt64)(Int64)-1;
     10 
     11 #define CONVERT_STRING_TO_UINT_FUNC(uintType, charType, charTypeUnsigned) \
     12   uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \
     13     if (end) *end = s; \
     14     uintType res = 0; \
     15     for (;; s++) { \
     16       charTypeUnsigned c = (charTypeUnsigned)*s; \
     17       if (c < '0' || c > '9') { if (end) *end = s; return res; } \
     18       if (res > (k_ ## uintType ## _max) / 10) return 0; \
     19       res *= 10; \
     20       unsigned v = (c - '0'); \
     21       if (res > (k_ ## uintType ## _max) - v) return 0; \
     22       res += v; }}
     23 
     24 CONVERT_STRING_TO_UINT_FUNC(UInt32, char, Byte)
     25 CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t, wchar_t)
     26 CONVERT_STRING_TO_UINT_FUNC(UInt64, char, Byte)
     27 CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t, wchar_t)
     28 
     29 Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw()
     30 {
     31   if (end)
     32     *end = s;
     33   const wchar_t *s2 = s;
     34   if (*s == '-')
     35     s2++;
     36   if (*s2 == 0)
     37     return 0;
     38   const wchar_t *end2;
     39   UInt32 res = ConvertStringToUInt32(s2, &end2);
     40   if (*s == '-')
     41   {
     42     if (res > ((UInt32)1 << (32 - 1)))
     43       return 0;
     44   }
     45   else if ((res & ((UInt32)1 << (32 - 1))) != 0)
     46     return 0;
     47   if (end)
     48     *end = end2;
     49   if (*s == '-')
     50     return -(Int32)res;
     51   return (Int32)res;
     52 }
     53 
     54 UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw()
     55 {
     56   if (end)
     57     *end = s;
     58   UInt32 res = 0;
     59   for (;; s++)
     60   {
     61     unsigned c = (unsigned char)*s;
     62     if (c < '0' || c > '7')
     63     {
     64       if (end)
     65         *end = s;
     66       return res;
     67     }
     68     if ((res & (UInt32)7 << (32 - 3)) != 0)
     69       return 0;
     70     res <<= 3;
     71     res |= (unsigned)(c - '0');
     72   }
     73 }
     74 
     75 UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw()
     76 {
     77   if (end)
     78     *end = s;
     79   UInt64 res = 0;
     80   for (;; s++)
     81   {
     82     unsigned c = (unsigned char)*s;
     83     if (c < '0' || c > '7')
     84     {
     85       if (end)
     86         *end = s;
     87       return res;
     88     }
     89     if ((res & (UInt64)7 << (64 - 3)) != 0)
     90       return 0;
     91     res <<= 3;
     92     res |= (unsigned)(c - '0');
     93   }
     94 }
     95 
     96 UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw()
     97 {
     98   if (end)
     99     *end = s;
    100   UInt32 res = 0;
    101   for (;; s++)
    102   {
    103     unsigned c = (Byte)*s;
    104     unsigned v;
    105     if (c >= '0' && c <= '9') v = (c - '0');
    106     else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
    107     else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
    108     else
    109     {
    110       if (end)
    111         *end = s;
    112       return res;
    113     }
    114     if ((res & (UInt32)0xF << (32 - 4)) != 0)
    115       return 0;
    116     res <<= 4;
    117     res |= v;
    118   }
    119 }
    120 
    121 UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw()
    122 {
    123   if (end)
    124     *end = s;
    125   UInt64 res = 0;
    126   for (;; s++)
    127   {
    128     unsigned c = (Byte)*s;
    129     unsigned v;
    130     if (c >= '0' && c <= '9') v = (c - '0');
    131     else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
    132     else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
    133     else
    134     {
    135       if (end)
    136         *end = s;
    137       return res;
    138     }
    139     if ((res & (UInt64)0xF << (64 - 4)) != 0)
    140       return 0;
    141     res <<= 4;
    142     res |= v;
    143   }
    144 }
    145