Home | History | Annotate | Download | only in fxcrt
      1 // Copyright 2017 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "core/fxcrt/fx_system.h"
      8 
      9 #include <limits>
     10 
     11 #include "core/fxcrt/fx_extension.h"
     12 
     13 namespace {
     14 
     15 template <typename IntType, typename CharType>
     16 IntType FXSYS_StrToInt(const CharType* str) {
     17   if (!str)
     18     return 0;
     19 
     20   // Process the sign.
     21   bool neg = *str == '-';
     22   if (neg || *str == '+')
     23     str++;
     24 
     25   IntType num = 0;
     26   while (*str && FXSYS_isDecimalDigit(*str)) {
     27     IntType val = FXSYS_DecimalCharToInt(*str);
     28     if (num > (std::numeric_limits<IntType>::max() - val) / 10) {
     29       if (neg && std::numeric_limits<IntType>::is_signed) {
     30         // Return MIN when the represented number is signed type and is smaller
     31         // than the min value.
     32         return std::numeric_limits<IntType>::min();
     33       } else {
     34         // Return MAX when the represented number is signed type and is larger
     35         // than the max value, or the number is unsigned type and out of range.
     36         return std::numeric_limits<IntType>::max();
     37       }
     38     }
     39 
     40     num = num * 10 + val;
     41     str++;
     42   }
     43   // When it is a negative value, -num should be returned. Since num may be of
     44   // unsigned type, use ~num + 1 to avoid the warning of applying unary minus
     45   // operator to unsigned type.
     46   return neg ? ~num + 1 : num;
     47 }
     48 
     49 template <typename T, typename UT, typename STR_T>
     50 STR_T FXSYS_IntToStr(T value, STR_T str, int radix) {
     51   if (radix < 2 || radix > 16) {
     52     str[0] = 0;
     53     return str;
     54   }
     55   if (value == 0) {
     56     str[0] = '0';
     57     str[1] = 0;
     58     return str;
     59   }
     60   int i = 0;
     61   UT uvalue;
     62   if (value < 0) {
     63     str[i++] = '-';
     64     // Standard trick to avoid undefined behaviour when negating INT_MIN.
     65     uvalue = static_cast<UT>(-(value + 1)) + 1;
     66   } else {
     67     uvalue = value;
     68   }
     69   int digits = 1;
     70   T order = uvalue / radix;
     71   while (order > 0) {
     72     digits++;
     73     order = order / radix;
     74   }
     75   for (int d = digits - 1; d > -1; d--) {
     76     str[d + i] = "0123456789abcdef"[uvalue % radix];
     77     uvalue /= radix;
     78   }
     79   str[digits + i] = 0;
     80   return str;
     81 }
     82 
     83 }  // namespace
     84 
     85 int FXSYS_round(float d) {
     86   if (d < static_cast<float>(std::numeric_limits<int>::min()))
     87     return std::numeric_limits<int>::min();
     88   if (d > static_cast<float>(std::numeric_limits<int>::max()))
     89     return std::numeric_limits<int>::max();
     90   return static_cast<int>(round(d));
     91 }
     92 
     93 int32_t FXSYS_atoi(const char* str) {
     94   return FXSYS_StrToInt<int32_t, char>(str);
     95 }
     96 uint32_t FXSYS_atoui(const char* str) {
     97   return FXSYS_StrToInt<uint32_t>(str);
     98 }
     99 int32_t FXSYS_wtoi(const wchar_t* str) {
    100   return FXSYS_StrToInt<int32_t, wchar_t>(str);
    101 }
    102 int64_t FXSYS_atoi64(const char* str) {
    103   return FXSYS_StrToInt<int64_t, char>(str);
    104 }
    105 const char* FXSYS_i64toa(int64_t value, char* str, int radix) {
    106   return FXSYS_IntToStr<int64_t, uint64_t, char*>(value, str, radix);
    107 }
    108 
    109 #if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
    110 
    111 int FXSYS_GetACP() {
    112   return 0;
    113 }
    114 
    115 char* FXSYS_strlwr(char* str) {
    116   if (!str) {
    117     return nullptr;
    118   }
    119   char* s = str;
    120   while (*str) {
    121     *str = FXSYS_tolower(*str);
    122     str++;
    123   }
    124   return s;
    125 }
    126 char* FXSYS_strupr(char* str) {
    127   if (!str) {
    128     return nullptr;
    129   }
    130   char* s = str;
    131   while (*str) {
    132     *str = FXSYS_toupper(*str);
    133     str++;
    134   }
    135   return s;
    136 }
    137 wchar_t* FXSYS_wcslwr(wchar_t* str) {
    138   if (!str) {
    139     return nullptr;
    140   }
    141   wchar_t* s = str;
    142   while (*str) {
    143     *str = FXSYS_tolower(*str);
    144     str++;
    145   }
    146   return s;
    147 }
    148 wchar_t* FXSYS_wcsupr(wchar_t* str) {
    149   if (!str) {
    150     return nullptr;
    151   }
    152   wchar_t* s = str;
    153   while (*str) {
    154     *str = FXSYS_toupper(*str);
    155     str++;
    156   }
    157   return s;
    158 }
    159 
    160 int FXSYS_stricmp(const char* dst, const char* src) {
    161   int f;
    162   int l;
    163   do {
    164     f = FXSYS_toupper(*dst);
    165     l = FXSYS_toupper(*src);
    166     ++dst;
    167     ++src;
    168   } while (f && f == l);
    169   return f - l;
    170 }
    171 
    172 int FXSYS_wcsicmp(const wchar_t* dst, const wchar_t* src) {
    173   wchar_t f;
    174   wchar_t l;
    175   do {
    176     f = FXSYS_toupper(*dst);
    177     l = FXSYS_toupper(*src);
    178     ++dst;
    179     ++src;
    180   } while (f && f == l);
    181   return f - l;
    182 }
    183 
    184 char* FXSYS_itoa(int value, char* str, int radix) {
    185   return FXSYS_IntToStr<int32_t, uint32_t, char*>(value, str, radix);
    186 }
    187 
    188 int FXSYS_WideCharToMultiByte(uint32_t codepage,
    189                               uint32_t dwFlags,
    190                               const wchar_t* wstr,
    191                               int wlen,
    192                               char* buf,
    193                               int buflen,
    194                               const char* default_str,
    195                               int* pUseDefault) {
    196   int len = 0;
    197   for (int i = 0; i < wlen; i++) {
    198     if (wstr[i] < 0x100) {
    199       if (buf && len < buflen)
    200         buf[len] = static_cast<char>(wstr[i]);
    201       len++;
    202     }
    203   }
    204   return len;
    205 }
    206 int FXSYS_MultiByteToWideChar(uint32_t codepage,
    207                               uint32_t dwFlags,
    208                               const char* bstr,
    209                               int blen,
    210                               wchar_t* buf,
    211                               int buflen) {
    212   int wlen = 0;
    213   for (int i = 0; i < blen; i++) {
    214     if (buf && wlen < buflen) {
    215       buf[wlen] = bstr[i];
    216     }
    217     wlen++;
    218   }
    219   return wlen;
    220 }
    221 
    222 #else  // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
    223 
    224 size_t FXSYS_wcsftime(wchar_t* strDest,
    225                       size_t maxsize,
    226                       const wchar_t* format,
    227                       const struct tm* timeptr) {
    228   // Avoid tripping an invalid parameter handler and crashing process.
    229   // Note: leap seconds may cause tm_sec == 60.
    230   if (timeptr->tm_year < -1900 || timeptr->tm_year > 8099 ||
    231       timeptr->tm_mon < 0 || timeptr->tm_mon > 11 || timeptr->tm_mday < 1 ||
    232       timeptr->tm_mday > 31 || timeptr->tm_hour < 0 || timeptr->tm_hour > 23 ||
    233       timeptr->tm_min < 0 || timeptr->tm_min > 59 || timeptr->tm_sec < 0 ||
    234       timeptr->tm_sec > 60 || timeptr->tm_wday < 0 || timeptr->tm_wday > 6 ||
    235       timeptr->tm_yday < 0 || timeptr->tm_yday > 365) {
    236     strDest[0] = L'\0';
    237     return 0;
    238   }
    239   return wcsftime(strDest, maxsize, format, timeptr);
    240 }
    241 
    242 #endif  // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
    243