Home | History | Annotate | Download | only in fxcrt
      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 "../../include/fxcrt/fx_ext.h"
      8 #include "extension.h"
      9 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
     10 #include <wincrypt.h>
     11 #else
     12 #include <ctime>
     13 #endif
     14 FX_HFILE FX_File_Open(FX_BSTR fileName, FX_DWORD dwMode)
     15 {
     16     IFXCRT_FileAccess* pFA = FXCRT_FileAccess_Create();
     17     if (pFA && !pFA->Open(fileName, dwMode)) {
     18         pFA->Release();
     19         return NULL;
     20     }
     21     return (FX_HFILE)pFA;
     22 }
     23 FX_HFILE FX_File_Open(FX_WSTR fileName, FX_DWORD dwMode)
     24 {
     25     IFXCRT_FileAccess* pFA = FXCRT_FileAccess_Create();
     26     if (pFA && !pFA->Open(fileName, dwMode)) {
     27         pFA->Release();
     28         return NULL;
     29     }
     30     return (FX_HFILE)pFA;
     31 }
     32 void FX_File_Close(FX_HFILE hFile)
     33 {
     34     FXSYS_assert(hFile != NULL);
     35     ((IFXCRT_FileAccess*)hFile)->Close();
     36     ((IFXCRT_FileAccess*)hFile)->Release();
     37 }
     38 FX_FILESIZE FX_File_GetSize(FX_HFILE hFile)
     39 {
     40     FXSYS_assert(hFile != NULL);
     41     return ((IFXCRT_FileAccess*)hFile)->GetSize();
     42 }
     43 FX_FILESIZE FX_File_GetPosition(FX_HFILE hFile)
     44 {
     45     FXSYS_assert(hFile != NULL);
     46     return ((IFXCRT_FileAccess*)hFile)->GetPosition();
     47 }
     48 FX_FILESIZE FX_File_SetPosition(FX_HFILE hFile, FX_FILESIZE pos)
     49 {
     50     FXSYS_assert(hFile != NULL);
     51     return ((IFXCRT_FileAccess*)hFile)->SetPosition(pos);
     52 }
     53 size_t FX_File_Read(FX_HFILE hFile, void* pBuffer, size_t szBuffer)
     54 {
     55     FXSYS_assert(hFile != NULL);
     56     return ((IFXCRT_FileAccess*)hFile)->Read(pBuffer, szBuffer);
     57 }
     58 size_t FX_File_ReadPos(FX_HFILE hFile, void* pBuffer, size_t szBuffer, FX_FILESIZE pos)
     59 {
     60     FXSYS_assert(hFile != NULL);
     61     return ((IFXCRT_FileAccess*)hFile)->ReadPos(pBuffer, szBuffer, pos);
     62 }
     63 size_t FX_File_Write(FX_HFILE hFile, const void* pBuffer, size_t szBuffer)
     64 {
     65     FXSYS_assert(hFile != NULL);
     66     return ((IFXCRT_FileAccess*)hFile)->Write(pBuffer, szBuffer);
     67 }
     68 size_t FX_File_WritePos(FX_HFILE hFile, const void* pBuffer, size_t szBuffer, FX_FILESIZE pos)
     69 {
     70     FXSYS_assert(hFile != NULL);
     71     return ((IFXCRT_FileAccess*)hFile)->WritePos(pBuffer, szBuffer, pos);
     72 }
     73 FX_BOOL FX_File_Flush(FX_HFILE hFile)
     74 {
     75     FXSYS_assert(hFile != NULL);
     76     return ((IFXCRT_FileAccess*)hFile)->Flush();
     77 }
     78 FX_BOOL FX_File_Truncate(FX_HFILE hFile, FX_FILESIZE szFile)
     79 {
     80     FXSYS_assert(hFile != NULL);
     81     return ((IFXCRT_FileAccess*)hFile)->Truncate(szFile);
     82 }
     83 IFX_FileStream* FX_CreateFileStream(FX_LPCSTR filename, FX_DWORD dwModes)
     84 {
     85     IFXCRT_FileAccess* pFA = FXCRT_FileAccess_Create();
     86     if (!pFA) {
     87         return NULL;
     88     }
     89     if (!pFA->Open(filename, dwModes)) {
     90         pFA->Release();
     91         return NULL;
     92     }
     93     return new CFX_CRTFileStream(pFA);
     94 }
     95 IFX_FileStream* FX_CreateFileStream(FX_LPCWSTR filename, FX_DWORD dwModes)
     96 {
     97     IFXCRT_FileAccess* pFA = FXCRT_FileAccess_Create();
     98     if (!pFA) {
     99         return NULL;
    100     }
    101     if (!pFA->Open(filename, dwModes)) {
    102         pFA->Release();
    103         return NULL;
    104     }
    105     return new CFX_CRTFileStream(pFA);
    106 }
    107 IFX_FileWrite* FX_CreateFileWrite(FX_LPCSTR filename)
    108 {
    109     return FX_CreateFileStream(filename, FX_FILEMODE_Truncate);
    110 }
    111 IFX_FileWrite* FX_CreateFileWrite(FX_LPCWSTR filename)
    112 {
    113     return FX_CreateFileStream(filename, FX_FILEMODE_Truncate);
    114 }
    115 IFX_FileRead* FX_CreateFileRead(FX_LPCSTR filename)
    116 {
    117     return FX_CreateFileStream(filename, FX_FILEMODE_ReadOnly);
    118 }
    119 IFX_FileRead* FX_CreateFileRead(FX_LPCWSTR filename)
    120 {
    121     return FX_CreateFileStream(filename, FX_FILEMODE_ReadOnly);
    122 }
    123 IFX_MemoryStream* FX_CreateMemoryStream(FX_LPBYTE pBuffer, size_t dwSize, FX_BOOL bTakeOver)
    124 {
    125     return new CFX_MemoryStream(pBuffer, dwSize, bTakeOver);
    126 }
    127 IFX_MemoryStream* FX_CreateMemoryStream(FX_BOOL bConsecutive)
    128 {
    129     return new CFX_MemoryStream(bConsecutive);
    130 }
    131 #ifdef __cplusplus
    132 extern "C" {
    133 #endif
    134 FX_FLOAT FXSYS_tan(FX_FLOAT a)
    135 {
    136     return (FX_FLOAT)tan(a);
    137 }
    138 FX_FLOAT FXSYS_logb(FX_FLOAT b, FX_FLOAT x)
    139 {
    140     return FXSYS_log(x) / FXSYS_log(b);
    141 }
    142 FX_FLOAT FXSYS_strtof(FX_LPCSTR pcsStr, FX_INT32 iLength, FX_INT32 *pUsedLen)
    143 {
    144     FXSYS_assert(pcsStr != NULL);
    145     if (iLength < 0) {
    146         iLength = (FX_INT32)FXSYS_strlen(pcsStr);
    147     }
    148     CFX_WideString ws = CFX_WideString::FromLocal(pcsStr, iLength);
    149     return FXSYS_wcstof(ws.c_str(), iLength, pUsedLen);
    150 }
    151 FX_FLOAT FXSYS_wcstof(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_INT32 *pUsedLen)
    152 {
    153     FXSYS_assert(pwsStr != NULL);
    154     if (iLength < 0) {
    155         iLength = (FX_INT32)FXSYS_wcslen(pwsStr);
    156     }
    157     if (iLength == 0) {
    158         return 0.0f;
    159     }
    160     FX_INT32 iUsedLen = 0;
    161     FX_BOOL bNegtive = FALSE;
    162     switch (pwsStr[iUsedLen]) {
    163         case '-':
    164             bNegtive = TRUE;
    165         case '+':
    166             iUsedLen++;
    167             break;
    168     }
    169     FX_FLOAT fValue = 0.0f;
    170     while (iUsedLen < iLength) {
    171         FX_WCHAR wch = pwsStr[iUsedLen];
    172         if (wch >= L'0' && wch <= L'9') {
    173             fValue = fValue * 10.0f + (wch - L'0');
    174         } else {
    175             break;
    176         }
    177         iUsedLen++;
    178     }
    179     if (iUsedLen < iLength && pwsStr[iUsedLen] == L'.') {
    180         FX_FLOAT fPrecise = 0.1f;
    181         while (++iUsedLen < iLength) {
    182             FX_WCHAR wch = pwsStr[iUsedLen];
    183             if (wch >= L'0' && wch <= L'9') {
    184                 fValue += (wch - L'0') * fPrecise;
    185                 fPrecise *= 0.1f;
    186             } else {
    187                 break;
    188             }
    189         }
    190     }
    191     if (pUsedLen) {
    192         *pUsedLen = iUsedLen;
    193     }
    194     return bNegtive ? -fValue : fValue;
    195 }
    196 FX_LPWSTR FXSYS_wcsncpy(FX_LPWSTR dstStr, FX_LPCWSTR srcStr, size_t count)
    197 {
    198     FXSYS_assert(dstStr != NULL && srcStr != NULL && count > 0);
    199     for (size_t i = 0; i < count; ++i)
    200         if ((dstStr[i] = srcStr[i]) == L'\0') {
    201             break;
    202         }
    203     return dstStr;
    204 }
    205 FX_INT32 FXSYS_wcsnicmp(FX_LPCWSTR s1, FX_LPCWSTR s2, size_t count)
    206 {
    207     FXSYS_assert(s1 != NULL && s2 != NULL && count > 0);
    208     FX_WCHAR wch1 = 0, wch2 = 0;
    209     while (count-- > 0) {
    210         wch1 = (FX_WCHAR)FXSYS_tolower(*s1++);
    211         wch2 = (FX_WCHAR)FXSYS_tolower(*s2++);
    212         if (wch1 != wch2) {
    213             break;
    214         }
    215     }
    216     return wch1 - wch2;
    217 }
    218 FX_INT32 FXSYS_strnicmp(FX_LPCSTR s1, FX_LPCSTR s2, size_t count)
    219 {
    220     FXSYS_assert(s1 != NULL && s2 != NULL && count > 0);
    221     FX_CHAR ch1 = 0, ch2 = 0;
    222     while (count-- > 0) {
    223         ch1 = (FX_CHAR)FXSYS_tolower(*s1++);
    224         ch2 = (FX_CHAR)FXSYS_tolower(*s2++);
    225         if (ch1 != ch2) {
    226             break;
    227         }
    228     }
    229     return ch1 - ch2;
    230 }
    231 FX_DWORD FX_HashCode_String_GetA(FX_LPCSTR pStr, FX_INT32 iLength, FX_BOOL bIgnoreCase)
    232 {
    233     FXSYS_assert(pStr != NULL);
    234     if (iLength < 0) {
    235         iLength = (FX_INT32)FXSYS_strlen(pStr);
    236     }
    237     FX_LPCSTR pStrEnd = pStr + iLength;
    238     FX_DWORD dwHashCode = 0;
    239     if (bIgnoreCase) {
    240         while (pStr < pStrEnd) {
    241             dwHashCode = 31 * dwHashCode + FXSYS_tolower(*pStr++);
    242         }
    243     } else {
    244         while (pStr < pStrEnd) {
    245             dwHashCode = 31 * dwHashCode + *pStr ++;
    246         }
    247     }
    248     return dwHashCode;
    249 }
    250 FX_DWORD FX_HashCode_String_GetW(FX_LPCWSTR pStr, FX_INT32 iLength, FX_BOOL bIgnoreCase)
    251 {
    252     FXSYS_assert(pStr != NULL);
    253     if (iLength < 0) {
    254         iLength = (FX_INT32)FXSYS_wcslen(pStr);
    255     }
    256     FX_LPCWSTR pStrEnd = pStr + iLength;
    257     FX_DWORD dwHashCode = 0;
    258     if (bIgnoreCase) {
    259         while (pStr < pStrEnd) {
    260             dwHashCode = 1313 * dwHashCode + FXSYS_tolower(*pStr++);
    261         }
    262     } else {
    263         while (pStr < pStrEnd) {
    264             dwHashCode = 1313 * dwHashCode + *pStr ++;
    265         }
    266     }
    267     return dwHashCode;
    268 }
    269 #ifdef __cplusplus
    270 }
    271 #endif
    272 #ifdef __cplusplus
    273 extern "C" {
    274 #endif
    275 FX_LPVOID FX_Random_MT_Start(FX_DWORD dwSeed)
    276 {
    277     FX_LPMTRANDOMCONTEXT pContext = FX_Alloc(FX_MTRANDOMCONTEXT, 1);
    278     pContext->mt[0] = dwSeed;
    279     FX_DWORD &i = pContext->mti;
    280     FX_LPDWORD pBuf = pContext->mt;
    281     for (i = 1; i < MT_N; i ++) {
    282         pBuf[i] = (1812433253UL * (pBuf[i - 1] ^ (pBuf[i - 1] >> 30)) + i);
    283     }
    284     pContext->bHaveSeed = TRUE;
    285     return pContext;
    286 }
    287 FX_DWORD FX_Random_MT_Generate(FX_LPVOID pContext)
    288 {
    289     FXSYS_assert(pContext != NULL);
    290     FX_LPMTRANDOMCONTEXT pMTC = (FX_LPMTRANDOMCONTEXT)pContext;
    291     FX_DWORD v;
    292     static FX_DWORD mag[2] = {0, MT_Matrix_A};
    293     FX_DWORD &mti = pMTC->mti;
    294     FX_LPDWORD pBuf = pMTC->mt;
    295     if ((int)mti < 0 || mti >= MT_N) {
    296         if (mti > MT_N && !pMTC->bHaveSeed) {
    297             return 0;
    298         }
    299         FX_DWORD kk;
    300         for (kk = 0; kk < MT_N - MT_M; kk ++) {
    301             v = (pBuf[kk] & MT_Upper_Mask) | (pBuf[kk + 1] & MT_Lower_Mask);
    302             pBuf[kk] = pBuf[kk + MT_M] ^ (v >> 1) ^ mag[v & 1];
    303         }
    304         for (; kk < MT_N - 1; kk ++) {
    305             v = (pBuf[kk] & MT_Upper_Mask) | (pBuf[kk + 1] & MT_Lower_Mask);
    306             pBuf[kk] = pBuf[kk + (MT_M - MT_N)] ^ (v >> 1) ^ mag[v & 1];
    307         }
    308         v = (pBuf[MT_N - 1] & MT_Upper_Mask) | (pBuf[0] & MT_Lower_Mask);
    309         pBuf[MT_N - 1] = pBuf[MT_M - 1] ^ (v >> 1) ^ mag[v & 1];
    310         mti = 0;
    311     }
    312     v = pBuf[mti ++];
    313     v ^= (v >> 11);
    314     v ^= (v << 7) & 0x9d2c5680UL;
    315     v ^= (v << 15) & 0xefc60000UL;
    316     v ^= (v >> 18);
    317     return v;
    318 }
    319 void FX_Random_MT_Close(FX_LPVOID pContext)
    320 {
    321     FXSYS_assert(pContext != NULL);
    322     FX_Free(pContext);
    323 }
    324 void FX_Random_GenerateMT(FX_LPDWORD pBuffer, FX_INT32 iCount)
    325 {
    326     FX_DWORD dwSeed;
    327 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    328     if (!FX_GenerateCryptoRandom(&dwSeed, 1)) {
    329         FX_Random_GenerateBase(&dwSeed, 1);
    330     }
    331 #else
    332     FX_Random_GenerateBase(&dwSeed, 1);
    333 #endif
    334     FX_LPVOID pContext = FX_Random_MT_Start(dwSeed);
    335     while (iCount -- > 0) {
    336         *pBuffer ++ = FX_Random_MT_Generate(pContext);
    337     }
    338     FX_Random_MT_Close(pContext);
    339 }
    340 void FX_Random_GenerateBase(FX_LPDWORD pBuffer, FX_INT32 iCount)
    341 {
    342 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    343     SYSTEMTIME st1, st2;
    344     ::GetSystemTime(&st1);
    345     do {
    346         ::GetSystemTime(&st2);
    347     } while (FXSYS_memcmp32(&st1, &st2, sizeof(SYSTEMTIME)) == 0);
    348     FX_DWORD dwHash1 = FX_HashCode_String_GetA((FX_LPCSTR)&st1, sizeof(st1), TRUE);
    349     FX_DWORD dwHash2 = FX_HashCode_String_GetA((FX_LPCSTR)&st2, sizeof(st2), TRUE);
    350     ::srand((dwHash1 << 16) | (FX_DWORD)dwHash2);
    351 #else
    352     time_t tmLast = time(NULL), tmCur;
    353     while ((tmCur = time(NULL)) == tmLast);
    354     ::srand((tmCur << 16) | (tmLast & 0xFFFF));
    355 #endif
    356     while (iCount -- > 0) {
    357         *pBuffer ++ = (FX_DWORD)((::rand() << 16) | (::rand() & 0xFFFF));
    358     }
    359 }
    360 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    361 FX_BOOL FX_GenerateCryptoRandom(FX_LPDWORD pBuffer, FX_INT32 iCount)
    362 {
    363     HCRYPTPROV hCP = NULL;
    364     if (!::CryptAcquireContext(&hCP, NULL, NULL, PROV_RSA_FULL, 0) || hCP == NULL) {
    365         return FALSE;
    366     }
    367     ::CryptGenRandom(hCP, iCount * sizeof(FX_DWORD), (FX_LPBYTE)pBuffer);
    368     ::CryptReleaseContext(hCP, 0);
    369     return TRUE;
    370 }
    371 #endif
    372 void FX_Random_GenerateCrypto(FX_LPDWORD pBuffer, FX_INT32 iCount)
    373 {
    374 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    375     FX_GenerateCryptoRandom(pBuffer, iCount);
    376 #else
    377     FX_Random_GenerateBase(pBuffer, iCount);
    378 #endif
    379 }
    380 #ifdef __cplusplus
    381 }
    382 #endif
    383