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