Home | History | Annotate | Download | only in crt
      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