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