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
FXSYS_wcstof(const wchar_t * pwsStr,int32_t iLength,int32_t * pUsedLen)12 float FXSYS_wcstof(const wchar_t* pwsStr, int32_t iLength, int32_t* pUsedLen) {
13 ASSERT(pwsStr);
14 if (iLength < 0)
15 iLength = static_cast<int32_t>(wcslen(pwsStr));
16 if (iLength == 0)
17 return 0.0f;
18
19 int32_t iUsedLen = 0;
20 bool bNegtive = false;
21 switch (pwsStr[iUsedLen]) {
22 case '-':
23 bNegtive = true;
24 case '+':
25 iUsedLen++;
26 break;
27 }
28
29 float fValue = 0.0f;
30 while (iUsedLen < iLength) {
31 wchar_t wch = pwsStr[iUsedLen];
32 if (!std::iswdigit(wch))
33 break;
34
35 fValue = fValue * 10.0f + (wch - L'0');
36 iUsedLen++;
37 }
38
39 if (iUsedLen < iLength && pwsStr[iUsedLen] == L'.') {
40 float fPrecise = 0.1f;
41 while (++iUsedLen < iLength) {
42 wchar_t wch = pwsStr[iUsedLen];
43 if (!std::iswdigit(wch))
44 break;
45
46 fValue += (wch - L'0') * fPrecise;
47 fPrecise *= 0.1f;
48 }
49 }
50 if (pUsedLen)
51 *pUsedLen = iUsedLen;
52
53 return bNegtive ? -fValue : fValue;
54 }
55
FXSYS_wcsncpy(wchar_t * dstStr,const wchar_t * srcStr,size_t count)56 wchar_t* FXSYS_wcsncpy(wchar_t* dstStr, const wchar_t* srcStr, size_t count) {
57 ASSERT(dstStr && srcStr && count > 0);
58 for (size_t i = 0; i < count; ++i)
59 if ((dstStr[i] = srcStr[i]) == L'\0')
60 break;
61 return dstStr;
62 }
63
FXSYS_wcsnicmp(const wchar_t * s1,const wchar_t * s2,size_t count)64 int32_t FXSYS_wcsnicmp(const wchar_t* s1, const wchar_t* s2, size_t count) {
65 ASSERT(s1 && s2 && count > 0);
66 wchar_t wch1 = 0, wch2 = 0;
67 while (count-- > 0) {
68 wch1 = static_cast<wchar_t>(FXSYS_tolower(*s1++));
69 wch2 = static_cast<wchar_t>(FXSYS_tolower(*s2++));
70 if (wch1 != wch2)
71 break;
72 }
73 return wch1 - wch2;
74 }
75
FX_HashCode_GetA(const ByteStringView & str,bool bIgnoreCase)76 uint32_t FX_HashCode_GetA(const ByteStringView& str, bool bIgnoreCase) {
77 uint32_t dwHashCode = 0;
78 if (bIgnoreCase) {
79 for (const auto& c : str)
80 dwHashCode = 31 * dwHashCode + FXSYS_tolower(c);
81 } else {
82 for (const auto& c : str)
83 dwHashCode = 31 * dwHashCode + c;
84 }
85 return dwHashCode;
86 }
87
FX_HashCode_GetW(const WideStringView & str,bool bIgnoreCase)88 uint32_t FX_HashCode_GetW(const WideStringView& str, bool bIgnoreCase) {
89 uint32_t dwHashCode = 0;
90 if (bIgnoreCase) {
91 for (const auto& c : str)
92 dwHashCode = 1313 * dwHashCode + FXSYS_tolower(c);
93 } else {
94 for (const auto& c : str)
95 dwHashCode = 1313 * dwHashCode + c;
96 }
97 return dwHashCode;
98 }
99
FXSYS_IntToTwoHexChars(uint8_t n,char * buf)100 void FXSYS_IntToTwoHexChars(uint8_t n, char* buf) {
101 static const char kHex[] = "0123456789ABCDEF";
102 buf[0] = kHex[n / 16];
103 buf[1] = kHex[n % 16];
104 }
105
FXSYS_IntToFourHexChars(uint16_t n,char * buf)106 void FXSYS_IntToFourHexChars(uint16_t n, char* buf) {
107 FXSYS_IntToTwoHexChars(n / 256, buf);
108 FXSYS_IntToTwoHexChars(n % 256, buf + 2);
109 }
110
FXSYS_ToUTF16BE(uint32_t unicode,char * buf)111 size_t FXSYS_ToUTF16BE(uint32_t unicode, char* buf) {
112 ASSERT(unicode <= 0xD7FF || (unicode > 0xDFFF && unicode <= 0x10FFFF));
113 if (unicode <= 0xFFFF) {
114 FXSYS_IntToFourHexChars(unicode, buf);
115 return 4;
116 }
117 unicode -= 0x010000;
118 // High ten bits plus 0xD800
119 FXSYS_IntToFourHexChars(0xD800 + unicode / 0x400, buf);
120 // Low ten bits plus 0xDC00
121 FXSYS_IntToFourHexChars(0xDC00 + unicode % 0x400, buf + 4);
122 return 8;
123 }
124
GetBits32(const uint8_t * pData,int bitpos,int nbits)125 uint32_t GetBits32(const uint8_t* pData, int bitpos, int nbits) {
126 ASSERT(0 < nbits && nbits <= 32);
127 const uint8_t* dataPtr = &pData[bitpos / 8];
128 int bitShift;
129 int bitMask;
130 int dstShift;
131 int bitCount = bitpos & 0x07;
132 if (nbits < 8 && nbits + bitCount <= 8) {
133 bitShift = 8 - nbits - bitCount;
134 bitMask = (1 << nbits) - 1;
135 dstShift = 0;
136 } else {
137 bitShift = 0;
138 int bitOffset = 8 - bitCount;
139 bitMask = (1 << std::min(bitOffset, nbits)) - 1;
140 dstShift = nbits - bitOffset;
141 }
142 uint32_t result =
143 static_cast<uint32_t>((*dataPtr++ >> bitShift & bitMask) << dstShift);
144 while (dstShift >= 8) {
145 dstShift -= 8;
146 result |= *dataPtr++ << dstShift;
147 }
148 if (dstShift > 0) {
149 bitShift = 8 - dstShift;
150 bitMask = (1 << dstShift) - 1;
151 result |= *dataPtr++ >> bitShift & bitMask;
152 }
153 return result;
154 }
155