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 <algorithm> 8 9 #include "xfa/src/fgas/src/fgas_base.h" 10 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \ 11 _FX_OS_ == _FX_WIN64_ 12 #include <io.h> 13 #elif _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_LINUX_Mini_ 14 #include <sys/times.h> 15 #endif 16 #ifdef __cplusplus 17 extern "C" { 18 #endif 19 FX_FLOAT FX_tan(FX_FLOAT a) { 20 return (FX_FLOAT)tan(a); 21 } 22 FX_FLOAT FX_log(FX_FLOAT b, FX_FLOAT x) { 23 return FXSYS_log(x) / FXSYS_log(b); 24 } 25 FX_WCHAR* FX_wcsncpy(FX_WCHAR* dstStr, const FX_WCHAR* srcStr, size_t count) { 26 FXSYS_assert(dstStr != NULL && srcStr != NULL && count > 0); 27 for (size_t i = 0; i < count; ++i) 28 if ((dstStr[i] = srcStr[i]) == L'\0') { 29 break; 30 } 31 return dstStr; 32 } 33 int32_t FX_wcsnicmp(const FX_WCHAR* s1, const FX_WCHAR* s2, size_t count) { 34 FXSYS_assert(s1 != NULL && s2 != NULL && count > 0); 35 FX_WCHAR wch1 = 0, wch2 = 0; 36 while (count-- > 0) { 37 wch1 = (FX_WCHAR)FX_tolower(*s1++); 38 wch2 = (FX_WCHAR)FX_tolower(*s2++); 39 if (wch1 != wch2) { 40 break; 41 } 42 } 43 return wch1 - wch2; 44 } 45 int32_t FX_strnicmp(const FX_CHAR* s1, const FX_CHAR* s2, size_t count) { 46 FXSYS_assert(s1 != NULL && s2 != NULL && count > 0); 47 FX_CHAR ch1 = 0, ch2 = 0; 48 while (count-- > 0) { 49 ch1 = (FX_CHAR)FX_tolower(*s1++); 50 ch2 = (FX_CHAR)FX_tolower(*s2++); 51 if (ch1 != ch2) { 52 break; 53 } 54 } 55 return ch1 - ch2; 56 } 57 int32_t FX_filelength(FXSYS_FILE* file) { 58 FXSYS_assert(file != NULL); 59 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ 60 return _filelength(_fileno(file)); 61 #else 62 int32_t iPos = FXSYS_ftell(file); 63 FXSYS_fseek(file, 0, FXSYS_SEEK_END); 64 int32_t iLen = FXSYS_ftell(file); 65 FXSYS_fseek(file, iPos, FXSYS_SEEK_SET); 66 return iLen; 67 #endif 68 } 69 FX_BOOL FX_fsetsize(FXSYS_FILE* file, int32_t size) { 70 FXSYS_assert(file != NULL); 71 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ 72 return _chsize(_fileno(file), size) == 0; 73 #elif _FX_OS_ == _FX_WIN32_MOBILE_ 74 HANDLE hFile = _fileno(file); 75 FX_DWORD dwPos = ::SetFilePointer(hFile, 0, 0, FILE_CURRENT); 76 ::SetFilePointer(hFile, size, 0, FILE_BEGIN); 77 FX_BOOL bRet = ::SetEndOfFile(hFile); 78 ::SetFilePointer(hFile, (int32_t)dwPos, 0, FILE_BEGIN); 79 return bRet; 80 #else 81 return FALSE; 82 #endif 83 } 84 FX_FLOAT FX_strtof(const FX_CHAR* pcsStr, int32_t iLength, int32_t* pUsedLen) { 85 FXSYS_assert(pcsStr != NULL); 86 if (iLength < 0) { 87 iLength = FXSYS_strlen(pcsStr); 88 } 89 return FX_wcstof(CFX_WideString::FromLocal(pcsStr, iLength), iLength, 90 pUsedLen); 91 } 92 FX_FLOAT FX_wcstof(const FX_WCHAR* pwsStr, int32_t iLength, int32_t* pUsedLen) { 93 FXSYS_assert(pwsStr != NULL); 94 if (iLength < 0) { 95 iLength = FXSYS_wcslen(pwsStr); 96 } 97 if (iLength == 0) { 98 return 0.0f; 99 } 100 int32_t iUsedLen = 0; 101 FX_BOOL bNegtive = FALSE; 102 switch (pwsStr[iUsedLen]) { 103 case '-': 104 bNegtive = TRUE; 105 case '+': 106 iUsedLen++; 107 break; 108 } 109 FX_FLOAT fValue = 0.0f; 110 while (iUsedLen < iLength) { 111 FX_WCHAR wch = pwsStr[iUsedLen]; 112 if (wch >= L'0' && wch <= L'9') { 113 fValue = fValue * 10.0f + (wch - L'0'); 114 } else { 115 break; 116 } 117 iUsedLen++; 118 } 119 if (iUsedLen < iLength && pwsStr[iUsedLen] == L'.') { 120 FX_FLOAT fPrecise = 0.1f; 121 while (++iUsedLen < iLength) { 122 FX_WCHAR wch = pwsStr[iUsedLen]; 123 if (wch >= L'0' && wch <= L'9') { 124 fValue += (wch - L'0') * fPrecise; 125 fPrecise *= 0.1f; 126 } else { 127 break; 128 } 129 } 130 } 131 if (pUsedLen) { 132 *pUsedLen = iUsedLen; 133 } 134 return bNegtive ? -fValue : fValue; 135 } 136 void FX_memset(void* pBuf, int32_t iValue, size_t size) { 137 FXSYS_assert(pBuf != NULL && size > 0 && (size & 0x03) == 0); 138 FXSYS_assert((((size_t)pBuf) & 0x03) == 0); 139 FX_DWORD* pStart = (FX_DWORD*)pBuf; 140 FX_DWORD* pEnd = pStart + (size >> 2); 141 while (pStart < pEnd) { 142 *pStart++ = iValue; 143 } 144 } 145 void FX_memcpy(void* pDst, const void* pSrc, size_t size) { 146 FXSYS_assert(pDst != NULL && pSrc != NULL && size > 0 && (size & 0x03) == 0); 147 FXSYS_assert((((size_t)pDst) & 0x03) == 0 && (((size_t)pSrc) & 0x03) == 0); 148 FX_DWORD* pStart = (FX_DWORD*)pDst; 149 FX_DWORD* pEnd = pStart + (size >> 2); 150 FX_DWORD* pValue = (FX_DWORD*)pSrc; 151 while (pStart < pEnd) { 152 *pStart++ = *pValue++; 153 } 154 } 155 FX_BOOL FX_IsRelativePath(const CFX_WideStringC& wsUrl) { 156 int32_t iUrlLen = wsUrl.GetLength(); 157 if (iUrlLen == 0) { 158 return TRUE; 159 } 160 for (int32_t i = std::min(5, iUrlLen) - 1; i >= 0; --i) 161 if (wsUrl.GetAt(i) == ':') { 162 return FALSE; 163 } 164 return TRUE; 165 } 166 FX_BOOL FX_JoinPath(const CFX_WideStringC& wsBasePath, 167 const CFX_WideStringC& wsRelativePath, 168 CFX_WideString& wsAbsolutePath) { 169 if (!FX_IsRelativePath(wsRelativePath)) { 170 wsAbsolutePath = wsRelativePath; 171 return TRUE; 172 } 173 const FX_WCHAR* pRelStart = wsRelativePath.GetPtr(); 174 const FX_WCHAR* pRelEnd = pRelStart + wsRelativePath.GetLength(); 175 if (pRelStart < pRelEnd) { 176 switch (*pRelStart) { 177 case '#': 178 wsAbsolutePath = CFX_WideString(wsBasePath, wsRelativePath); 179 return wsAbsolutePath.GetLength() > 0; 180 case '/': 181 case '\\': 182 wsAbsolutePath = wsRelativePath; 183 return wsAbsolutePath.GetLength() > 0; 184 } 185 } 186 int32_t nBackCount = 0; 187 for (;;) { 188 if (pRelStart >= pRelEnd) { 189 wsAbsolutePath = wsBasePath; 190 return TRUE; 191 } 192 if (*pRelStart != '.') { 193 break; 194 } 195 if (pRelStart + 1 < pRelEnd && 196 (pRelStart[1] == '/' || pRelStart[1] == '\\')) { 197 pRelStart += 2; 198 } else if (pRelStart + 2 < pRelEnd && pRelStart[1] == '.' && 199 (pRelStart[2] == '/' || pRelStart[2] == '\\')) { 200 pRelStart += 3; 201 nBackCount++; 202 } else { 203 return FALSE; 204 } 205 } 206 const FX_WCHAR* pBaseStart = wsBasePath.GetPtr(); 207 const FX_WCHAR* pBaseEnd = pBaseStart + wsBasePath.GetLength(); 208 while (pBaseStart < (--pBaseEnd) && *pBaseEnd != '/' && *pBaseEnd != '\\') 209 ; 210 if (pBaseStart == pBaseEnd) { 211 wsAbsolutePath = CFX_WideStringC(pRelStart, pRelEnd - pRelStart); 212 return wsAbsolutePath.GetLength() > 0; 213 } 214 while (nBackCount > 0) { 215 if (pBaseStart >= (--pBaseEnd)) { 216 return FALSE; 217 } else if (*pBaseEnd == '/' || *pBaseEnd == '\\') 218 if ((--nBackCount) <= 0) { 219 break; 220 } 221 } 222 wsAbsolutePath = 223 CFX_WideString(CFX_WideStringC(pBaseStart, pBaseEnd - pBaseStart + 1), 224 CFX_WideStringC(pRelStart, pRelEnd - pRelStart)); 225 return wsAbsolutePath.GetLength() > 0; 226 } 227 #ifdef __cplusplus 228 }; 229 #endif 230