1 // Copyright 2014 The PDFium Authors
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_extension.h"
8
9 #include <algorithm>
10 #include <limits>
11
12 #include "core/fxcrt/fx_system.h"
13 #include "third_party/base/check.h"
14
15 namespace {
16
DefaultTimeFunction()17 time_t DefaultTimeFunction() {
18 return time(nullptr);
19 }
20
DefaultLocaltimeFunction(const time_t * tp)21 struct tm* DefaultLocaltimeFunction(const time_t* tp) {
22 return localtime(tp);
23 }
24
25 time_t (*g_time_func)() = DefaultTimeFunction;
26 struct tm* (*g_localtime_func)(const time_t*) = DefaultLocaltimeFunction;
27
28 } // namespace
29
FXSYS_wcstof(const wchar_t * pwsStr,size_t nLength,size_t * pUsedLen)30 float FXSYS_wcstof(const wchar_t* pwsStr, size_t nLength, size_t* pUsedLen) {
31 DCHECK(pwsStr);
32 if (nLength == 0)
33 return 0.0f;
34
35 size_t nUsedLen = 0;
36 bool bNegtive = false;
37 switch (pwsStr[nUsedLen]) {
38 case '-':
39 bNegtive = true;
40 [[fallthrough]];
41 case '+':
42 nUsedLen++;
43 break;
44 }
45
46 float fValue = 0.0f;
47 while (nUsedLen < nLength) {
48 wchar_t wch = pwsStr[nUsedLen];
49 if (!FXSYS_IsDecimalDigit(wch))
50 break;
51
52 fValue = fValue * 10.0f + (wch - L'0');
53 nUsedLen++;
54 }
55
56 if (nUsedLen < nLength && pwsStr[nUsedLen] == L'.') {
57 float fPrecise = 0.1f;
58 while (++nUsedLen < nLength) {
59 wchar_t wch = pwsStr[nUsedLen];
60 if (!FXSYS_IsDecimalDigit(wch))
61 break;
62
63 fValue += (wch - L'0') * fPrecise;
64 fPrecise *= 0.1f;
65 }
66 }
67
68 if (nUsedLen < nLength &&
69 (pwsStr[nUsedLen] == 'e' || pwsStr[nUsedLen] == 'E')) {
70 ++nUsedLen;
71
72 bool negative_exponent = false;
73 if (nUsedLen < nLength &&
74 (pwsStr[nUsedLen] == '-' || pwsStr[nUsedLen] == '+')) {
75 negative_exponent = pwsStr[nUsedLen] == '-';
76 ++nUsedLen;
77 }
78
79 int32_t exp_value = 0;
80 while (nUsedLen < nLength) {
81 wchar_t wch = pwsStr[nUsedLen];
82 if (!FXSYS_IsDecimalDigit(wch))
83 break;
84
85 exp_value = exp_value * 10.0f + (wch - L'0');
86 // Exponent is outside the valid range, fail.
87 if ((negative_exponent &&
88 -exp_value < std::numeric_limits<float>::min_exponent10) ||
89 (!negative_exponent &&
90 exp_value > std::numeric_limits<float>::max_exponent10)) {
91 if (pUsedLen)
92 *pUsedLen = 0;
93 return 0.0f;
94 }
95
96 ++nUsedLen;
97 }
98
99 for (size_t i = exp_value; i > 0; --i) {
100 if (exp_value > 0) {
101 if (negative_exponent)
102 fValue /= 10;
103 else
104 fValue *= 10;
105 }
106 }
107 }
108
109 if (pUsedLen)
110 *pUsedLen = nUsedLen;
111
112 return bNegtive ? -fValue : fValue;
113 }
114
FXSYS_wcsncpy(wchar_t * dstStr,const wchar_t * srcStr,size_t count)115 wchar_t* FXSYS_wcsncpy(wchar_t* dstStr, const wchar_t* srcStr, size_t count) {
116 DCHECK(dstStr);
117 DCHECK(srcStr);
118 DCHECK(count > 0);
119
120 for (size_t i = 0; i < count; ++i)
121 if ((dstStr[i] = srcStr[i]) == L'\0')
122 break;
123 return dstStr;
124 }
125
FXSYS_wcsnicmp(const wchar_t * s1,const wchar_t * s2,size_t count)126 int32_t FXSYS_wcsnicmp(const wchar_t* s1, const wchar_t* s2, size_t count) {
127 DCHECK(s1);
128 DCHECK(s2);
129 DCHECK(count > 0);
130
131 wchar_t wch1 = 0, wch2 = 0;
132 while (count-- > 0) {
133 wch1 = static_cast<wchar_t>(FXSYS_towlower(*s1++));
134 wch2 = static_cast<wchar_t>(FXSYS_towlower(*s2++));
135 if (wch1 != wch2)
136 break;
137 }
138 return wch1 - wch2;
139 }
140
FXSYS_IntToTwoHexChars(uint8_t n,char * buf)141 void FXSYS_IntToTwoHexChars(uint8_t n, char* buf) {
142 static const char kHex[] = "0123456789ABCDEF";
143 buf[0] = kHex[n / 16];
144 buf[1] = kHex[n % 16];
145 }
146
FXSYS_IntToFourHexChars(uint16_t n,char * buf)147 void FXSYS_IntToFourHexChars(uint16_t n, char* buf) {
148 FXSYS_IntToTwoHexChars(n / 256, buf);
149 FXSYS_IntToTwoHexChars(n % 256, buf + 2);
150 }
151
FXSYS_ToUTF16BE(uint32_t unicode,char * buf)152 size_t FXSYS_ToUTF16BE(uint32_t unicode, char* buf) {
153 DCHECK(unicode <= 0xD7FF || (unicode > 0xDFFF && unicode <= 0x10FFFF));
154 if (unicode <= 0xFFFF) {
155 FXSYS_IntToFourHexChars(unicode, buf);
156 return 4;
157 }
158 unicode -= 0x010000;
159 // High ten bits plus 0xD800
160 FXSYS_IntToFourHexChars(0xD800 + unicode / 0x400, buf);
161 // Low ten bits plus 0xDC00
162 FXSYS_IntToFourHexChars(0xDC00 + unicode % 0x400, buf + 4);
163 return 8;
164 }
165
FXSYS_SetTimeFunction(time_t (* func)())166 void FXSYS_SetTimeFunction(time_t (*func)()) {
167 g_time_func = func ? func : DefaultTimeFunction;
168 }
169
FXSYS_SetLocaltimeFunction(struct tm * (* func)(const time_t *))170 void FXSYS_SetLocaltimeFunction(struct tm* (*func)(const time_t*)) {
171 g_localtime_func = func ? func : DefaultLocaltimeFunction;
172 }
173
FXSYS_time(time_t * tloc)174 time_t FXSYS_time(time_t* tloc) {
175 time_t ret_val = g_time_func();
176 if (tloc)
177 *tloc = ret_val;
178 return ret_val;
179 }
180
FXSYS_localtime(const time_t * tp)181 struct tm* FXSYS_localtime(const time_t* tp) {
182 return g_localtime_func(tp);
183 }
184