blob: b08236bb1db3efb8baf67ce5fb781181a198a37d [file] [log] [blame]
// 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