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>
FXSYS_StrToInt(const CharType * str)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>
FXSYS_IntToStr(T value,STR_T str,int radix)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
FXSYS_atoi(const FX_CHAR * str)85 int32_t FXSYS_atoi(const FX_CHAR* str) {
86 return FXSYS_StrToInt<int32_t, FX_CHAR>(str);
87 }
FXSYS_atoui(const FX_CHAR * str)88 uint32_t FXSYS_atoui(const FX_CHAR* str) {
89 return FXSYS_StrToInt<uint32_t>(str);
90 }
FXSYS_wtoi(const FX_WCHAR * str)91 int32_t FXSYS_wtoi(const FX_WCHAR* str) {
92 return FXSYS_StrToInt<int32_t, FX_WCHAR>(str);
93 }
FXSYS_atoi64(const FX_CHAR * str)94 int64_t FXSYS_atoi64(const FX_CHAR* str) {
95 return FXSYS_StrToInt<int64_t, FX_CHAR>(str);
96 }
FXSYS_wtoi64(const FX_WCHAR * str)97 int64_t FXSYS_wtoi64(const FX_WCHAR* str) {
98 return FXSYS_StrToInt<int64_t, FX_WCHAR>(str);
99 }
FXSYS_i64toa(int64_t value,FX_CHAR * str,int radix)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
FXSYS_GetACP()110 int FXSYS_GetACP() {
111 return 0;
112 }
FXSYS_GetFullPathName(const FX_CHAR * filename,uint32_t buflen,FX_CHAR * buf,FX_CHAR ** filepart)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 }
FXSYS_GetModuleFileName(void * hModule,char * buf,uint32_t bufsize)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
FXSYS_wfopen(const FX_WCHAR * filename,const FX_WCHAR * mode)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 }
FXSYS_strlwr(char * str)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 }
FXSYS_strupr(char * str)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 }
FXSYS_wcslwr(FX_WCHAR * str)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 }
FXSYS_wcsupr(FX_WCHAR * str)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 }
FXSYS_stricmp(const char * dst,const char * src)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 }
FXSYS_wcsicmp(const FX_WCHAR * dst,const FX_WCHAR * src)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 }
FXSYS_itoa(int value,char * str,int radix)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
FXSYS_WideCharToMultiByte(uint32_t codepage,uint32_t dwFlags,const FX_WCHAR * wstr,int wlen,FX_CHAR * buf,int buflen,const FX_CHAR * default_str,int * pUseDefault)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 }
FXSYS_MultiByteToWideChar(uint32_t codepage,uint32_t dwFlags,const FX_CHAR * bstr,int blen,FX_WCHAR * buf,int buflen)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