| // Copyright 2014 PDFium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| |
| #include <algorithm> |
| |
| #include "xfa/src/fgas/src/fgas_base.h" |
| #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \ |
| _FX_OS_ == _FX_WIN64_ |
| #include <io.h> |
| #elif _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_LINUX_Mini_ |
| #include <sys/times.h> |
| #endif |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| FX_FLOAT FX_tan(FX_FLOAT a) { |
| return (FX_FLOAT)tan(a); |
| } |
| FX_FLOAT FX_log(FX_FLOAT b, FX_FLOAT x) { |
| return FXSYS_log(x) / FXSYS_log(b); |
| } |
| FX_WCHAR* FX_wcsncpy(FX_WCHAR* dstStr, const FX_WCHAR* srcStr, size_t count) { |
| FXSYS_assert(dstStr != NULL && srcStr != NULL && count > 0); |
| for (size_t i = 0; i < count; ++i) |
| if ((dstStr[i] = srcStr[i]) == L'\0') { |
| break; |
| } |
| return dstStr; |
| } |
| int32_t FX_wcsnicmp(const FX_WCHAR* s1, const FX_WCHAR* s2, size_t count) { |
| FXSYS_assert(s1 != NULL && s2 != NULL && count > 0); |
| FX_WCHAR wch1 = 0, wch2 = 0; |
| while (count-- > 0) { |
| wch1 = (FX_WCHAR)FX_tolower(*s1++); |
| wch2 = (FX_WCHAR)FX_tolower(*s2++); |
| if (wch1 != wch2) { |
| break; |
| } |
| } |
| return wch1 - wch2; |
| } |
| int32_t FX_strnicmp(const FX_CHAR* s1, const FX_CHAR* s2, size_t count) { |
| FXSYS_assert(s1 != NULL && s2 != NULL && count > 0); |
| FX_CHAR ch1 = 0, ch2 = 0; |
| while (count-- > 0) { |
| ch1 = (FX_CHAR)FX_tolower(*s1++); |
| ch2 = (FX_CHAR)FX_tolower(*s2++); |
| if (ch1 != ch2) { |
| break; |
| } |
| } |
| return ch1 - ch2; |
| } |
| int32_t FX_filelength(FXSYS_FILE* file) { |
| FXSYS_assert(file != NULL); |
| #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ |
| return _filelength(_fileno(file)); |
| #else |
| int32_t iPos = FXSYS_ftell(file); |
| FXSYS_fseek(file, 0, FXSYS_SEEK_END); |
| int32_t iLen = FXSYS_ftell(file); |
| FXSYS_fseek(file, iPos, FXSYS_SEEK_SET); |
| return iLen; |
| #endif |
| } |
| FX_BOOL FX_fsetsize(FXSYS_FILE* file, int32_t size) { |
| FXSYS_assert(file != NULL); |
| #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ |
| return _chsize(_fileno(file), size) == 0; |
| #elif _FX_OS_ == _FX_WIN32_MOBILE_ |
| HANDLE hFile = _fileno(file); |
| FX_DWORD dwPos = ::SetFilePointer(hFile, 0, 0, FILE_CURRENT); |
| ::SetFilePointer(hFile, size, 0, FILE_BEGIN); |
| FX_BOOL bRet = ::SetEndOfFile(hFile); |
| ::SetFilePointer(hFile, (int32_t)dwPos, 0, FILE_BEGIN); |
| return bRet; |
| #else |
| return FALSE; |
| #endif |
| } |
| FX_FLOAT FX_strtof(const FX_CHAR* pcsStr, int32_t iLength, int32_t* pUsedLen) { |
| FXSYS_assert(pcsStr != NULL); |
| if (iLength < 0) { |
| iLength = FXSYS_strlen(pcsStr); |
| } |
| return FX_wcstof(CFX_WideString::FromLocal(pcsStr, iLength), iLength, |
| pUsedLen); |
| } |
| FX_FLOAT FX_wcstof(const FX_WCHAR* pwsStr, int32_t iLength, int32_t* pUsedLen) { |
| FXSYS_assert(pwsStr != NULL); |
| if (iLength < 0) { |
| iLength = FXSYS_wcslen(pwsStr); |
| } |
| if (iLength == 0) { |
| return 0.0f; |
| } |
| int32_t iUsedLen = 0; |
| FX_BOOL bNegtive = FALSE; |
| switch (pwsStr[iUsedLen]) { |
| case '-': |
| bNegtive = TRUE; |
| case '+': |
| iUsedLen++; |
| break; |
| } |
| FX_FLOAT fValue = 0.0f; |
| while (iUsedLen < iLength) { |
| FX_WCHAR wch = pwsStr[iUsedLen]; |
| if (wch >= L'0' && wch <= L'9') { |
| fValue = fValue * 10.0f + (wch - L'0'); |
| } else { |
| break; |
| } |
| iUsedLen++; |
| } |
| if (iUsedLen < iLength && pwsStr[iUsedLen] == L'.') { |
| FX_FLOAT fPrecise = 0.1f; |
| while (++iUsedLen < iLength) { |
| FX_WCHAR wch = pwsStr[iUsedLen]; |
| if (wch >= L'0' && wch <= L'9') { |
| fValue += (wch - L'0') * fPrecise; |
| fPrecise *= 0.1f; |
| } else { |
| break; |
| } |
| } |
| } |
| if (pUsedLen) { |
| *pUsedLen = iUsedLen; |
| } |
| return bNegtive ? -fValue : fValue; |
| } |
| void FX_memset(void* pBuf, int32_t iValue, size_t size) { |
| FXSYS_assert(pBuf != NULL && size > 0 && (size & 0x03) == 0); |
| FXSYS_assert((((size_t)pBuf) & 0x03) == 0); |
| FX_DWORD* pStart = (FX_DWORD*)pBuf; |
| FX_DWORD* pEnd = pStart + (size >> 2); |
| while (pStart < pEnd) { |
| *pStart++ = iValue; |
| } |
| } |
| void FX_memcpy(void* pDst, const void* pSrc, size_t size) { |
| FXSYS_assert(pDst != NULL && pSrc != NULL && size > 0 && (size & 0x03) == 0); |
| FXSYS_assert((((size_t)pDst) & 0x03) == 0 && (((size_t)pSrc) & 0x03) == 0); |
| FX_DWORD* pStart = (FX_DWORD*)pDst; |
| FX_DWORD* pEnd = pStart + (size >> 2); |
| FX_DWORD* pValue = (FX_DWORD*)pSrc; |
| while (pStart < pEnd) { |
| *pStart++ = *pValue++; |
| } |
| } |
| FX_BOOL FX_IsRelativePath(const CFX_WideStringC& wsUrl) { |
| int32_t iUrlLen = wsUrl.GetLength(); |
| if (iUrlLen == 0) { |
| return TRUE; |
| } |
| for (int32_t i = std::min(5, iUrlLen) - 1; i >= 0; --i) |
| if (wsUrl.GetAt(i) == ':') { |
| return FALSE; |
| } |
| return TRUE; |
| } |
| FX_BOOL FX_JoinPath(const CFX_WideStringC& wsBasePath, |
| const CFX_WideStringC& wsRelativePath, |
| CFX_WideString& wsAbsolutePath) { |
| if (!FX_IsRelativePath(wsRelativePath)) { |
| wsAbsolutePath = wsRelativePath; |
| return TRUE; |
| } |
| const FX_WCHAR* pRelStart = wsRelativePath.GetPtr(); |
| const FX_WCHAR* pRelEnd = pRelStart + wsRelativePath.GetLength(); |
| if (pRelStart < pRelEnd) { |
| switch (*pRelStart) { |
| case '#': |
| wsAbsolutePath = CFX_WideString(wsBasePath, wsRelativePath); |
| return wsAbsolutePath.GetLength() > 0; |
| case '/': |
| case '\\': |
| wsAbsolutePath = wsRelativePath; |
| return wsAbsolutePath.GetLength() > 0; |
| } |
| } |
| int32_t nBackCount = 0; |
| for (;;) { |
| if (pRelStart >= pRelEnd) { |
| wsAbsolutePath = wsBasePath; |
| return TRUE; |
| } |
| if (*pRelStart != '.') { |
| break; |
| } |
| if (pRelStart + 1 < pRelEnd && |
| (pRelStart[1] == '/' || pRelStart[1] == '\\')) { |
| pRelStart += 2; |
| } else if (pRelStart + 2 < pRelEnd && pRelStart[1] == '.' && |
| (pRelStart[2] == '/' || pRelStart[2] == '\\')) { |
| pRelStart += 3; |
| nBackCount++; |
| } else { |
| return FALSE; |
| } |
| } |
| const FX_WCHAR* pBaseStart = wsBasePath.GetPtr(); |
| const FX_WCHAR* pBaseEnd = pBaseStart + wsBasePath.GetLength(); |
| while (pBaseStart < (--pBaseEnd) && *pBaseEnd != '/' && *pBaseEnd != '\\') |
| ; |
| if (pBaseStart == pBaseEnd) { |
| wsAbsolutePath = CFX_WideStringC(pRelStart, pRelEnd - pRelStart); |
| return wsAbsolutePath.GetLength() > 0; |
| } |
| while (nBackCount > 0) { |
| if (pBaseStart >= (--pBaseEnd)) { |
| return FALSE; |
| } else if (*pBaseEnd == '/' || *pBaseEnd == '\\') |
| if ((--nBackCount) <= 0) { |
| break; |
| } |
| } |
| wsAbsolutePath = |
| CFX_WideString(CFX_WideStringC(pBaseStart, pBaseEnd - pBaseStart + 1), |
| CFX_WideStringC(pRelStart, pRelEnd - pRelStart)); |
| return wsAbsolutePath.GetLength() > 0; |
| } |
| #ifdef __cplusplus |
| }; |
| #endif |