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