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