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