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
~CFX_PrivateData()19 CFX_PrivateData::~CFX_PrivateData() {
20 ClearAll();
21 }
FreeData()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 }
AddData(void * pModuleId,void * pData,PD_CALLBACK_FREEDATA callback,FX_BOOL bSelfDestruct)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 }
SetPrivateData(void * pModuleId,void * pData,PD_CALLBACK_FREEDATA callback)52 void CFX_PrivateData::SetPrivateData(void* pModuleId,
53 void* pData,
54 PD_CALLBACK_FREEDATA callback) {
55 AddData(pModuleId, pData, callback, FALSE);
56 }
SetPrivateObj(void * pModuleId,CFX_DestructObject * pObj)57 void CFX_PrivateData::SetPrivateObj(void* pModuleId, CFX_DestructObject* pObj) {
58 AddData(pModuleId, pObj, NULL, TRUE);
59 }
RemovePrivateData(void * pModuleId)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 }
GetPrivateData(void * pModuleId)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 }
ClearAll()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 }
FX_atonum(const CFX_ByteStringC & strc,FX_BOOL & bInteger,void * pData)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 }
FX_atof(const CFX_ByteStringC & strc)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
FXSYS_snprintf(char * str,size_t size,_Printf_format_string_ const char * fmt,...)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 }
FXSYS_vsnprintf(char * str,size_t size,const char * fmt,va_list ap)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:
~CFindFileData()192 virtual ~CFindFileData() {}
193 HANDLE m_Handle;
194 FX_BOOL m_bEnd;
195 };
196 class CFindFileDataA : public CFindFileData {
197 public:
~CFindFileDataA()198 virtual ~CFindFileDataA() {}
199 WIN32_FIND_DATAA m_FindData;
200 };
201 class CFindFileDataW : public CFindFileData {
202 public:
~CFindFileDataW()203 virtual ~CFindFileDataW() {}
204 WIN32_FIND_DATAW m_FindData;
205 };
206 #endif
FX_OpenFolder(const FX_CHAR * path)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 }
FX_OpenFolder(const FX_WCHAR * path)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 }
FX_GetNextFile(void * handle,CFX_ByteString & filename,FX_BOOL & bFolder)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 }
FX_GetNextFile(void * handle,CFX_WideString & filename,FX_BOOL & bFolder)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 }
FX_CloseFolder(void * handle)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 }
FX_GetFolderSeparator()342 FX_WCHAR FX_GetFolderSeparator() {
343 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
344 return '\\';
345 #else
346 return '/';
347 #endif
348 }
349
Inverse()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
Multiply(const CFX_Matrix_3by3 & m)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
TransformVector(const CFX_Vector_3by1 & v)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