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 "core/include/fxcrt/fx_basic.h"
      8 #include "core/include/fxcrt/fx_ext.h"
      9 
     10 #include <cctype>
     11 
     12 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
     13 #include <sys/types.h>
     14 #include <dirent.h>
     15 #else
     16 #include <direct.h>
     17 #endif
     18 
     19 CFX_PrivateData::~CFX_PrivateData() {
     20   ClearAll();
     21 }
     22 void FX_PRIVATEDATA::FreeData() {
     23   if (!m_pData) {
     24     return;
     25   }
     26   if (m_bSelfDestruct) {
     27     delete (CFX_DestructObject*)m_pData;
     28   } else if (m_pCallback) {
     29     m_pCallback(m_pData);
     30   }
     31 }
     32 void CFX_PrivateData::AddData(void* pModuleId,
     33                               void* pData,
     34                               PD_CALLBACK_FREEDATA callback,
     35                               FX_BOOL bSelfDestruct) {
     36   if (!pModuleId) {
     37     return;
     38   }
     39   FX_PRIVATEDATA* pList = m_DataList.GetData();
     40   int count = m_DataList.GetSize();
     41   for (int i = 0; i < count; i++) {
     42     if (pList[i].m_pModuleId == pModuleId) {
     43       pList[i].FreeData();
     44       pList[i].m_pData = pData;
     45       pList[i].m_pCallback = callback;
     46       return;
     47     }
     48   }
     49   FX_PRIVATEDATA data = {pModuleId, pData, callback, bSelfDestruct};
     50   m_DataList.Add(data);
     51 }
     52 void CFX_PrivateData::SetPrivateData(void* pModuleId,
     53                                      void* pData,
     54                                      PD_CALLBACK_FREEDATA callback) {
     55   AddData(pModuleId, pData, callback, FALSE);
     56 }
     57 void CFX_PrivateData::SetPrivateObj(void* pModuleId, CFX_DestructObject* pObj) {
     58   AddData(pModuleId, pObj, NULL, TRUE);
     59 }
     60 FX_BOOL CFX_PrivateData::RemovePrivateData(void* pModuleId) {
     61   if (!pModuleId) {
     62     return FALSE;
     63   }
     64   FX_PRIVATEDATA* pList = m_DataList.GetData();
     65   int count = m_DataList.GetSize();
     66   for (int i = 0; i < count; i++) {
     67     if (pList[i].m_pModuleId == pModuleId) {
     68       m_DataList.RemoveAt(i);
     69       return TRUE;
     70     }
     71   }
     72   return FALSE;
     73 }
     74 void* CFX_PrivateData::GetPrivateData(void* pModuleId) {
     75   if (!pModuleId) {
     76     return NULL;
     77   }
     78   FX_PRIVATEDATA* pList = m_DataList.GetData();
     79   int count = m_DataList.GetSize();
     80   for (int i = 0; i < count; i++) {
     81     if (pList[i].m_pModuleId == pModuleId) {
     82       return pList[i].m_pData;
     83     }
     84   }
     85   return NULL;
     86 }
     87 void CFX_PrivateData::ClearAll() {
     88   FX_PRIVATEDATA* pList = m_DataList.GetData();
     89   int count = m_DataList.GetSize();
     90   for (int i = 0; i < count; i++) {
     91     pList[i].FreeData();
     92   }
     93   m_DataList.RemoveAll();
     94 }
     95 void FX_atonum(const CFX_ByteStringC& strc, FX_BOOL& bInteger, void* pData) {
     96   if (!FXSYS_memchr(strc.GetPtr(), '.', strc.GetLength())) {
     97     bInteger = TRUE;
     98     int cc = 0, integer = 0;
     99     const FX_CHAR* str = strc.GetCStr();
    100     int len = strc.GetLength();
    101     FX_BOOL bNegative = FALSE;
    102     if (str[0] == '+') {
    103       cc++;
    104     } else if (str[0] == '-') {
    105       bNegative = TRUE;
    106       cc++;
    107     }
    108     while (cc < len && std::isdigit(str[cc])) {
    109       // TODO(dsinclair): This is not the right way to handle overflow.
    110       integer = integer * 10 + FXSYS_toDecimalDigit(str[cc]);
    111       if (integer < 0)
    112         break;
    113       cc++;
    114     }
    115     if (bNegative) {
    116       integer = -integer;
    117     }
    118     *(int*)pData = integer;
    119   } else {
    120     bInteger = FALSE;
    121     *(FX_FLOAT*)pData = FX_atof(strc);
    122   }
    123 }
    124 FX_FLOAT FX_atof(const CFX_ByteStringC& strc) {
    125   if (strc.GetLength() == 0) {
    126     return 0.0;
    127   }
    128   int cc = 0;
    129   FX_BOOL bNegative = FALSE;
    130   const FX_CHAR* str = strc.GetCStr();
    131   int len = strc.GetLength();
    132   if (str[0] == '+') {
    133     cc++;
    134   } else if (str[0] == '-') {
    135     bNegative = TRUE;
    136     cc++;
    137   }
    138   while (cc < len) {
    139     if (str[cc] != '+' && str[cc] != '-') {
    140       break;
    141     }
    142     cc++;
    143   }
    144   FX_FLOAT value = 0;
    145   while (cc < len) {
    146     if (str[cc] == '.') {
    147       break;
    148     }
    149     value = value * 10 + FXSYS_toDecimalDigit(str[cc]);
    150     cc++;
    151   }
    152   static const FX_FLOAT fraction_scales[] = {
    153       0.1f,         0.01f,         0.001f,        0.0001f,
    154       0.00001f,     0.000001f,     0.0000001f,    0.00000001f,
    155       0.000000001f, 0.0000000001f, 0.00000000001f};
    156   int scale = 0;
    157   if (cc < len && str[cc] == '.') {
    158     cc++;
    159     while (cc < len) {
    160       value += fraction_scales[scale] * FXSYS_toDecimalDigit(str[cc]);
    161       scale++;
    162       if (scale == sizeof fraction_scales / sizeof(FX_FLOAT)) {
    163         break;
    164       }
    165       cc++;
    166     }
    167   }
    168   return bNegative ? -value : value;
    169 }
    170 
    171 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900
    172 void FXSYS_snprintf(char* str,
    173                     size_t size,
    174                     _Printf_format_string_ const char* fmt,
    175                     ...) {
    176   va_list ap;
    177   va_start(ap, fmt);
    178   FXSYS_vsnprintf(str, size, fmt, ap);
    179   va_end(ap);
    180 }
    181 void FXSYS_vsnprintf(char* str, size_t size, const char* fmt, va_list ap) {
    182   (void)_vsnprintf(str, size, fmt, ap);
    183   if (size) {
    184     str[size - 1] = 0;
    185   }
    186 }
    187 #endif  // _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900
    188 
    189 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    190 class CFindFileData {
    191  public:
    192   virtual ~CFindFileData() {}
    193   HANDLE m_Handle;
    194   FX_BOOL m_bEnd;
    195 };
    196 class CFindFileDataA : public CFindFileData {
    197  public:
    198   virtual ~CFindFileDataA() {}
    199   WIN32_FIND_DATAA m_FindData;
    200 };
    201 class CFindFileDataW : public CFindFileData {
    202  public:
    203   virtual ~CFindFileDataW() {}
    204   WIN32_FIND_DATAW m_FindData;
    205 };
    206 #endif
    207 void* FX_OpenFolder(const FX_CHAR* path) {
    208 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    209 #ifndef _WIN32_WCE
    210   CFindFileDataA* pData = new CFindFileDataA;
    211 #ifdef _FX_WINAPI_PARTITION_DESKTOP_
    212   pData->m_Handle =
    213       FindFirstFileA(CFX_ByteString(path) + "/*.*", &pData->m_FindData);
    214 #else
    215   pData->m_Handle =
    216       FindFirstFileExA(CFX_ByteString(path) + "/*.*", FindExInfoStandard,
    217                        &pData->m_FindData, FindExSearchNameMatch, NULL, 0);
    218 #endif
    219 #else
    220   CFindFileDataW* pData = new CFindFileDataW;
    221   pData->m_Handle = FindFirstFileW(CFX_WideString::FromLocal(path) + L"/*.*",
    222                                    &pData->m_FindData);
    223 #endif
    224   if (pData->m_Handle == INVALID_HANDLE_VALUE) {
    225     delete pData;
    226     return NULL;
    227   }
    228   pData->m_bEnd = FALSE;
    229   return pData;
    230 #else
    231   DIR* dir = opendir(path);
    232   return dir;
    233 #endif
    234 }
    235 void* FX_OpenFolder(const FX_WCHAR* path) {
    236 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    237   CFindFileDataW* pData = new CFindFileDataW;
    238 #ifdef _FX_WINAPI_PARTITION_DESKTOP_
    239   pData->m_Handle = FindFirstFileW((CFX_WideString(path) + L"/*.*").c_str(),
    240                                    &pData->m_FindData);
    241 #else
    242   pData->m_Handle = FindFirstFileExW((CFX_WideString(path) + L"/*.*").c_str(),
    243                                      FindExInfoStandard, &pData->m_FindData,
    244                                      FindExSearchNameMatch, NULL, 0);
    245 #endif
    246   if (pData->m_Handle == INVALID_HANDLE_VALUE) {
    247     delete pData;
    248     return NULL;
    249   }
    250   pData->m_bEnd = FALSE;
    251   return pData;
    252 #else
    253   DIR* dir = opendir(CFX_ByteString::FromUnicode(path));
    254   return dir;
    255 #endif
    256 }
    257 FX_BOOL FX_GetNextFile(void* handle,
    258                        CFX_ByteString& filename,
    259                        FX_BOOL& bFolder) {
    260   if (!handle) {
    261     return FALSE;
    262   }
    263 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    264 #ifndef _WIN32_WCE
    265   CFindFileDataA* pData = (CFindFileDataA*)handle;
    266   if (pData->m_bEnd) {
    267     return FALSE;
    268   }
    269   filename = pData->m_FindData.cFileName;
    270   bFolder = pData->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
    271   if (!FindNextFileA(pData->m_Handle, &pData->m_FindData)) {
    272     pData->m_bEnd = TRUE;
    273   }
    274   return TRUE;
    275 #else
    276   CFindFileDataW* pData = (CFindFileDataW*)handle;
    277   if (pData->m_bEnd) {
    278     return FALSE;
    279   }
    280   filename = CFX_ByteString::FromUnicode(pData->m_FindData.cFileName);
    281   bFolder = pData->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
    282   if (!FindNextFileW(pData->m_Handle, &pData->m_FindData)) {
    283     pData->m_bEnd = TRUE;
    284   }
    285   return TRUE;
    286 #endif
    287 #elif defined(__native_client__)
    288   abort();
    289   return FALSE;
    290 #else
    291   struct dirent* de = readdir((DIR*)handle);
    292   if (!de) {
    293     return FALSE;
    294   }
    295   filename = de->d_name;
    296   bFolder = de->d_type == DT_DIR;
    297   return TRUE;
    298 #endif
    299 }
    300 FX_BOOL FX_GetNextFile(void* handle,
    301                        CFX_WideString& filename,
    302                        FX_BOOL& bFolder) {
    303   if (!handle) {
    304     return FALSE;
    305   }
    306 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    307   CFindFileDataW* pData = (CFindFileDataW*)handle;
    308   if (pData->m_bEnd) {
    309     return FALSE;
    310   }
    311   filename = pData->m_FindData.cFileName;
    312   bFolder = pData->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
    313   if (!FindNextFileW(pData->m_Handle, &pData->m_FindData)) {
    314     pData->m_bEnd = TRUE;
    315   }
    316   return TRUE;
    317 #elif defined(__native_client__)
    318   abort();
    319   return FALSE;
    320 #else
    321   struct dirent* de = readdir((DIR*)handle);
    322   if (!de) {
    323     return FALSE;
    324   }
    325   filename = CFX_WideString::FromLocal(de->d_name);
    326   bFolder = de->d_type == DT_DIR;
    327   return TRUE;
    328 #endif
    329 }
    330 void FX_CloseFolder(void* handle) {
    331   if (!handle) {
    332     return;
    333   }
    334 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    335   CFindFileData* pData = (CFindFileData*)handle;
    336   FindClose(pData->m_Handle);
    337   delete pData;
    338 #else
    339   closedir((DIR*)handle);
    340 #endif
    341 }
    342 FX_WCHAR FX_GetFolderSeparator() {
    343 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    344   return '\\';
    345 #else
    346   return '/';
    347 #endif
    348 }
    349 
    350 CFX_Matrix_3by3 CFX_Matrix_3by3::Inverse() {
    351   FX_FLOAT det =
    352       a * (e * i - f * h) - b * (i * d - f * g) + c * (d * h - e * g);
    353   if (FXSYS_fabs(det) < 0.0000001)
    354     return CFX_Matrix_3by3();
    355 
    356   return CFX_Matrix_3by3(
    357       (e * i - f * h) / det, -(b * i - c * h) / det, (b * f - c * e) / det,
    358       -(d * i - f * g) / det, (a * i - c * g) / det, -(a * f - c * d) / det,
    359       (d * h - e * g) / det, -(a * h - b * g) / det, (a * e - b * d) / det);
    360 }
    361 
    362 CFX_Matrix_3by3 CFX_Matrix_3by3::Multiply(const CFX_Matrix_3by3& m) {
    363   return CFX_Matrix_3by3(
    364       a * m.a + b * m.d + c * m.g, a * m.b + b * m.e + c * m.h,
    365       a * m.c + b * m.f + c * m.i, d * m.a + e * m.d + f * m.g,
    366       d * m.b + e * m.e + f * m.h, d * m.c + e * m.f + f * m.i,
    367       g * m.a + h * m.d + i * m.g, g * m.b + h * m.e + i * m.h,
    368       g * m.c + h * m.f + i * m.i);
    369 }
    370 
    371 CFX_Vector_3by1 CFX_Matrix_3by3::TransformVector(const CFX_Vector_3by1& v) {
    372   return CFX_Vector_3by1(a * v.a + b * v.b + c * v.c,
    373                          d * v.a + e * v.b + f * v.c,
    374                          g * v.a + h * v.b + i * v.c);
    375 }
    376