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 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 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 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 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 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 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 106 void FXSYS_IntToFourHexChars(uint16_t n, char* buf) { 107 FXSYS_IntToTwoHexChars(n / 256, buf); 108 FXSYS_IntToTwoHexChars(n % 256, buf + 2); 109 } 110 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 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