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