• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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