Home | History | Annotate | Download | only in fxcrt
      1 // Copyright 2014 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 <cctype>
      8 #include <cwctype>
      9 #include <limits>
     10 
     11 #include "core/fxcrt/fx_ext.h"
     12 #include "core/fxcrt/fx_string.h"
     13 
     14 template <typename IntType, typename CharType>
     15 IntType FXSYS_StrToInt(const CharType* str) {
     16   if (!str)
     17     return 0;
     18 
     19   // Process the sign.
     20   bool neg = *str == '-';
     21   if (neg || *str == '+')
     22     str++;
     23 
     24   IntType num = 0;
     25   while (*str && FXSYS_isDecimalDigit(*str)) {
     26     IntType val = FXSYS_toDecimalDigit(*str);
     27     if (num > (std::numeric_limits<IntType>::max() - val) / 10) {
     28       if (neg && std::numeric_limits<IntType>::is_signed) {
     29         // Return MIN when the represented number is signed type and is smaller
     30         // than the min value.
     31         return std::numeric_limits<IntType>::min();
     32       } else {
     33         // Return MAX when the represented number is signed type and is larger
     34         // than the max value, or the number is unsigned type and out of range.
     35         return std::numeric_limits<IntType>::max();
     36       }
     37     }
     38 
     39     num = num * 10 + val;
     40     str++;
     41   }
     42   // When it is a negative value, -num should be returned. Since num may be of
     43   // unsigned type, use ~num + 1 to avoid the warning of applying unary minus
     44   // operator to unsigned type.
     45   return neg ? ~num + 1 : num;
     46 }
     47 
     48 template <typename T, typename UT, typename STR_T>
     49 STR_T FXSYS_IntToStr(T value, STR_T str, int radix) {
     50   if (radix < 2 || radix > 16) {
     51     str[0] = 0;
     52     return str;
     53   }
     54   if (value == 0) {
     55     str[0] = '0';
     56     str[1] = 0;
     57     return str;
     58   }
     59   int i = 0;
     60   UT uvalue;
     61   if (value < 0) {
     62     str[i++] = '-';
     63     // Standard trick to avoid undefined behaviour when negating INT_MIN.
     64     uvalue = static_cast<UT>(-(value + 1)) + 1;
     65   } else {
     66     uvalue = value;
     67   }
     68   int digits = 1;
     69   T order = uvalue / radix;
     70   while (order > 0) {
     71     digits++;
     72     order = order / radix;
     73   }
     74   for (int d = digits - 1; d > -1; d--) {
     75     str[d + i] = "0123456789abcdef"[uvalue % radix];
     76     uvalue /= radix;
     77   }
     78   str[digits + i] = 0;
     79   return str;
     80 }
     81 
     82 #ifdef __cplusplus
     83 extern "C" {
     84 #endif
     85 int32_t FXSYS_atoi(const FX_CHAR* str) {
     86   return FXSYS_StrToInt<int32_t, FX_CHAR>(str);
     87 }
     88 uint32_t FXSYS_atoui(const FX_CHAR* str) {
     89   return FXSYS_StrToInt<uint32_t>(str);
     90 }
     91 int32_t FXSYS_wtoi(const FX_WCHAR* str) {
     92   return FXSYS_StrToInt<int32_t, FX_WCHAR>(str);
     93 }
     94 int64_t FXSYS_atoi64(const FX_CHAR* str) {
     95   return FXSYS_StrToInt<int64_t, FX_CHAR>(str);
     96 }
     97 int64_t FXSYS_wtoi64(const FX_WCHAR* str) {
     98   return FXSYS_StrToInt<int64_t, FX_WCHAR>(str);
     99 }
    100 const FX_CHAR* FXSYS_i64toa(int64_t value, FX_CHAR* str, int radix) {
    101   return FXSYS_IntToStr<int64_t, uint64_t, FX_CHAR*>(value, str, radix);
    102 }
    103 #ifdef __cplusplus
    104 }
    105 #endif
    106 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
    107 #ifdef __cplusplus
    108 extern "C" {
    109 #endif
    110 int FXSYS_GetACP() {
    111   return 0;
    112 }
    113 uint32_t FXSYS_GetFullPathName(const FX_CHAR* filename,
    114                                uint32_t buflen,
    115                                FX_CHAR* buf,
    116                                FX_CHAR** filepart) {
    117   int srclen = FXSYS_strlen(filename);
    118   if (!buf || (int)buflen < srclen + 1) {
    119     return srclen + 1;
    120   }
    121   FXSYS_strcpy(buf, filename);
    122   return srclen;
    123 }
    124 uint32_t FXSYS_GetModuleFileName(void* hModule, char* buf, uint32_t bufsize) {
    125   return (uint32_t)-1;
    126 }
    127 #ifdef __cplusplus
    128 }
    129 #endif
    130 #endif
    131 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
    132 #ifdef __cplusplus
    133 extern "C" {
    134 #endif
    135 FXSYS_FILE* FXSYS_wfopen(const FX_WCHAR* filename, const FX_WCHAR* mode) {
    136   return FXSYS_fopen(CFX_ByteString::FromUnicode(filename).c_str(),
    137                      CFX_ByteString::FromUnicode(mode).c_str());
    138 }
    139 char* FXSYS_strlwr(char* str) {
    140   if (!str) {
    141     return nullptr;
    142   }
    143   char* s = str;
    144   while (*str) {
    145     *str = FXSYS_tolower(*str);
    146     str++;
    147   }
    148   return s;
    149 }
    150 char* FXSYS_strupr(char* str) {
    151   if (!str) {
    152     return nullptr;
    153   }
    154   char* s = str;
    155   while (*str) {
    156     *str = FXSYS_toupper(*str);
    157     str++;
    158   }
    159   return s;
    160 }
    161 FX_WCHAR* FXSYS_wcslwr(FX_WCHAR* str) {
    162   if (!str) {
    163     return nullptr;
    164   }
    165   FX_WCHAR* s = str;
    166   while (*str) {
    167     *str = FXSYS_tolower(*str);
    168     str++;
    169   }
    170   return s;
    171 }
    172 FX_WCHAR* FXSYS_wcsupr(FX_WCHAR* str) {
    173   if (!str) {
    174     return nullptr;
    175   }
    176   FX_WCHAR* s = str;
    177   while (*str) {
    178     *str = FXSYS_toupper(*str);
    179     str++;
    180   }
    181   return s;
    182 }
    183 int FXSYS_stricmp(const char* dst, const char* src) {
    184   int f, l;
    185   do {
    186     if (((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z')) {
    187       f -= ('A' - 'a');
    188     }
    189     if (((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z')) {
    190       l -= ('A' - 'a');
    191     }
    192   } while (f && (f == l));
    193   return (f - l);
    194 }
    195 int FXSYS_wcsicmp(const FX_WCHAR* dst, const FX_WCHAR* src) {
    196   FX_WCHAR f, l;
    197   do {
    198     if (((f = (FX_WCHAR)(*(dst++))) >= 'A') && (f <= 'Z')) {
    199       f -= ('A' - 'a');
    200     }
    201     if (((l = (FX_WCHAR)(*(src++))) >= 'A') && (l <= 'Z')) {
    202       l -= ('A' - 'a');
    203     }
    204   } while (f && (f == l));
    205   return (f - l);
    206 }
    207 char* FXSYS_itoa(int value, char* str, int radix) {
    208   return FXSYS_IntToStr<int32_t, uint32_t, FX_CHAR*>(value, str, radix);
    209 }
    210 #ifdef __cplusplus
    211 }
    212 #endif
    213 #endif
    214 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
    215 #ifdef __cplusplus
    216 extern "C" {
    217 #endif
    218 int FXSYS_WideCharToMultiByte(uint32_t codepage,
    219                               uint32_t dwFlags,
    220                               const FX_WCHAR* wstr,
    221                               int wlen,
    222                               FX_CHAR* buf,
    223                               int buflen,
    224                               const FX_CHAR* default_str,
    225                               int* pUseDefault) {
    226   int len = 0;
    227   for (int i = 0; i < wlen; i++) {
    228     if (wstr[i] < 0x100) {
    229       if (buf && len < buflen)
    230         buf[len] = static_cast<FX_CHAR>(wstr[i]);
    231       len++;
    232     }
    233   }
    234   return len;
    235 }
    236 int FXSYS_MultiByteToWideChar(uint32_t codepage,
    237                               uint32_t dwFlags,
    238                               const FX_CHAR* bstr,
    239                               int blen,
    240                               FX_WCHAR* buf,
    241                               int buflen) {
    242   int wlen = 0;
    243   for (int i = 0; i < blen; i++) {
    244     if (buf && wlen < buflen) {
    245       buf[wlen] = bstr[i];
    246     }
    247     wlen++;
    248   }
    249   return wlen;
    250 }
    251 #ifdef __cplusplus
    252 }
    253 #endif
    254 #endif
    255